OPEN - issue BATCH-777: Parametrise RetryCallback and related interfaces
Downgrade throws clause in RetryCallback - it's not reasonable to retry arbitrary Throwable
This commit is contained in:
@@ -458,7 +458,7 @@ public class SkipLimitStepFactoryBean<T, S> extends SimpleStepFactoryBean<T, S>
|
||||
private void retryChunk(final Chunk<S> chunk, final StepContribution contribution) throws Exception {
|
||||
|
||||
RecoveryRetryCallback retryCallback = new RecoveryRetryCallback(chunk, new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
doWrite(chunk.getItems());
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -15,11 +15,18 @@
|
||||
*/
|
||||
package org.springframework.batch.container.jms;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import javax.jms.Message;
|
||||
import javax.jms.MessageListener;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.batch.retry.RecoveryCallback;
|
||||
import org.springframework.batch.retry.RetryCallback;
|
||||
import org.springframework.batch.retry.RetryContext;
|
||||
@@ -27,14 +34,10 @@ import org.springframework.batch.retry.callback.RecoveryRetryCallback;
|
||||
import org.springframework.batch.retry.policy.NeverRetryPolicy;
|
||||
import org.springframework.batch.retry.policy.RecoveryCallbackRetryPolicy;
|
||||
import org.springframework.batch.retry.support.RetryTemplate;
|
||||
import org.springframework.jms.core.JmsTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.jms.core.JmsTemplate;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.junit.Before;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -54,19 +57,18 @@ public class BatchMessageListenerContainerIntegrationTests {
|
||||
|
||||
private volatile int count;
|
||||
|
||||
@After
|
||||
@Before
|
||||
public void onSetUp() throws Exception {
|
||||
public void drainQueue() throws Exception {
|
||||
container.stop();
|
||||
while(jmsTemplate.receiveAndConvert("queue")!=null) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void onTearDown() throws Exception {
|
||||
container.stop();
|
||||
while(jmsTemplate.receiveAndConvert("queue")!=null) {
|
||||
// do nothing
|
||||
}
|
||||
@AfterClass
|
||||
public static void giveContainerTimeToStop() throws Exception {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -122,7 +124,7 @@ public class BatchMessageListenerContainerIntegrationTests {
|
||||
public void onMessage(final Message msg) {
|
||||
try {
|
||||
RecoveryRetryCallback callback = new RecoveryRetryCallback(msg, new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
count++;
|
||||
throw new RuntimeException("planned failure: " + msg);
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ public class ExternalRetryInBatchTests {
|
||||
}
|
||||
|
||||
RecoveryRetryCallback callback = new RecoveryRetryCallback(item, new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
// No need for transaction here: the whole batch will roll
|
||||
// back. When it comes back for recovery this code is not
|
||||
// executed...
|
||||
|
||||
@@ -130,7 +130,7 @@ public class ExternalRetryTests {
|
||||
try {
|
||||
final Object item = provider.read();
|
||||
RecoveryRetryCallback callback = new RecoveryRetryCallback(item, new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
writer.write(Collections.singletonList(item));
|
||||
return null;
|
||||
}
|
||||
@@ -158,7 +158,7 @@ public class ExternalRetryTests {
|
||||
try {
|
||||
final Object item = provider.read();
|
||||
RecoveryRetryCallback callback = new RecoveryRetryCallback(item, new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
writer.write(Collections.singletonList(item));
|
||||
return null;
|
||||
}
|
||||
@@ -193,7 +193,7 @@ public class ExternalRetryTests {
|
||||
|
||||
final Object item = provider.read();
|
||||
final RecoveryRetryCallback callback = new RecoveryRetryCallback(item, new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
simpleJdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", list.size(), item);
|
||||
throw new RuntimeException("Rollback!");
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ public class SynchronousTests {
|
||||
assertNotNull(text);
|
||||
|
||||
retryTemplate.execute(new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext status) throws Throwable {
|
||||
public Object doWithRetry(RetryContext status) throws Exception {
|
||||
|
||||
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
|
||||
transactionTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_NESTED);
|
||||
@@ -173,7 +173,7 @@ public class SynchronousTests {
|
||||
final Object item = provider.read();
|
||||
|
||||
retryTemplate.execute(new RecoveryRetryCallback(item, new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
|
||||
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
|
||||
transactionTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_NESTED);
|
||||
@@ -234,7 +234,7 @@ public class SynchronousTests {
|
||||
|
||||
try {
|
||||
retryTemplate.execute(new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext status) throws Throwable {
|
||||
public Object doWithRetry(RetryContext status) throws Exception {
|
||||
|
||||
TransactionTemplate nestedTxTemplate = new TransactionTemplate(transactionManager);
|
||||
nestedTxTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_NESTED);
|
||||
@@ -289,7 +289,7 @@ public class SynchronousTests {
|
||||
assertInitialState();
|
||||
|
||||
retryTemplate.execute(new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext status) throws Throwable {
|
||||
public Object doWithRetry(RetryContext status) throws Exception {
|
||||
|
||||
// use REQUIRES_NEW so that the retry executes in its own transaction
|
||||
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
|
||||
@@ -337,7 +337,7 @@ public class SynchronousTests {
|
||||
try {
|
||||
|
||||
retryTemplate.execute(new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext status) throws Throwable {
|
||||
public Object doWithRetry(RetryContext status) throws Exception {
|
||||
|
||||
// use REQUIRES_NEW so that the retry executes in its own transaction
|
||||
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
|
||||
|
||||
@@ -30,6 +30,7 @@ public interface RetryCallback {
|
||||
* semantics when an operation is retried.
|
||||
* @param context the current retry context.
|
||||
* @return the result of the successful operation.
|
||||
* @throws Exception TODO
|
||||
*/
|
||||
Object doWithRetry(RetryContext context) throws Throwable;
|
||||
Object doWithRetry(RetryContext context) throws Exception;
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ public class RecoveryRetryCallback implements RetryCallback {
|
||||
this.forceRefresh = forceRefresh;
|
||||
}
|
||||
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
return callback.doWithRetry(context);
|
||||
// N.B. code used to check here for isExhaustedOnly and throw exception.
|
||||
// This is unnecessary because the callback could just throw the
|
||||
|
||||
@@ -54,7 +54,7 @@ public class RetryOperationsInterceptor implements MethodInterceptor {
|
||||
|
||||
return this.retryOperations.execute(new RetryCallback() {
|
||||
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
|
||||
/*
|
||||
* If we don't copy the invocation carefully it won't keep a
|
||||
@@ -64,8 +64,17 @@ public class RetryOperationsInterceptor implements MethodInterceptor {
|
||||
* implementation come along?).
|
||||
*/
|
||||
if (invocation instanceof ProxyMethodInvocation) {
|
||||
return ((ProxyMethodInvocation) invocation)
|
||||
.invocableClone().proceed();
|
||||
try {
|
||||
return ((ProxyMethodInvocation) invocation)
|
||||
.invocableClone().proceed();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw e;
|
||||
} catch (Error e) {
|
||||
throw e;
|
||||
} catch (Throwable e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"MethodInvocation of the wrong type detected - this should not happen with Spring AOP, so please raise an issue if you see this exception");
|
||||
|
||||
@@ -174,8 +174,19 @@ public class StatefulRetryOperationsInterceptor implements MethodInterceptor {
|
||||
this.invocation = invocation;
|
||||
}
|
||||
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
return invocation.proceed();
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
try {
|
||||
return invocation.proceed();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Error e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.retry.RetryCallback;
|
||||
import org.springframework.batch.retry.RetryContext;
|
||||
import org.springframework.batch.retry.RetryException;
|
||||
import org.springframework.batch.retry.RetryListener;
|
||||
import org.springframework.batch.retry.RetryOperations;
|
||||
import org.springframework.batch.retry.RetryPolicy;
|
||||
@@ -167,17 +166,17 @@ public class RetryTemplate implements RetryOperations {
|
||||
lastException = null;
|
||||
return callback.doWithRetry(context);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
Throwable throwable = unwrapIfRethrown(ex);
|
||||
lastException = throwable;
|
||||
catch (Exception e) {
|
||||
|
||||
doOnErrorInterceptors(callback, context, throwable);
|
||||
lastException = e;
|
||||
|
||||
retryPolicy.registerThrowable(context, throwable);
|
||||
doOnErrorInterceptors(callback, context, e);
|
||||
|
||||
retryPolicy.registerThrowable(context, e);
|
||||
|
||||
if (retryPolicy.shouldRethrow(context)) {
|
||||
logger.debug("Rethrow in retry for policy: count=" + context.getRetryCount());
|
||||
rethrow(throwable);
|
||||
throw e;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -190,7 +189,7 @@ public class RetryTemplate implements RetryOperations {
|
||||
// back off was prevented by another thread - fail the
|
||||
// retry
|
||||
logger.debug("Abort retry because interrupted: count=" + context.getRetryCount());
|
||||
rethrow(e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -235,44 +234,4 @@ public class RetryTemplate implements RetryOperations {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-throw the exception directly if possible, wrap custom Throwables into
|
||||
* {@link UnclassifiedRetryException}.
|
||||
*/
|
||||
private static void rethrow(Throwable throwable) throws Exception {
|
||||
if (throwable instanceof Exception) {
|
||||
throw (Exception) throwable;
|
||||
}
|
||||
else if (throwable instanceof Error) {
|
||||
throw (Error) throwable;
|
||||
}
|
||||
else {
|
||||
throw new UnclassifiedRetryException("Unclassified Throwable encountered", throwable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Undo the wrapping done in {@link #rethrow(Throwable)}
|
||||
*/
|
||||
private static Throwable unwrapIfRethrown(Throwable throwable) {
|
||||
if (throwable instanceof UnclassifiedRetryException) {
|
||||
return throwable.getCause();
|
||||
}
|
||||
else {
|
||||
return throwable;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runtime exception wrapper for Throwables that are neither Exception nor
|
||||
* Error.
|
||||
*/
|
||||
private static class UnclassifiedRetryException extends RetryException {
|
||||
|
||||
public UnclassifiedRetryException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ public class RecoveryRetryCallbackTests extends TestCase {
|
||||
}
|
||||
};
|
||||
callback = new RecoveryRetryCallback("foo", new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
count++;
|
||||
return null;
|
||||
}
|
||||
@@ -73,7 +73,7 @@ public class RecoveryRetryCallbackTests extends TestCase {
|
||||
// We can use the policy to intercept the context and do something with
|
||||
// the item...
|
||||
callback = new RecoveryRetryCallback("bar", new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
count++;
|
||||
throw new IllegalStateException("Detected bar");
|
||||
}
|
||||
@@ -109,7 +109,7 @@ public class RecoveryRetryCallbackTests extends TestCase {
|
||||
// We can use the policy to intercept the context and do something with
|
||||
// the item...
|
||||
callback = new RecoveryRetryCallback("bar", new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
count++;
|
||||
throw new IllegalStateException("Detected bar");
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class RetryListenerTests extends TestCase {
|
||||
}
|
||||
} });
|
||||
template.execute(new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@@ -69,7 +69,7 @@ public class RetryListenerTests extends TestCase {
|
||||
});
|
||||
try {
|
||||
template.execute(new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
count++;
|
||||
return null;
|
||||
}
|
||||
@@ -97,7 +97,7 @@ public class RetryListenerTests extends TestCase {
|
||||
}
|
||||
} });
|
||||
template.execute(new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@@ -120,7 +120,7 @@ public class RetryListenerTests extends TestCase {
|
||||
} });
|
||||
try {
|
||||
template.execute(new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
count++;
|
||||
throw new IllegalStateException("foo");
|
||||
}
|
||||
@@ -147,7 +147,7 @@ public class RetryListenerTests extends TestCase {
|
||||
}
|
||||
});
|
||||
template.execute(new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
if (count++ < 1)
|
||||
throw new RuntimeException("Retry!");
|
||||
return null;
|
||||
|
||||
@@ -121,7 +121,7 @@ public class ExternalRetryIntergrationTests {
|
||||
private final class MockRetryCallback implements RetryCallback {
|
||||
int attempts = 0;
|
||||
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
attempts++;
|
||||
if (attempts < 2) {
|
||||
throw new RuntimeException();
|
||||
|
||||
@@ -43,7 +43,7 @@ public class RecoveryRetryPolicyTests extends TestCase {
|
||||
|
||||
final StringHolder item = new StringHolder("foo");
|
||||
RetryCallback writer = new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
count++;
|
||||
list.add(item.string);
|
||||
return item;
|
||||
@@ -59,7 +59,7 @@ public class RecoveryRetryPolicyTests extends TestCase {
|
||||
public void testOpenWithWrongCallbackType() {
|
||||
try {
|
||||
policy.open(new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
return null;
|
||||
}
|
||||
}, null);
|
||||
@@ -74,7 +74,7 @@ public class RecoveryRetryPolicyTests extends TestCase {
|
||||
policy.setDelegate(new AlwaysRetryPolicy());
|
||||
|
||||
RetryContext context = policy.open(new RecoveryRetryCallback("foo", new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
count++;
|
||||
return null;
|
||||
}
|
||||
@@ -88,7 +88,7 @@ public class RecoveryRetryPolicyTests extends TestCase {
|
||||
public void testRegisterThrowable() {
|
||||
policy.setDelegate(new NeverRetryPolicy());
|
||||
RetryContext context = policy.open(new RecoveryRetryCallback("foo", new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
count++;
|
||||
return null;
|
||||
}
|
||||
@@ -101,7 +101,7 @@ public class RecoveryRetryPolicyTests extends TestCase {
|
||||
public void testClose() throws Exception {
|
||||
policy.setDelegate(new NeverRetryPolicy());
|
||||
RetryContext context = policy.open(new RecoveryRetryCallback("foo", new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
count++;
|
||||
return null;
|
||||
}
|
||||
@@ -117,7 +117,7 @@ public class RecoveryRetryPolicyTests extends TestCase {
|
||||
|
||||
public void testOpenTwice() throws Exception {
|
||||
RecoveryRetryCallback callback = new RecoveryRetryCallback("foo", new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
count++;
|
||||
return null;
|
||||
}
|
||||
@@ -145,7 +145,7 @@ public class RecoveryRetryPolicyTests extends TestCase {
|
||||
policy.setDelegate(new SimpleRetryPolicy(1));
|
||||
final String input = "foo";
|
||||
RecoveryRetryCallback callback = new RecoveryRetryCallback(input, new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
@@ -184,7 +184,7 @@ public class RecoveryRetryPolicyTests extends TestCase {
|
||||
policy.setDelegate(new SimpleRetryPolicy(1));
|
||||
final String input = "foo";
|
||||
RecoveryRetryCallback callback = new RecoveryRetryCallback(input, new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
throw new RuntimeException("Barf!");
|
||||
}
|
||||
});
|
||||
@@ -214,7 +214,7 @@ public class RecoveryRetryPolicyTests extends TestCase {
|
||||
|
||||
public void testExhaustedClearsHistoryAfterLastAttempt() throws Exception {
|
||||
RecoveryRetryCallback callback = new RecoveryRetryCallback("foo", new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
count++;
|
||||
return null;
|
||||
}
|
||||
@@ -242,7 +242,7 @@ public class RecoveryRetryPolicyTests extends TestCase {
|
||||
policy = new RecoveryCallbackRetryPolicy();
|
||||
policy.setDelegate(new SimpleRetryPolicy(1));
|
||||
RetryContext context = policy.open(new RecoveryRetryCallback("foo", new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
count++;
|
||||
return null;
|
||||
}
|
||||
@@ -257,7 +257,7 @@ public class RecoveryRetryPolicyTests extends TestCase {
|
||||
|
||||
public void testRetryCountPreservedBetweenRetries() throws Exception {
|
||||
RecoveryRetryCallback callback = new RecoveryRetryCallback("bar", new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
count++;
|
||||
return null;
|
||||
}
|
||||
@@ -282,7 +282,7 @@ public class RecoveryRetryPolicyTests extends TestCase {
|
||||
final StringHolder item = new StringHolder("bar");
|
||||
|
||||
RetryCallback writer = new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
// This simulates what happens if someone uses a primary key
|
||||
// for hasCode and equals and then relies on default key
|
||||
// generator
|
||||
@@ -320,7 +320,7 @@ public class RecoveryRetryPolicyTests extends TestCase {
|
||||
final StringHolder item = new StringHolder("foo");
|
||||
|
||||
RetryCallback writer = new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
count++;
|
||||
list.add(item.string);
|
||||
return item;
|
||||
@@ -349,7 +349,7 @@ public class RecoveryRetryPolicyTests extends TestCase {
|
||||
final StringHolder item = new StringHolder("foo");
|
||||
|
||||
RetryCallback writer = new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
count++;
|
||||
list.add(item.string);
|
||||
return item;
|
||||
|
||||
@@ -23,13 +23,10 @@ import junit.framework.TestCase;
|
||||
import org.springframework.batch.retry.ExhaustedRetryException;
|
||||
import org.springframework.batch.retry.RetryCallback;
|
||||
import org.springframework.batch.retry.RetryContext;
|
||||
import org.springframework.batch.retry.RetryException;
|
||||
import org.springframework.batch.retry.RetryListener;
|
||||
import org.springframework.batch.retry.backoff.BackOffContext;
|
||||
import org.springframework.batch.retry.backoff.BackOffInterruptedException;
|
||||
import org.springframework.batch.retry.backoff.BackOffPolicy;
|
||||
import org.springframework.batch.retry.backoff.StatelessBackOffPolicy;
|
||||
import org.springframework.batch.retry.listener.RetryListenerSupport;
|
||||
import org.springframework.batch.retry.policy.NeverRetryPolicy;
|
||||
import org.springframework.batch.retry.policy.SimpleRetryPolicy;
|
||||
|
||||
@@ -141,7 +138,7 @@ public class RetryTemplateTests extends TestCase {
|
||||
try {
|
||||
RetryTemplate retryTemplate = new RetryTemplate();
|
||||
retryTemplate.execute(new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext status) throws Throwable {
|
||||
public Object doWithRetry(RetryContext status) throws Exception {
|
||||
status.setExhaustedOnly();
|
||||
throw new IllegalStateException("Retry this operation");
|
||||
}
|
||||
@@ -159,11 +156,11 @@ public class RetryTemplateTests extends TestCase {
|
||||
RetryTemplate outer = new RetryTemplate();
|
||||
final RetryTemplate inner = new RetryTemplate();
|
||||
outer.execute(new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext status) throws Throwable {
|
||||
public Object doWithRetry(RetryContext status) throws Exception {
|
||||
context = status;
|
||||
count++;
|
||||
Object result = inner.execute(new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext status) throws Throwable {
|
||||
public Object doWithRetry(RetryContext status) throws Exception {
|
||||
count++;
|
||||
assertNotNull(context);
|
||||
assertNotSame(status, context);
|
||||
@@ -184,7 +181,7 @@ public class RetryTemplateTests extends TestCase {
|
||||
retryTemplate.setRetryPolicy(new NeverRetryPolicy());
|
||||
try {
|
||||
retryTemplate.execute(new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
throw new Error("Realllly bad!");
|
||||
}
|
||||
});
|
||||
@@ -204,7 +201,7 @@ public class RetryTemplateTests extends TestCase {
|
||||
});
|
||||
try {
|
||||
retryTemplate.execute(new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
public Object doWithRetry(RetryContext context) throws Exception {
|
||||
throw new RuntimeException("Bad!");
|
||||
}
|
||||
});
|
||||
@@ -239,74 +236,6 @@ public class RetryTemplateTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throwables that aren't Exception nor Error are wrapped into
|
||||
* RetryException.
|
||||
*/
|
||||
public void testThrowableWrapping() throws Exception {
|
||||
RetryCallback callback = new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
throw new Throwable("throwable in callback");
|
||||
}
|
||||
};
|
||||
RetryTemplate template = new RetryTemplate();
|
||||
|
||||
try {
|
||||
template.execute(callback);
|
||||
fail();
|
||||
}
|
||||
catch (RetryException expected) {
|
||||
assertTrue(expected.getMessage().contains("Unclassified Throwable encountered"));
|
||||
assertEquals("throwable in callback", expected.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If nested template wraps unclassified Throwable into RetryException the
|
||||
* Throwable is unwrapped before passed to collaborators.
|
||||
*/
|
||||
public void testThrowableUnwrapping() throws Exception {
|
||||
|
||||
final RetryCallback throwingCallback = new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
throw new Throwable("Crashed terribly");
|
||||
}
|
||||
};
|
||||
final RetryTemplate nested = new RetryTemplate();
|
||||
|
||||
RetryCallback callNested = new RetryCallback() {
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
return nested.execute(throwingCallback);
|
||||
}
|
||||
};
|
||||
ExceptionCheckingListener listener = new ExceptionCheckingListener();
|
||||
RetryTemplate template = new RetryTemplate();
|
||||
template.setListeners(new RetryListener[] { listener });
|
||||
|
||||
try {
|
||||
template.execute(callNested);
|
||||
fail();
|
||||
}
|
||||
catch (RetryException expected) {
|
||||
assertTrue(expected.getMessage().contains("Unclassified Throwable encountered"));
|
||||
assertEquals("Crashed terribly", expected.getCause().getMessage());
|
||||
}
|
||||
assertTrue(listener.called);
|
||||
}
|
||||
|
||||
private static class ExceptionCheckingListener extends RetryListenerSupport {
|
||||
|
||||
boolean called = false;
|
||||
|
||||
public void onError(RetryContext context, RetryCallback callback, Throwable throwable) {
|
||||
called = true;
|
||||
assertFalse(throwable instanceof Exception);
|
||||
assertFalse(throwable instanceof Error);
|
||||
assertEquals("Crashed terribly", throwable.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class MockRetryCallback implements RetryCallback {
|
||||
|
||||
private int attempts;
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
<property name="commitInterval" value="1" />
|
||||
</bean>
|
||||
|
||||
<bean id="skipLimitStep" class="org.springframework.batch.core.step.item.SkipLimitStepFactoryBean"
|
||||
parent="simpleStep" abstract="true">
|
||||
<property name="skipLimit" value="0" />
|
||||
<bean id="skipLimitStep" class="org.springframework.batch.core.step.item.SkipLimitStepFactoryBean"
|
||||
parent="simpleStep" abstract="true">
|
||||
<property name="skipLimit" value="0" />
|
||||
</bean>
|
||||
|
||||
<bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
|
||||
|
||||
Reference in New Issue
Block a user