From c1aeafbf5507aa67f2022a6d672baf7a7ef3b94b Mon Sep 17 00:00:00 2001 From: michaelin007 Date: Thu, 9 Apr 2026 19:04:46 +0100 Subject: [PATCH 1/4] https://jira.baeldung.com/browse/BAEL-9654 --- spring-scheduling/pom.xml | 23 ++++++++++++++++ .../baeldung/springretry/ExternalService.java | 22 +++++++++++++++ .../springretry/RetryEventListener.java | 27 +++++++++++++++++++ .../src/main/resources/RetryConfig.java | 9 +++++++ .../SpringRetryListenerIntegrationTest.java | 22 +++++++++++++++ .../src/test/resources/logback-test.xml | 12 ++++++++- 6 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 spring-scheduling/src/main/java/com/baeldung/springretry/ExternalService.java create mode 100644 spring-scheduling/src/main/java/com/baeldung/springretry/RetryEventListener.java create mode 100644 spring-scheduling/src/main/resources/RetryConfig.java create mode 100644 spring-scheduling/src/test/java/com/baeldung/springretry/SpringRetryListenerIntegrationTest.java diff --git a/spring-scheduling/pom.xml b/spring-scheduling/pom.xml index ece6a9aba7f2..e73c6118a06b 100644 --- a/spring-scheduling/pom.xml +++ b/spring-scheduling/pom.xml @@ -7,6 +7,18 @@ 0.1-SNAPSHOT jar spring-scheduling + + + + org.apache.maven.plugins + maven-compiler-plugin + + 21 + 21 + + + + com.baeldung @@ -56,10 +68,21 @@ junit-vintage-engine test + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + 2.0.12 + 4.0.2 diff --git a/spring-scheduling/src/main/java/com/baeldung/springretry/ExternalService.java b/spring-scheduling/src/main/java/com/baeldung/springretry/ExternalService.java new file mode 100644 index 000000000000..1f6a4f856fbc --- /dev/null +++ b/spring-scheduling/src/main/java/com/baeldung/springretry/ExternalService.java @@ -0,0 +1,22 @@ +package com.baeldung.springretry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.resilience.annotation.Retryable; +import org.springframework.stereotype.Service; + +@Service +public class ExternalService { + + private static final Logger LOG = LoggerFactory.getLogger(ExternalService.class); + + private int attempt = 0; + + @Retryable(maxRetries = 2, delay = 500) + public void callExternalApi() { + + attempt++; + LOG.info("Attempt " + attempt + " - Calling external API..."); + + throw new RuntimeException("Temporary connection failure!"); + } +} \ No newline at end of file diff --git a/spring-scheduling/src/main/java/com/baeldung/springretry/RetryEventListener.java b/spring-scheduling/src/main/java/com/baeldung/springretry/RetryEventListener.java new file mode 100644 index 000000000000..cf0da4b4a8b8 --- /dev/null +++ b/spring-scheduling/src/main/java/com/baeldung/springretry/RetryEventListener.java @@ -0,0 +1,27 @@ +package com.baeldung.springretry; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.event.EventListener; +import org.springframework.resilience.retry.MethodRetryEvent; +import org.springframework.stereotype.Component; + +@Component +public class RetryEventListener { + + private static final Logger log = LoggerFactory.getLogger(RetryEventListener.class); + + @EventListener + public void onRetryEvent(MethodRetryEvent event) { + String methodName = event.getMethod() + .getName(); + Throwable exception = event.getFailure(); + + if (event.isRetryAborted()) { + log.error("Retries exhausted for method '{}' after {} attempts. Final exception: {}", methodName, exception.getMessage()); + + } else { + log.warn("Retry failed for method '{}'. Exception: {}", methodName, exception.getMessage()); + } + } +} diff --git a/spring-scheduling/src/main/resources/RetryConfig.java b/spring-scheduling/src/main/resources/RetryConfig.java new file mode 100644 index 000000000000..2717ea5c2e25 --- /dev/null +++ b/spring-scheduling/src/main/resources/RetryConfig.java @@ -0,0 +1,9 @@ +package com.baeldung; + +import org.springframework.context.annotation.Configuration; +import org.springframework.retry.annotation.EnableRetry; + +@Configuration +@EnableRetry +public class RetryConfig { +} diff --git a/spring-scheduling/src/test/java/com/baeldung/springretry/SpringRetryListenerIntegrationTest.java b/spring-scheduling/src/test/java/com/baeldung/springretry/SpringRetryListenerIntegrationTest.java new file mode 100644 index 000000000000..c5f495e33548 --- /dev/null +++ b/spring-scheduling/src/test/java/com/baeldung/springretry/SpringRetryListenerIntegrationTest.java @@ -0,0 +1,22 @@ +package com.baeldung.springretry; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +public class SpringRetryListenerIntegrationTest { + + @Autowired + private ExternalService externalService; + + @Test + void givenFailingExternalService_whenCallExternalApi_thenShouldRetryMultipleTimesAndLogRetriesExhausted() { + assertThrows(RuntimeException.class, () -> { + externalService.callExternalApi(); + }); + } + +} diff --git a/spring-scheduling/src/test/resources/logback-test.xml b/spring-scheduling/src/test/resources/logback-test.xml index af8c372d9651..80306d0c64b5 100644 --- a/spring-scheduling/src/test/resources/logback-test.xml +++ b/spring-scheduling/src/test/resources/logback-test.xml @@ -1,6 +1,16 @@ + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + - + + + + + + \ No newline at end of file From 06b09cbf652c03123b753a4dde2c9d50da1c26df Mon Sep 17 00:00:00 2001 From: michaelin007 Date: Thu, 9 Apr 2026 19:05:18 +0100 Subject: [PATCH 2/4] https://jira.baeldung.com/browse/BAEL-9654 --- spring-scheduling/src/main/resources/RetryConfig.java | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 spring-scheduling/src/main/resources/RetryConfig.java diff --git a/spring-scheduling/src/main/resources/RetryConfig.java b/spring-scheduling/src/main/resources/RetryConfig.java deleted file mode 100644 index 2717ea5c2e25..000000000000 --- a/spring-scheduling/src/main/resources/RetryConfig.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.baeldung; - -import org.springframework.context.annotation.Configuration; -import org.springframework.retry.annotation.EnableRetry; - -@Configuration -@EnableRetry -public class RetryConfig { -} From 98940471dfd5968058a380cde2955f0ce3a709ad Mon Sep 17 00:00:00 2001 From: michaelin007 Date: Wed, 22 Apr 2026 04:23:04 +0100 Subject: [PATCH 3/4] https://jira.baeldung.com/browse/BAEL-9654 --- .../src/main/java/com/baeldung/springretry/ExternalService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-scheduling/src/main/java/com/baeldung/springretry/ExternalService.java b/spring-scheduling/src/main/java/com/baeldung/springretry/ExternalService.java index 1f6a4f856fbc..91b9de38e218 100644 --- a/spring-scheduling/src/main/java/com/baeldung/springretry/ExternalService.java +++ b/spring-scheduling/src/main/java/com/baeldung/springretry/ExternalService.java @@ -1,4 +1,5 @@ package com.baeldung.springretry; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.resilience.annotation.Retryable; From 5e48692fd6d1dafa430c59405870bd7ac796e8d5 Mon Sep 17 00:00:00 2001 From: michaelin007 Date: Sat, 25 Apr 2026 22:04:40 +0100 Subject: [PATCH 4/4] https://jira.baeldung.com/browse/BAEL-9654 --- .../src/main/java/com/baeldung/springretry/ExternalService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-scheduling/src/main/java/com/baeldung/springretry/ExternalService.java b/spring-scheduling/src/main/java/com/baeldung/springretry/ExternalService.java index 91b9de38e218..8b493afc8429 100644 --- a/spring-scheduling/src/main/java/com/baeldung/springretry/ExternalService.java +++ b/spring-scheduling/src/main/java/com/baeldung/springretry/ExternalService.java @@ -16,7 +16,7 @@ public class ExternalService { public void callExternalApi() { attempt++; - LOG.info("Attempt " + attempt + " - Calling external API..."); + LOG.info("Attempt {} - Calling external API...", attempt); throw new RuntimeException("Temporary connection failure!"); }