RESOLVED - issue BATCH-537: Bad ItemKeyGenerator strategy can lead to infinite loop in retry
Some changes to account for retry exceptions and force a failure if strange hashCode/equals are detected.
This commit is contained in:
@@ -42,8 +42,9 @@ public class SimpleRetryExceptionHandlerTests extends TestCase {
|
||||
protected void setUp() throws Exception {
|
||||
RepeatSynchronizationManager.register(context);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see junit.framework.TestCase#tearDown()
|
||||
*/
|
||||
protected void tearDown() throws Exception {
|
||||
@@ -59,7 +60,7 @@ public class SimpleRetryExceptionHandlerTests extends TestCase {
|
||||
RetryPolicy retryPolicy = new NeverRetryPolicy();
|
||||
RuntimeException ex = new RuntimeException("foo");
|
||||
|
||||
SimpleRetryExceptionHandler handler = getHandlerAfterRetry(retryPolicy, ex);
|
||||
SimpleRetryExceptionHandler handler = getHandlerAfterRetry(retryPolicy, ex, new Class[] { Error.class });
|
||||
|
||||
// Then pretend to handle the exception in the parent context...
|
||||
try {
|
||||
@@ -71,7 +72,8 @@ public class SimpleRetryExceptionHandlerTests extends TestCase {
|
||||
}
|
||||
|
||||
assertEquals(0, context.attributeNames().length);
|
||||
// One for the retry exhausted flag and one for the counter in the delegate exception handler
|
||||
// One for the retry exhausted flag and one for the counter in the
|
||||
// delegate exception handler
|
||||
assertEquals(2, context.getParent().attributeNames().length);
|
||||
}
|
||||
|
||||
@@ -84,24 +86,50 @@ public class SimpleRetryExceptionHandlerTests extends TestCase {
|
||||
RetryPolicy retryPolicy = new AlwaysRetryPolicy();
|
||||
RuntimeException ex = new RuntimeException("foo");
|
||||
|
||||
SimpleRetryExceptionHandler handler = getHandlerAfterRetry(retryPolicy, ex);
|
||||
SimpleRetryExceptionHandler handler = getHandlerAfterRetry(retryPolicy, ex, new Class[] { Error.class });
|
||||
|
||||
// Then pretend to handle the exception in the parent context...
|
||||
handler.handleException(context.getParent(), ex);
|
||||
|
||||
|
||||
assertEquals(0, context.attributeNames().length);
|
||||
assertEquals(0, context.getParent().attributeNames().length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.step.item.SimpleRetryExceptionHandler#handleException(org.springframework.batch.repeat.RepeatContext, java.lang.Throwable)}.
|
||||
*/
|
||||
public void testRethrowWhenFatal() throws Throwable {
|
||||
|
||||
RetryPolicy retryPolicy = new AlwaysRetryPolicy();
|
||||
RuntimeException ex = new RuntimeException("foo");
|
||||
|
||||
SimpleRetryExceptionHandler handler = getHandlerAfterRetry(retryPolicy, ex, new Class[] { RuntimeException.class });
|
||||
|
||||
// Then pretend to handle the exception in the parent context...
|
||||
try {
|
||||
handler.handleException(context.getParent(), ex);
|
||||
fail("Expected RuntimeException");
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
assertEquals(ex, e);
|
||||
}
|
||||
|
||||
assertEquals(0, context.attributeNames().length);
|
||||
// One for the counter in the delegate exception handler
|
||||
assertEquals(1, context.getParent().attributeNames().length);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param retryPolicy
|
||||
* @param ex
|
||||
* @return
|
||||
*/
|
||||
private SimpleRetryExceptionHandler getHandlerAfterRetry(RetryPolicy retryPolicy, RuntimeException ex) {
|
||||
|
||||
private SimpleRetryExceptionHandler getHandlerAfterRetry(RetryPolicy retryPolicy, RuntimeException ex, Class[] fatalExceptions) {
|
||||
|
||||
// Always rethrow if the retry is exhausted
|
||||
SimpleRetryExceptionHandler handler = new SimpleRetryExceptionHandler(retryPolicy, new SimpleLimitExceptionHandler(0));
|
||||
SimpleRetryExceptionHandler handler = new SimpleRetryExceptionHandler(retryPolicy,
|
||||
new SimpleLimitExceptionHandler(0), fatalExceptions);
|
||||
|
||||
// Simulate a failed retry...
|
||||
RetryContext retryContext = retryPolicy.open(null, null);
|
||||
|
||||
@@ -32,8 +32,6 @@ import org.springframework.batch.core.repository.dao.MapJobExecutionDao;
|
||||
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.item.ItemOrientedStep;
|
||||
import org.springframework.batch.core.step.item.StatefulRetryStepFactoryBean;
|
||||
import org.springframework.batch.item.AbstractItemWriter;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemRecoverer;
|
||||
@@ -125,5 +123,5 @@ public class StatefulRetryStepFactoryBeanTests extends TestCase {
|
||||
|
||||
step.execute(new StepExecution(step, jobExecution));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user