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 8d4874a87..102fbc804 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 @@ -12,8 +12,6 @@ import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.job.JobSupport; import org.springframework.batch.core.step.JobRepositorySupport; -import org.springframework.batch.core.step.item.ItemOrientedStep; -import org.springframework.batch.core.step.item.SkipLimitStepFactoryBean; import org.springframework.batch.item.ClearFailedException; import org.springframework.batch.item.FlushFailedException; import org.springframework.batch.item.ItemReader; @@ -24,7 +22,6 @@ import org.springframework.batch.item.ParseException; import org.springframework.batch.item.ResetFailedException; import org.springframework.batch.item.Skippable; import org.springframework.batch.item.UnexpectedInputException; -import org.springframework.batch.repeat.RepeatException; import org.springframework.batch.support.transaction.ResourcelessTransactionManager; /** @@ -34,10 +31,7 @@ public class SkipLimitStepFactoryBeanTests extends TestCase { SkipLimitStepFactoryBean tested = new SkipLimitStepFactoryBean(); - // TODO checked exceptions are wrapped as RepeatExceptions by the - // chunkOperations#exceptionHandler - Class[] skippableExceptions = new Class[] { RepeatException.class, SkippableException.class, - SkippableRuntimeException.class }; + Class[] skippableExceptions = new Class[] { SkippableException.class, SkippableRuntimeException.class }; final int SKIP_LIMIT = 2; diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/exception/DefaultExceptionHandler.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/exception/DefaultExceptionHandler.java index b637f9359..108b46a01 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/exception/DefaultExceptionHandler.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/exception/DefaultExceptionHandler.java @@ -17,10 +17,9 @@ package org.springframework.batch.repeat.exception; import org.springframework.batch.repeat.RepeatContext; -import org.springframework.batch.repeat.RepeatException; /** - * Default implementation of {@link ExceptionHandler} - just re-throws the first exception it encounters. + * Default implementation of {@link ExceptionHandler} - just re-throws the exception it encounters. * * @author Dave Syer * @@ -28,33 +27,13 @@ import org.springframework.batch.repeat.RepeatException; public class DefaultExceptionHandler implements ExceptionHandler { /** - * Rethrow the throwable in the collection's iterator. Wrap in a {@link RepeatException} if the first instance is - * not a {@link RuntimeException}. + * Re-throw the throwable. * * @see org.springframework.batch.repeat.exception.ExceptionHandler#handleException(RepeatContext, * Throwable) */ public void handleException(RepeatContext context, Throwable throwable) throws Throwable { - rethrow(throwable); - } - - /** - * Convenience method to rethrow the Throwable instance. Wraps it in a {@link RepeatException} if it is not a - * {@link RuntimeException} or {@link Error}. - * - * @param throwable a Throwable. - * @throws RuntimeException if the throwable is a {@link RuntimeException} - * @throws Error if the throwable is an {@link Error} - * @throws RepeatException otherwise - */ - public static void rethrow(Throwable throwable) throws RuntimeException { - if (throwable instanceof Error) { - throw (Error) throwable; - } else if (throwable instanceof RuntimeException) { - throw (RuntimeException) throwable; - } else { - throw new RepeatException("Exception in batch process", throwable); - } + throw throwable; } } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/exception/LogOrRethrowExceptionHandler.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/exception/LogOrRethrowExceptionHandler.java index 4838c4917..d56bfa955 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/exception/LogOrRethrowExceptionHandler.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/exception/LogOrRethrowExceptionHandler.java @@ -75,7 +75,7 @@ public class LogOrRethrowExceptionHandler implements ExceptionHandler { /** * Classify the throwables and decide whether to rethrow based on the result. The context is not used. * - * @throws RuntimeException + * @throws Throwable * * @see {@link ExceptionHandler#handleException(RepeatContext, Throwable)} */ @@ -89,7 +89,7 @@ public class LogOrRethrowExceptionHandler implements ExceptionHandler { } else if (DEBUG.equals(key) && logger.isDebugEnabled()) { logger.debug("Exception encountered in batch repeat.", throwable); } else if (RETHROW.equals(key)) { - DefaultExceptionHandler.rethrow(throwable); + throw throwable; } else { throw new IllegalStateException( "Unclassified exception encountered. Did you mean to classifiy this as 'rethrow'?"); diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/exception/RethrowOnThresholdExceptionHandler.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/exception/RethrowOnThresholdExceptionHandler.java index 318ff78be..882ca3f78 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/exception/RethrowOnThresholdExceptionHandler.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/exception/RethrowOnThresholdExceptionHandler.java @@ -123,7 +123,7 @@ public class RethrowOnThresholdExceptionHandler implements ExceptionHandler { int count = counter.getCount(); Integer threshold = (Integer) thresholds.get(key); if (threshold == null || count > threshold.intValue()) { - DefaultExceptionHandler.rethrow(throwable); + throw throwable; } } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/RepeatTemplate.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/RepeatTemplate.java index 5d80b291b..ec9737fb4 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/RepeatTemplate.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/support/RepeatTemplate.java @@ -27,6 +27,7 @@ import org.springframework.batch.repeat.CompletionPolicy; import org.springframework.batch.repeat.ExitStatus; import org.springframework.batch.repeat.RepeatCallback; import org.springframework.batch.repeat.RepeatContext; +import org.springframework.batch.repeat.RepeatException; import org.springframework.batch.repeat.RepeatListener; import org.springframework.batch.repeat.RepeatOperations; import org.springframework.batch.repeat.exception.DefaultExceptionHandler; @@ -227,7 +228,8 @@ public class RepeatTemplate implements RepeatOperations { logger.debug("Exception intercepted (" + (i + 1) + " of " + listeners.length + ")", throwable); } - exceptionHandler.handleException(context, throwable); + + exceptionHandler.handleException(context, unwrapIfRethrown(throwable)); } catch (Throwable handled) { @@ -285,11 +287,31 @@ public class RepeatTemplate implements RepeatOperations { } /** - * @param next - * @return + * Re-throws the original throwable if it is unchecked, wraps checked + * exceptions into {@link RepeatException}. */ - private static void rethrow(Throwable next) throws RuntimeException { - DefaultExceptionHandler.rethrow(next); + private static void rethrow(Throwable throwable) throws RuntimeException { + if (throwable instanceof Error) { + throw (Error) throwable; + } + else if (throwable instanceof RuntimeException) { + throw (RuntimeException) throwable; + } + else { + throw new RepeatException("Exception in batch process", throwable); + } + } + + /** + * Unwraps the throwable if it has been wrapped by {@link #rethrow(Throwable)}. + */ + private static Throwable unwrapIfRethrown(Throwable throwable) { + if (throwable instanceof RepeatException) { + return throwable.getCause(); + } + else { + return throwable; + } } /** diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/interceptor/RepeatOperationsInterceptorTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/interceptor/RepeatOperationsInterceptorTests.java index 06cd78309..fe97dee24 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/interceptor/RepeatOperationsInterceptorTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/interceptor/RepeatOperationsInterceptorTests.java @@ -29,9 +29,7 @@ import org.springframework.aop.framework.Advised; import org.springframework.aop.framework.ProxyFactory; import org.springframework.batch.repeat.ExitStatus; import org.springframework.batch.repeat.RepeatCallback; -import org.springframework.batch.repeat.RepeatException; import org.springframework.batch.repeat.RepeatOperations; -import org.springframework.batch.repeat.interceptor.RepeatOperationsInterceptor; import org.springframework.batch.repeat.policy.SimpleCompletionPolicy; import org.springframework.batch.repeat.support.RepeatTemplate; @@ -100,8 +98,8 @@ public class RepeatOperationsInterceptorTests extends TestCase { try { service.error(); fail("Expected BatchException"); - } catch (RepeatException e) { - assertEquals("Unexpected", e.getMessage().substring(0, 10)); + } catch (Error e) { + assertEquals("Duh", e.getMessage().substring(0, 3)); } }