diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemReader.java index 5773950aa..3496bb78b 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemReader.java @@ -179,17 +179,17 @@ public class FlatFileItemReader extends AbstractItemCountingItemStreamItemRea } String line = readLine(); - + if (line == null) { return null; } else { - try{ + try { return lineMapper.mapLine(line, lineCount); } - catch(Exception ex){ - logger.error("Parsing error at line: " + lineCount + " in resource=" + - resource.getDescription() + ", input=[" + line + "]", ex); + catch (Exception ex) { + logger.error("Parsing error at line: " + lineCount + " in resource=" + resource.getDescription() + + ", input=[" + line + "]", ex); throw ex; } } @@ -219,7 +219,7 @@ public class FlatFileItemReader extends AbstractItemCountingItemStreamItemRea } lineCount++; } - + line = applyRecordSeparatorPolicy(line); } catch (IOException e) { @@ -250,21 +250,20 @@ public class FlatFileItemReader extends AbstractItemCountingItemStreamItemRea Assert.notNull(resource, "Input resource must be set"); Assert.notNull(recordSeparatorPolicy, "RecordSeparatorPolicy must be set"); - noInput = false; + noInput = true; if (!resource.exists()) { if (strict) { throw new IllegalStateException("Input resource must exist (reader is in 'strict' mode): " + resource); } - noInput = true; logger.warn("Input resource does not exist " + resource.getDescription()); return; } if (!resource.isReadable()) { if (strict) { - throw new IllegalStateException("Input resource must be readable (reader is in 'strict' mode): " + resource); + throw new IllegalStateException("Input resource must be readable (reader is in 'strict' mode): " + + resource); } - noInput = true; logger.warn("Input resource is not readable " + resource.getDescription()); return; } @@ -276,21 +275,22 @@ public class FlatFileItemReader extends AbstractItemCountingItemStreamItemRea skippedLinesCallback.handleLine(line); } } + noInput = false; } public void afterPropertiesSet() throws Exception { Assert.notNull(lineMapper, "LineMapper is required"); } - + @Override protected void jumpToItem(int itemIndex) throws Exception { for (int i = 0; i < itemIndex; i++) { readLine(); } } - - private String applyRecordSeparatorPolicy(String line) throws IOException{ - + + private String applyRecordSeparatorPolicy(String line) throws IOException { + String record = line; while (line != null && !recordSeparatorPolicy.isEndOfRecord(record)) { line = this.reader.readLine(); @@ -302,18 +302,19 @@ public class FlatFileItemReader extends AbstractItemCountingItemStreamItemRea } else { // Record has no text but it might still be post processed - // to something (skipping preProcess since that was already done) + // to something (skipping preProcess since that was already + // done) break; } - } else { + } + else { lineCount++; - } + } record = recordSeparatorPolicy.preProcess(record) + line; } - + return recordSeparatorPolicy.postProcess(record); - + } - } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemWriter.java index 75f6e4c79..9a283118b 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemWriter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemWriter.java @@ -33,7 +33,6 @@ import org.springframework.batch.item.ItemStream; import org.springframework.batch.item.ItemStreamException; import org.springframework.batch.item.WriteFailedException; import org.springframework.batch.item.WriterNotOpenException; -import org.springframework.batch.item.database.JdbcBatchItemWriter; import org.springframework.batch.item.file.transform.LineAggregator; import org.springframework.batch.item.util.ExecutionContextUserSupport; import org.springframework.batch.item.util.FileUtils; diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxEventItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxEventItemReader.java index 6e7c1b618..cbb6058e0 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxEventItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxEventItemReader.java @@ -148,7 +148,8 @@ public class StaxEventItemReader extends AbstractItemCountingItemStreamItemRe } QName startElementName = ((StartElement) reader.peek()).getName(); if (startElementName.getLocalPart().equals(fragmentRootElementName)) { - if (fragmentRootElementNameSpace==null || startElementName.getNamespaceURI().equals(fragmentRootElementNameSpace)) { + if (fragmentRootElementNameSpace == null + || startElementName.getNamespaceURI().equals(fragmentRootElementNameSpace)) { return true; } } @@ -180,12 +181,11 @@ public class StaxEventItemReader extends AbstractItemCountingItemStreamItemRe protected void doOpen() throws Exception { Assert.notNull(resource, "The Resource must not be null."); - noInput = false; + noInput = true; if (!resource.exists()) { if (strict) { throw new IllegalStateException("Input resource must exist (reader is in 'strict' mode)"); } - noInput = true; logger.warn("Input resource does not exist " + resource.getDescription()); return; } @@ -193,7 +193,6 @@ public class StaxEventItemReader extends AbstractItemCountingItemStreamItemRe if (strict) { throw new IllegalStateException("Input resource must be readable (reader is in 'strict' mode)"); } - noInput = true; logger.warn("Input resource is not readable " + resource.getDescription()); return; } @@ -201,6 +200,7 @@ public class StaxEventItemReader extends AbstractItemCountingItemStreamItemRe inputStream = resource.getInputStream(); eventReader = XMLInputFactory.newInstance().createXMLEventReader(inputStream); fragmentReader = new DefaultFragmentEventReader(eventReader); + noInput = false; } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemReaderTests.java index 22fc47e07..9c5b93bba 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemReaderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemReaderTests.java @@ -302,6 +302,37 @@ public class FlatFileItemReaderTests { reader.close(); } + @Test + public void testOpenBadIOInput() throws Exception { + + reader.setResource(new AbstractResource() { + public String getDescription() { + return null; + } + + public InputStream getInputStream() throws IOException { + throw new IOException(); + } + + public boolean exists() { + return true; + } + }); + + try { + reader.open(executionContext); + fail(); + } + catch (ItemStreamException ex) { + // expected + } + + // read() should then return a null + assertNull(reader.read()); + reader.close(); + + } + @Test public void testDirectoryResource() throws Exception { diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/MultiResourceItemReaderIntegrationTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/MultiResourceItemReaderIntegrationTests.java index e43c8b229..1416ff025 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/MultiResourceItemReaderIntegrationTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/MultiResourceItemReaderIntegrationTests.java @@ -345,6 +345,41 @@ public class MultiResourceItemReaderIntegrationTests { } } + @Test + public void testBadIOInput() throws Exception { + + Resource badResource = new AbstractResource() { + + public boolean exists() { + // Looks good ... + return true; + } + + public InputStream getInputStream() throws IOException { + // ... but fails during read + throw new RuntimeException(); + } + + public String getDescription() {return null;} + }; + + tested.setResources(new Resource[] { badResource, r2, r3, r4, r5 }); + + tested.open(ctx); + + try{ + assertEquals("1", tested.read()); + fail(); + } + catch(ItemStreamException ex){ + // expected + } + + // Now check the next read gets the next resource + assertEquals("4", tested.read()); + + } + @Test public void testGetCurrentResourceBeforeRead() throws Exception { tested.open(ctx); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java index 1350e5984..e5403b39f 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java @@ -234,7 +234,7 @@ public class StaxEventItemReaderTests { } @Test - public void testOpenBadIOInput() { + public void testOpenBadIOInput() throws Exception { source.setResource(new AbstractResource() { public String getDescription() { @@ -252,10 +252,15 @@ public class StaxEventItemReaderTests { try { source.open(executionContext); + fail(); } catch (ItemStreamException ex) { // expected } + + // read() should then return a null + assertNull(source.read()); + source.close(); }