Fix counting errors in args matchers for recovery
There were off-by-one errors in the recovery argument matching, and also in the copying of arguments from source to target method. Fixes gh-169
This commit is contained in:
@@ -127,7 +127,8 @@ public class RecoverAnnotationRecoveryHandler<T> implements MethodInvocationReco
|
||||
startingIndex = 1;
|
||||
}
|
||||
for (int i = startingIndex; i < parameterTypes.length; i++) {
|
||||
final Object argument = args[i - 1];
|
||||
final Object argument = i - startingIndex < args.length
|
||||
? args[i - startingIndex] : null;
|
||||
if (argument == null) {
|
||||
continue;
|
||||
}
|
||||
@@ -213,7 +214,12 @@ public class RecoverAnnotationRecoveryHandler<T> implements MethodInvocationReco
|
||||
result[0] = t;
|
||||
startArgs = 1;
|
||||
}
|
||||
System.arraycopy(args, 0, result, startArgs, result.length - startArgs);
|
||||
int length = result.length - startArgs > args.length ? args.length
|
||||
: result.length - startArgs;
|
||||
if (length == 0) {
|
||||
return result;
|
||||
}
|
||||
System.arraycopy(args, 0, result, startArgs, length);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,17 +16,18 @@
|
||||
|
||||
package org.springframework.retry.annotation;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.retry.ExhaustedRetryException;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -71,7 +72,7 @@ public class RecoverAnnotationRecoveryHandlerTests {
|
||||
RecoverAnnotationRecoveryHandler<?> handler = new RecoverAnnotationRecoveryHandler<Integer>(
|
||||
new SpecificException(),
|
||||
ReflectionUtils.findMethod(SpecificException.class, "foo", String.class));
|
||||
expected.expect(ExhaustedRetryException.class);
|
||||
this.expected.expect(ExhaustedRetryException.class);
|
||||
handler.recover(new Object[] { "Dave" }, new Error("Planned"));
|
||||
}
|
||||
|
||||
@@ -139,6 +140,17 @@ public class RecoverAnnotationRecoveryHandlerTests {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleQualifyingRecoverMethodsWithNoThrowable() {
|
||||
Method foo = ReflectionUtils.findMethod(
|
||||
MultipleQualifyingRecoversNoThrowable.class, "foo", String.class);
|
||||
RecoverAnnotationRecoveryHandler<?> handler = new RecoverAnnotationRecoveryHandler<Integer>(
|
||||
new MultipleQualifyingRecoversNoThrowable(), foo);
|
||||
assertEquals(1,
|
||||
handler.recover(new Object[] { null }, new RuntimeException("Planned")));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleQualifyingRecoverMethodsReOrdered() {
|
||||
Method foo = ReflectionUtils.findMethod(MultipleQualifyingRecoversReOrdered.class,
|
||||
@@ -165,8 +177,8 @@ public class RecoverAnnotationRecoveryHandlerTests {
|
||||
|
||||
@Test
|
||||
public void inheritanceOnArgumentClass() {
|
||||
Method foo = ReflectionUtils.findMethod(
|
||||
InheritanceOnArgumentClass.class, "foo", List.class);
|
||||
Method foo = ReflectionUtils.findMethod(InheritanceOnArgumentClass.class, "foo",
|
||||
List.class);
|
||||
RecoverAnnotationRecoveryHandler<?> handler = new RecoverAnnotationRecoveryHandler<Integer>(
|
||||
new InheritanceOnArgumentClass(), foo);
|
||||
assertEquals(1, handler.recover(new Object[] { new ArrayList<String>() },
|
||||
@@ -215,7 +227,7 @@ public class RecoverAnnotationRecoveryHandlerTests {
|
||||
}
|
||||
|
||||
public Throwable getCause() {
|
||||
return cause;
|
||||
return this.cause;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -296,6 +308,25 @@ public class RecoverAnnotationRecoveryHandlerTests {
|
||||
|
||||
}
|
||||
|
||||
protected static class MultipleQualifyingRecoversNoThrowable {
|
||||
|
||||
@Retryable
|
||||
public int foo(String name) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Recover
|
||||
public int fooRecover(String name, String nullable) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Recover
|
||||
public int fooRecover(int other, String nullable) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected static class MultipleQualifyingRecovers {
|
||||
|
||||
@Retryable
|
||||
|
||||
Reference in New Issue
Block a user