Spring Retry only for specific exceptions (using RetryTemplateBuilder)

In this post under Spring Retry, I will show with example how to configure Spring Retry to retry failed operations for specific exception only using RetryTemplateBuilder.

For our example, we will use the below Service class

Service Class


import java.util.NoSuchElementException;

public class Service4 {
    private int i = 0;
    private int j = 0;
    private int k = 0;

    public void executeWithNullPointerException() {
        i = i + 1;
        System.out.println("Executing 'executeWithNullPointerException' : " + i);
        throw new NullPointerException();
    }

    public void executeWithIllegalArgumentException() {
        j = j + 1;
        System.out.println("Executing 'executeWithIllegalArgumentException' : " + j);
        throw new IllegalArgumentException();
    }

    public void executeWithNoSuchElementException() {
        k = k + 1;
        System.out.println("Executing 'executeWithNoSuchElementException' : " + k);
        throw new NoSuchElementException();
    }
}

In the above Service class, we have three methods that throws exceptions, one method throws NullPointerException, another method throws IllegalArgumentException, and third method throws NoSuchElementException.

Below is the xml configuration

XML Code


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <bean id="service4" class="Service4"/>
</beans>

As you can see in the above xml code, there is only one bean declared which is of type Service4 class.

Next we will see the main code where we configure RetryTemplate to retry on specific exceptions using RetryTemplateBuilder class.

Main Class


1  import java.util.NoSuchElementException;
2  
3  import org.springframework.context.ApplicationContext;
4  import org.springframework.context.support.ClassPathXmlApplicationContext;
5  import org.springframework.retry.support.RetryTemplate;
6  import org.springframework.retry.support.RetryTemplateBuilder;
7  
8  public class Example25 {
9      public static void main(String[] args) {
10         ApplicationContext context = new ClassPathXmlApplicationContext("Example25.xml");
11         Service4 service4 = (Service4)context.getBean("service4");
12         
13         RetryTemplateBuilder retryTemplateBuilder = RetryTemplate.builder();
14         retryTemplateBuilder.retryOn(NullPointerException.class);
15         retryTemplateBuilder.retryOn(IllegalArgumentException.class);
16         
17         RetryTemplate retryTemplate = retryTemplateBuilder.build();
18         
19         try {
20             retryTemplate.execute((retryContext) -> { service4.executeWithNullPointerException(); return null; });
21         } catch(NullPointerException excep) {
22             excep.printStackTrace();
23         }
24         
25         try {
26             retryTemplate.execute((retryContext) -> { service4.executeWithIllegalArgumentException(); return null; });
27         } catch(IllegalArgumentException excep) {
28             excep.printStackTrace();
29         }
30         
31         try {
32             retryTemplate.execute((retryContext) -> { service4.executeWithNoSuchElementException(); return null; });
33         } catch(NoSuchElementException excep) {
34             excep.printStackTrace();
35         }
36     }
37 }

In the above java code, at line 13, I will create an instance of RetryTemplateBuilder class by calling static method “builder” on the RetryTemplateBuilder class itself.

At line 14 and 15, I am telling RetryTemplateBuilder instance to retry failed operations only if the exception thrown is of type NullPointerException and IllegalArgumentException.

Then at line 17, we create an instance of RetryTemplate by calling “build” method on RetryTemplateBuilder instance.

In this way, we create an instance of RetryTemplate class which is configured to retry failed operations only if the exception thrown is of type NullPointerException and IllegalArgumentException

Below is the output

Output


[INFO] ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@6576fe71: startup date [Tue May 03 08:12:48 IST 2022]; root of context hierarchy
[INFO] XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [Example25.xml]
Executing 'executeWithNullPointerException' : 1
java.lang.NullPointerException
    at Service4.executeWithNullPointerException(Service4.java:11)
    at Example25.lambda$0(Example25.java:20)
    at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:329)
    at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:209)
    at Example25.main(Example25.java:20)
java.lang.IllegalArgumentException
    at Service4.executeWithIllegalArgumentException(Service4.java:17)
    at Example25.lambda$1(Example25.java:26)
    at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:329)
    at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:209)
    at Example25.main(Example25.java:26)
java.util.NoSuchElementException
    at Service4.executeWithNoSuchElementException(Service4.java:23)
    at Example25.lambda$2(Example25.java:32)
    at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:329)
    at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:209)
    at Example25.main(Example25.java:32)
Executing 'executeWithNullPointerException' : 2
Executing 'executeWithNullPointerException' : 3
Executing 'executeWithIllegalArgumentException' : 1
Executing 'executeWithIllegalArgumentException' : 2
Executing 'executeWithIllegalArgumentException' : 3
Executing 'executeWithNoSuchElementException' : 1

As you see from the output, the method that throws NullPointerException is retried 3 times before completely failing. Similarly the method that throws IllegalArgumentException is retried 3 times before completely failing. Whereas the method that throws NoSuchElementException is failed immediately after first try.

Note

Press like button if you like the post. Also share your opinion regarding posts through comments. Also mention what other framework you want me to cover through comments.

Leave a Reply