diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/AbstractStep.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/AbstractStep.java index 83b2872a5..87e47b1ad 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/AbstractStep.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/AbstractStep.java @@ -353,15 +353,4 @@ public abstract class AbstractStep implements Step, InitializingBean, BeanNameAw return exitStatus; } - /** - * Signals a fatal exception - e.g. unable to persist batch metadata or - * rollback transaction. Throwing this exception will result in storing - * {@link BatchStatus#UNKNOWN} as step's status. - */ - protected static class FatalException extends RuntimeException { - public FatalException(String string, Throwable e) { - super(string, e); - } - } - } \ No newline at end of file diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/FatalException.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/FatalException.java new file mode 100644 index 000000000..1a832010a --- /dev/null +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/FatalException.java @@ -0,0 +1,15 @@ +package org.springframework.batch.core.step; + +import org.springframework.batch.core.BatchStatus; +import org.springframework.batch.core.UnexpectedJobExecutionException; + +/** + * Signals a fatal exception in step - e.g. unable to persist batch metadata or + * rollback transaction. Throwing this exception in a step implementation will + * result in the step having a status of {@link BatchStatus#UNKNOWN}. + */ +public class FatalException extends UnexpectedJobExecutionException { + public FatalException(String string, Throwable e) { + super(string, e); + } +} \ No newline at end of file diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBean.java index 061b328a3..8dc650afb 100755 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBean.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBean.java @@ -28,6 +28,7 @@ import org.springframework.batch.classify.Classifier; import org.springframework.batch.classify.SubclassClassifier; import org.springframework.batch.core.JobInterruptedException; import org.springframework.batch.core.Step; +import org.springframework.batch.core.step.FatalException; import org.springframework.batch.core.step.skip.LimitCheckingItemSkipPolicy; import org.springframework.batch.core.step.skip.NonSkippableReadException; import org.springframework.batch.core.step.skip.SkipLimitExceededException; @@ -293,9 +294,9 @@ public class FaultTolerantStepFactoryBean extends SimpleStepFactoryBean, Boolean> skippable = getExceptionClasses("s1", chunkElementParentAttributeParserTestsContext); - assertEquals(11, skippable.size()); + assertEquals(12, skippable.size()); containsClassified(skippable, NullPointerException.class, true); containsClassified(skippable, ArithmeticException.class, true); containsClassified(skippable, CannotAcquireLockException.class, false); @@ -61,7 +61,7 @@ public class ChunkElementParserTests { public void testInheritSkippableWithNoMerge() throws Exception { Map, Boolean> skippable = getExceptionClasses("s2", chunkElementParentAttributeParserTestsContext); - assertEquals(9, skippable.size()); + assertEquals(10, skippable.size()); containsClassified(skippable, NullPointerException.class, true); assertFalse(skippable.containsKey(ArithmeticException.class)); containsClassified(skippable, CannotAcquireLockException.class, false); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StepParserTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StepParserTests.java index 65534857b..4818e4f24 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StepParserTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/configuration/xml/StepParserTests.java @@ -38,7 +38,7 @@ import org.springframework.batch.core.listener.StepExecutionListenerSupport; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.repository.support.SimpleJobRepository; import org.springframework.batch.core.step.AbstractStep; -import org.springframework.batch.core.step.item.FatalException; +import org.springframework.batch.core.step.item.FatalSkippableException; import org.springframework.batch.core.step.item.FatalRuntimeException; import org.springframework.batch.core.step.item.SkippableException; import org.springframework.batch.core.step.item.SkippableRuntimeException; @@ -427,10 +427,10 @@ public class StepParserTests { skippable.put(SkippableRuntimeException.class, true); skippable.put(SkippableException.class, true); skippable.put(FatalRuntimeException.class, false); - skippable.put(FatalException.class, false); + skippable.put(FatalSkippableException.class, false); Map, Boolean> retryable = new HashMap, Boolean>(); retryable.put(DeadlockLoserDataAccessException.class, true); - retryable.put(FatalException.class, true); + retryable.put(FatalSkippableException.class, true); List> streams = Arrays.asList(CompositeItemStream.class, TestReader.class); List> retryListeners = Arrays.asList(RetryListenerSupport.class, DummyRetryListener.class); @@ -463,9 +463,9 @@ public class StepParserTests { Map, Boolean> skippable = new HashMap, Boolean>(); skippable.put(SkippableException.class, true); - skippable.put(FatalException.class, false); + skippable.put(FatalSkippableException.class, false); Map, Boolean> retryable = new HashMap, Boolean>(); - retryable.put(FatalException.class, true); + retryable.put(FatalSkippableException.class, true); List> streams = Arrays.asList(CompositeItemStream.class); List> retryListeners = Arrays.asList(DummyRetryListener.class); List> stepListeners = Arrays.asList(CompositeStepExecutionListener.class); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/AbstractExceptionThrowingItemHandlerStub.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/AbstractExceptionThrowingItemHandlerStub.java index ea6fd9970..ae3672fe8 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/AbstractExceptionThrowingItemHandlerStub.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/AbstractExceptionThrowingItemHandlerStub.java @@ -47,8 +47,14 @@ public abstract class AbstractExceptionThrowingItemHandlerStub { public void setExceptionType(Class exceptionType) throws Exception { try { exception = exceptionType.getConstructor(String.class); - } catch (NoSuchMethodException e) { - exception = exceptionType.getConstructor(Object.class); + } + catch (NoSuchMethodException e) { + try { + exception = exceptionType.getConstructor(String.class, Throwable.class); + } + catch (NoSuchMethodException ex) { + exception = exceptionType.getConstructor(Object.class); + } } } @@ -58,7 +64,7 @@ public abstract class AbstractExceptionThrowingItemHandlerStub { protected void checkFailure(T item) throws Exception { if (isFailure(item)) { - Throwable t = exception.newInstance("Intended Failure: " + item); + Throwable t = getException("Intended Failure: " + item); if (t instanceof Exception) { throw (Exception) t; } @@ -69,6 +75,13 @@ public abstract class AbstractExceptionThrowingItemHandlerStub { } } + private Throwable getException(String string) throws Exception { + if (exception.getParameterTypes().length==1) { + return exception.newInstance(string); + } + return exception.newInstance(string, new RuntimeException("Planned")); + } + protected boolean isFailure(T item) { return this.failures.contains(item); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FatalException.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FatalException.java deleted file mode 100644 index cc9c7b663..000000000 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FatalException.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.springframework.batch.core.step.item; - -/** - * @author Dan Garrette - * @since 2.0.2 - */ -public class FatalException extends SkippableException { - public FatalException(String message) { - super(message); - } -} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FatalSkippableException.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FatalSkippableException.java new file mode 100644 index 000000000..d43a2b69e --- /dev/null +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FatalSkippableException.java @@ -0,0 +1,11 @@ +package org.springframework.batch.core.step.item; + +/** + * @author Dan Garrette + * @since 2.0.2 + */ +public class FatalSkippableException extends SkippableException { + public FatalSkippableException(String message) { + super(message); + } +} diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantExceptionClassesTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantExceptionClassesTests.java index 674aba8d0..8c3bcde5c 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantExceptionClassesTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantExceptionClassesTests.java @@ -21,6 +21,7 @@ import org.springframework.batch.core.repository.JobExecutionAlreadyRunningExcep import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.repository.JobRestartException; +import org.springframework.batch.core.step.FatalException; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; @@ -121,6 +122,15 @@ public class FaultTolerantExceptionClassesTests implements ApplicationContextAwa assertEquals("[]", writer.getCommitted().toString()); } + @Test + public void testInternalFatalChecked() throws Exception { + writer.setExceptionType(FatalException.class); + StepExecution stepExecution = launchStep("skippableFatalStep"); + assertEquals(BatchStatus.UNKNOWN, stepExecution.getStatus()); + assertEquals("[1, 2, 3]", writer.getWritten().toString()); + assertEquals("[]", writer.getCommitted().toString()); + } + @Test public void testSkippableChecked() throws Exception { writer.setExceptionType(SkippableException.class); @@ -132,7 +142,7 @@ public class FaultTolerantExceptionClassesTests implements ApplicationContextAwa @Test public void testFatalChecked() throws Exception { - writer.setExceptionType(FatalException.class); + writer.setExceptionType(FatalSkippableException.class); StepExecution stepExecution = launchStep("skippableFatalStep"); assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); assertEquals("[1, 2, 3]", writer.getWritten().toString()); @@ -192,7 +202,7 @@ public class FaultTolerantExceptionClassesTests implements ApplicationContextAwa @Test public void testRetryableFatalChecked() throws Exception { - writer.setExceptionType(FatalException.class); + writer.setExceptionType(FatalSkippableException.class); StepExecution stepExecution = launchStep("retryable"); assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); // BATCH-1333: diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/step/item/FaultTolerantExceptionClassesTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/step/item/FaultTolerantExceptionClassesTests-context.xml index e8765a983..62f9db69e 100644 --- a/spring-batch-core/src/test/resources/org/springframework/batch/core/step/item/FaultTolerantExceptionClassesTests-context.xml +++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/step/item/FaultTolerantExceptionClassesTests-context.xml @@ -29,7 +29,7 @@ - + @@ -42,7 +42,7 @@ - + @@ -85,7 +85,7 @@ - + @@ -102,7 +102,7 @@ - +