IN PROGRESS - issue BATCH-422: Provide ability to specify exception types as well as skip limit in DefaultStepFactoryBean
http://jira.springframework.org/browse/BATCH-422 The desired functionality should now be there, but needs better tests
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
package org.springframework.batch.core.step;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.springframework.batch.repeat.exception.SimpleLimitExceptionHandler;
|
||||
|
||||
/**
|
||||
@@ -10,6 +12,8 @@ public class SkipLimitStepFactoryBean extends DefaultStepFactoryBean {
|
||||
|
||||
private int skipLimit = 0;
|
||||
|
||||
private Class[] skippableExceptionClasses = new Class[]{ Exception.class };
|
||||
|
||||
/**
|
||||
* Public setter for a limit that determines skip policy. If this value is
|
||||
* positive then an exception in chunk processing will cause the item to be
|
||||
@@ -22,6 +26,17 @@ public class SkipLimitStepFactoryBean extends DefaultStepFactoryBean {
|
||||
public void setSkipLimit(int skipLimit) {
|
||||
this.skipLimit = skipLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for exception classes that when raised won't crash the job
|
||||
* but will result in transaction rollback and the item which handling caused
|
||||
* the exception will be skipped.
|
||||
*
|
||||
* @param skippableExceptionClasses defaults to <code>Exception</code>
|
||||
*/
|
||||
public void setSkippableExceptionClasses(Class[] exceptionClasses) {
|
||||
this.skippableExceptionClasses = exceptionClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the {@link #skipLimit} value to configure item handler and
|
||||
@@ -38,7 +53,10 @@ public class SkipLimitStepFactoryBean extends DefaultStepFactoryBean {
|
||||
* to absorb exceptions at the step level because the failed items
|
||||
* will never re-appear after a rollback.
|
||||
*/
|
||||
itemHandler.setItemSkipPolicy(new LimitCheckingItemSkipPolicy(skipLimit));
|
||||
itemHandler.setItemSkipPolicy(new LimitCheckingItemSkipPolicy(skipLimit, Arrays.asList(skippableExceptionClasses)));
|
||||
SimpleLimitExceptionHandler exceptionHandler = new SimpleLimitExceptionHandler();
|
||||
exceptionHandler.setLimit(skipLimit);
|
||||
exceptionHandler.setExceptionClasses(skippableExceptionClasses);
|
||||
setExceptionHandler(new SimpleLimitExceptionHandler(skipLimit));
|
||||
getStepOperations().setExceptionHandler(getExceptionHandler());
|
||||
}
|
||||
@@ -50,5 +68,4 @@ public class SkipLimitStepFactoryBean extends DefaultStepFactoryBean {
|
||||
step.setItemHandler(itemHandler);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class SimpleLimitExceptionHandler implements ExceptionHandler {
|
||||
|
||||
private RethrowOnThresholdExceptionHandler delegate = new RethrowOnThresholdExceptionHandler();
|
||||
|
||||
private Class type = Exception.class;
|
||||
private Class[] exceptionClasses = new Class[] { Exception.class };
|
||||
|
||||
/**
|
||||
* Flag to indicate the the exception counters should be shared between
|
||||
@@ -68,8 +68,10 @@ public class SimpleLimitExceptionHandler implements ExceptionHandler {
|
||||
super();
|
||||
delegate.setExceptionClassifier(new ExceptionClassifierSupport() {
|
||||
public Object classify(Throwable throwable) {
|
||||
if (type.isAssignableFrom(throwable.getClass())) {
|
||||
return TX_INVALID;
|
||||
for (int i = 0; i < exceptionClasses.length; i++) {
|
||||
if (exceptionClasses[i].isAssignableFrom(throwable.getClass())) {
|
||||
return TX_INVALID;
|
||||
}
|
||||
}
|
||||
return super.classify(throwable);
|
||||
}
|
||||
@@ -106,13 +108,15 @@ public class SimpleLimitExceptionHandler implements ExceptionHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the Throwable type that this handler counts. Defaults to
|
||||
* {@link Exception}.
|
||||
* Setter for the Throwable exceptionClasses that this handler counts. Defaults to
|
||||
* {@link Exception}. If more exceptionClasses are specified handler uses single
|
||||
* counter that is incremented when one of the recognized exception
|
||||
* exceptionClasses is handled.
|
||||
*
|
||||
* @param type
|
||||
*/
|
||||
public void setType(Class type) {
|
||||
this.type = type;
|
||||
public void setExceptionClasses(Class[] classes) {
|
||||
this.exceptionClasses = classes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public class SimpleLimitExceptionHandlerTests extends TestCase {
|
||||
|
||||
final int MORE_THAN_ZERO = 1;
|
||||
handler.setLimit(MORE_THAN_ZERO);
|
||||
handler.setType(IllegalArgumentException.class);
|
||||
handler.setExceptionClasses(new Class[] { IllegalArgumentException.class });
|
||||
|
||||
try {
|
||||
handler.handleException(new RepeatContextSupport(null), throwable);
|
||||
@@ -82,7 +82,7 @@ public class SimpleLimitExceptionHandlerTests extends TestCase {
|
||||
public void testLimitedExceptionTypeNotThrown() throws Exception {
|
||||
final int MORE_THAN_ZERO = 1;
|
||||
handler.setLimit(MORE_THAN_ZERO);
|
||||
handler.setType(RuntimeException.class);
|
||||
handler.setExceptionClasses(new Class[] {RuntimeException.class} );
|
||||
|
||||
try {
|
||||
handler.handleException(new RepeatContextSupport(null), new RuntimeException("foo"));
|
||||
@@ -101,7 +101,7 @@ public class SimpleLimitExceptionHandlerTests extends TestCase {
|
||||
|
||||
final int MORE_THAN_ZERO = 1;
|
||||
handler.setLimit(MORE_THAN_ZERO);
|
||||
handler.setType(RuntimeException.class);
|
||||
handler.setExceptionClasses(new Class[] {RuntimeException.class});
|
||||
|
||||
RepeatContextSupport parent = new RepeatContextSupport(null);
|
||||
|
||||
@@ -125,7 +125,7 @@ public class SimpleLimitExceptionHandlerTests extends TestCase {
|
||||
|
||||
final int MORE_THAN_ZERO = 1;
|
||||
handler.setLimit(MORE_THAN_ZERO);
|
||||
handler.setType(RuntimeException.class);
|
||||
handler.setExceptionClasses(new Class[] { RuntimeException.class } );
|
||||
handler.setUseParent(true);
|
||||
|
||||
RepeatContextSupport parent = new RepeatContextSupport(null);
|
||||
|
||||
Reference in New Issue
Block a user