diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/MultiResourceItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/MultiResourceItemReader.java index a45bf0888..ae1f066b3 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/MultiResourceItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/MultiResourceItemReader.java @@ -150,7 +150,11 @@ public class MultiResourceItemReader extends AbstractItemStreamItemReader @Override public void close() throws ItemStreamException { super.close(); - delegate.close(); + + if(!this.noInput) { + delegate.close(); + } + noInput = false; } 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 603b8252e..21dd28c2f 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 @@ -15,10 +15,24 @@ */ package org.springframework.batch.item.file; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Comparator; + import org.junit.Before; import org.junit.Test; + import org.springframework.batch.item.ExecutionContext; import org.springframework.batch.item.ItemStreamException; +import org.springframework.batch.item.NonTransientResourceException; +import org.springframework.batch.item.ParseException; +import org.springframework.batch.item.UnexpectedInputException; import org.springframework.batch.item.file.mapping.PassThroughLineMapper; import org.springframework.core.io.AbstractResource; import org.springframework.core.io.ByteArrayResource; @@ -26,16 +40,6 @@ import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.test.util.ReflectionTestUtils; -import java.io.IOException; -import java.io.InputStream; -import java.util.Comparator; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - /** * Tests for {@link MultiResourceItemReader}. */ @@ -289,6 +293,25 @@ public class MultiResourceItemReaderIntegrationTests { tested.close(); } + /** + * Test {@link org.springframework.batch.item.ItemStream} lifecycle symmetry + */ + @Test + public void testNonExistentResourcesItemStreamLifecycle() throws Exception { + ItemStreamReaderImpl delegate = new ItemStreamReaderImpl(); + tested.setDelegate(delegate); + tested.setResources(new Resource[] { }); + itemReader.setStrict(false); + tested.open(new ExecutionContext()); + + assertNull(tested.read()); + assertFalse(delegate.openCalled); + assertFalse(delegate.closeCalled); + assertFalse(delegate.updateCalled); + + tested.close(); + } + /** * Directory resource behaves as if it was empty. */ @@ -456,4 +479,34 @@ public class MultiResourceItemReaderIntegrationTests { assertEquals("1", tested.read()); } + private static class ItemStreamReaderImpl implements ResourceAwareItemReaderItemStream { + + private boolean openCalled = false; + private boolean updateCalled = false; + private boolean closeCalled = false; + + @Override + public String read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException { + return null; + } + + @Override + public void open(ExecutionContext executionContext) throws ItemStreamException { + openCalled = true; + } + + @Override + public void update(ExecutionContext executionContext) throws ItemStreamException { + updateCalled = true; + } + + @Override + public void close() throws ItemStreamException { + closeCalled = true; + } + + @Override + public void setResource(Resource resource) { + } + } }