From 78ed0075ea6621f62ee9166bfba354c816ca0004 Mon Sep 17 00:00:00 2001 From: robokaso Date: Tue, 30 Sep 2008 11:32:41 +0000 Subject: [PATCH] RESOLVED - BATCH-847: FaultTolerantChunkOrientedTasklet loses chunks when non-skippable exceptions thrown in read phase used fatal NonSkippableReadException instead of reusing SkipLimitExceededException --- .../core/step/item/SkipLimitStepFactoryBean.java | 5 +++-- .../core/step/skip/NonSkippableReadException.java | 15 +++++++++++++++ .../step/item/SkipLimitStepFactoryBeanTests.java | 3 ++- .../item/StatefulRetryStepFactoryBeanTests.java | 3 ++- 4 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 spring-batch-core/src/main/java/org/springframework/batch/core/step/skip/NonSkippableReadException.java diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SkipLimitStepFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SkipLimitStepFactoryBean.java index 0a237d3f2..fef95f8f0 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SkipLimitStepFactoryBean.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SkipLimitStepFactoryBean.java @@ -10,6 +10,7 @@ import org.springframework.batch.core.StepContribution; import org.springframework.batch.core.listener.CompositeSkipListener; import org.springframework.batch.core.step.skip.ItemSkipPolicy; import org.springframework.batch.core.step.skip.LimitCheckingItemSkipPolicy; +import org.springframework.batch.core.step.skip.NonSkippableReadException; import org.springframework.batch.core.step.skip.SkipLimitExceededException; import org.springframework.batch.item.ItemKeyGenerator; import org.springframework.batch.item.ItemReader; @@ -205,6 +206,7 @@ public class SkipLimitStepFactoryBean extends SimpleStepFactoryBean { if (retryLimit > 0 || skipLimit > 0 || retryPolicy != null) { addFatalExceptionIfMissing(SkipLimitExceededException.class); + addFatalExceptionIfMissing(NonSkippableReadException.class); addFatalExceptionIfMissing(RetryException.class); if (retryPolicy == null) { @@ -385,8 +387,7 @@ public class SkipLimitStepFactoryBean extends SimpleStepFactoryBean { onSkipInRead(e); logger.debug("Skipping failed input", e); } else { - // re-throw the same way as exceeding skip limit (fatal) - throw new SkipLimitExceededException(0, e); + throw new NonSkippableReadException("Non-skippable exception during read", e); } } catch (SkipLimitExceededException ex) { // we are headed for a abnormal ending so bake in the diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/skip/NonSkippableReadException.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/skip/NonSkippableReadException.java new file mode 100644 index 000000000..aeb6ed7b2 --- /dev/null +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/skip/NonSkippableReadException.java @@ -0,0 +1,15 @@ +package org.springframework.batch.core.step.skip; + +import org.springframework.core.NestedRuntimeException; + +public class NonSkippableReadException extends NestedRuntimeException { + + public NonSkippableReadException(String msg, Throwable cause) { + super(msg, cause); + } + + public NonSkippableReadException(String msg) { + super(msg); + } + +} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkipLimitStepFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkipLimitStepFactoryBeanTests.java index c95de78ef..29ceaf1f1 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkipLimitStepFactoryBeanTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkipLimitStepFactoryBeanTests.java @@ -18,6 +18,7 @@ import org.springframework.batch.core.Step; import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.step.AbstractStep; import org.springframework.batch.core.step.JobRepositorySupport; +import org.springframework.batch.core.step.skip.NonSkippableReadException; import org.springframework.batch.core.step.skip.SkipLimitExceededException; import org.springframework.batch.item.ClearFailedException; import org.springframework.batch.item.FlushFailedException; @@ -118,7 +119,7 @@ public class SkipLimitStepFactoryBeanTests extends TestCase { step.execute(stepExecution); fail(); } - catch (SkipLimitExceededException e) { + catch (NonSkippableReadException e) { assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); assertEquals(1, stepExecution.getItemCount().intValue()); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StatefulRetryStepFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StatefulRetryStepFactoryBeanTests.java index 44b311669..290597adc 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StatefulRetryStepFactoryBeanTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StatefulRetryStepFactoryBeanTests.java @@ -37,6 +37,7 @@ import org.springframework.batch.core.repository.dao.MapJobInstanceDao; import org.springframework.batch.core.repository.dao.MapStepExecutionDao; import org.springframework.batch.core.repository.support.SimpleJobRepository; import org.springframework.batch.core.step.AbstractStep; +import org.springframework.batch.core.step.skip.NonSkippableReadException; import org.springframework.batch.core.step.skip.SkipLimitExceededException; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemWriter; @@ -143,7 +144,7 @@ public class StatefulRetryStepFactoryBeanTests extends TestCase { step.execute(stepExecution); fail(); } - catch (SkipLimitExceededException expected) { + catch (NonSkippableReadException expected) { assertEquals(0, stepExecution.getSkipCount()); // b is processed twice, plus a, plus c, plus the null at end