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:
Dave Syer
2019-04-04 13:48:09 +01:00
parent 8382f73a55
commit 73568416a8
2 changed files with 47 additions and 10 deletions

View File

@@ -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;
}

View File

@@ -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