Description
While using Spring retryable , we came across a scenario where in we have 2 methods with retryable annotation and we defined their respective recovery methods as well .
These methods have different signature (an extra argument is present in one of the methods i.e retryable2
When retry looks for recovery method. It always considers method recover1.
@Component
public class TestRetryService {
@Retryable(maxAttempts = 3, value = NullPointerException.class)
public void retryable1(String name) {
System.out.println("in retryable1");
throw new NullPointerException("from ret1");
}
@Retryable(maxAttempts = 3, value = NullPointerException.class)
public void retryable2(String name, String address) {
System.out.println("in retryable2");
throw new NullPointerException("from ret2");
}
@Recover
public void recover1(NullPointerException ne, String name ){
System.out.println("in recover1");
}
@Recover
public void recover2(NullPointerException ne, String name,String address){
System.out.println("in recover2");
}
}
Our test class ::
@RunWith(SpringRunner.class)
@NonTransactionalIntegrationTest
public class TestRetryServiceTest {
@Autowired
private TestRetryService testRetryService;
@Test
public void test(){
testRetryService.retryable1("name1","add1");
}
@Test
public void test2(){
testRetryService.retryable2("name1");
}
}
We see the @Recover
interface has this statement in its documentation
"Subsequent arguments are populated from the argument list of the failed method in order.", however we do not see this happening.
Also a quick glance at the snippet in RecoverAnnotationRecoveryHandler::findClosestMatch
tells us that the algorithm looks for a closest matching recovery method based on distance between type(Throwable
) of the recovery method(s) and the cause(i.e. value) defined in the Retryable
(i.e. failed method).
We believe that arguments passed to recovery methods should also be considered as valid candidates to find closest matching recovery method.