Total Pageviews
2019/03/31
2019/03/30
2019/03/15
[Spring boot] A simple spring-retry example
Scenario
How-To
Add spring-retry in your pom.xml
Create email service
Create email resource class
Enable spring retry function
Do test and check result
How-To
Add spring-retry in your pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>test</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>test</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Create email service
package com.example.service; import com.example.rest.EmailResource; import lombok.extern.slf4j.Slf4j; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Recover; import org.springframework.retry.annotation.Retryable; import org.springframework.stereotype.Service; @Slf4j @Service public class EmailService { private int counter = 0; /** * 最多 retry 5 次,每次 retry 間隔 5 秒鐘 * * @param param */ @Retryable(maxAttempts = 5, backoff = @Backoff(delay = 5000)) public void sendMailWithRetry(EmailResource.EmailParam param) { counter++; log.debug("Failed to send mail. Retried " + counter + " times"); throw new IllegalArgumentException("some error happened"); } /** * 當 retry 5 次全部失敗,則到 recover method,印出錯誤訊息 * * @param throwable * @param param */ @Recover public void recover(Throwable throwable, EmailResource.EmailParam param) { String errorMsg = "fail to retry 5 times, param = %s, error message : %s"; throw new IllegalArgumentException(String.format(errorMsg, param, throwable.getMessage())); } }
Create email resource class
package com.example.rest; import com.example.service.EmailService; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @Slf4j @RestController @RequestMapping(value = "/email") public class EmailResource { @Autowired private EmailService emailService; @PostMapping(value = "/send") public void sendMail(@RequestBody EmailParam param) { emailService.sendMailWithRetry(param); } @Data public static class EmailParam { private String to; private String subject; private String content; } }
Enable spring retry function
package com.example.test; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; import org.springframework.retry.annotation.EnableRetry; // add @EnableRetry annotation to enable spring retry function @EnableRetry @SpringBootApplication @ComponentScan(basePackages = "com.example") public class TestApplication { public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); } }
Do test and check result
2018-11-28 09:55:32.135 DEBUG 9804 --- [nio-8080-exec-1] com.example.service.EmailService : Failed to send mail. Retried 1 times 2018-11-28 09:55:37.136 DEBUG 9804 --- [nio-8080-exec-1] com.example.service.EmailService : Failed to send mail. Retried 2 times 2018-11-28 09:55:42.138 DEBUG 9804 --- [nio-8080-exec-1] com.example.service.EmailService : Failed to send mail. Retried 3 times 2018-11-28 09:55:47.138 DEBUG 9804 --- [nio-8080-exec-1] com.example.service.EmailService : Failed to send mail. Retried 4 times 2018-11-28 09:55:52.139 DEBUG 9804 --- [nio-8080-exec-1] com.example.service.EmailService : Failed to send mail. Retried 5 times 2018-11-28 09:55:52.215 ERROR 9804 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: fail to retry 5 times, param = EmailResource.EmailParam(to=junyuo@gmail.com, subject=email subject, content=email content), error message : some error happened] with root cause java.lang.IllegalArgumentException: fail to retry 5 times, param = EmailResource.EmailParam(to=junyuo@gmail.com, subject=email subject, content=email content), error message : some error happened at com.example.service.EmailService.recover(EmailService.java:37) ~[classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_151] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_151] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_151]
Labels:
Spring
2019/03/14
[Spring Boot] java.lang.NoClassDefFoundError: org/aspectj/lang/annotation/Pointcut
Problem
When I add @EnableRetry annotation:
Then startup my spring boot project, I got the following exception
How-To
Lacking of spring-boot-starter-aop dependency in pom.xml is root cause. So you need to edit pom.xml as bellows:
When I add @EnableRetry annotation:
package com.example.test; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; import org.springframework.retry.annotation.EnableRetry; @EnableRetry @SpringBootApplication @ComponentScan(basePackages = "com.example") public class TestApplication { public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); } }
Then startup my spring boot project, I got the following exception
Caused by: java.lang.NoClassDefFoundError: org/aspectj/lang/annotation/Pointcut at org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory.<clinit>(AbstractAspectJAdvisorFactory.java:62) ~[spring-aop-5.1.2.RELEASE.jar:5.1.2.RELEASE] at org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.initBeanFactory(AnnotationAwareAspectJAutoProxyCreator.java:82) ~[spring-aop-5.1.2.RELEASE.jar:5.1.2.RELEASE] at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.setBeanFactory(AbstractAdvisorAutoProxyCreator.java:63) ~[spring-aop-5.1.2.RELEASE.jar:5.1.2.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1767) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1732) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:576) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE] ... 15 common frames omitted Caused by: java.lang.ClassNotFoundException: org.aspectj.lang.annotation.Pointcut at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_151] at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_151] at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335) ~[na:1.8.0_151] at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_151] ... 21 common frames omitted
How-To
Lacking of spring-boot-starter-aop dependency in pom.xml is root cause. So you need to edit pom.xml as bellows:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>test</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>test</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Labels:
Spring
2019/03/13
[Spring boot] org.yaml.snakeyaml.scanner.ScannerException: mapping values are not allowed here
Problem
When I tried to startup my spring boot project, I got this exception:
Here had part of application.yml
How-To
I should add double quote to C: in head and tail. application.yml should modify as bellows:
When I tried to startup my spring boot project, I got this exception:
Caused by: org.yaml.snakeyaml.scanner.ScannerException: mapping values are not allowed here in 'reader', line 16, column 17: diskdrive: C: ^ at org.yaml.snakeyaml.scanner.ScannerImpl.fetchValue(ScannerImpl.java:872) at org.yaml.snakeyaml.scanner.ScannerImpl.fetchMoreTokens(ScannerImpl.java:360) at org.yaml.snakeyaml.scanner.ScannerImpl.checkToken(ScannerImpl.java:226) at org.yaml.snakeyaml.parser.ParserImpl$ParseBlockMappingKey.produce(ParserImpl.java:557) at org.yaml.snakeyaml.parser.ParserImpl.peekEvent(ParserImpl.java:157) at org.yaml.snakeyaml.parser.ParserImpl.checkEvent(ParserImpl.java:147) at org.yaml.snakeyaml.composer.Composer.composeMappingNode(Composer.java:227) at org.yaml.snakeyaml.composer.Composer.composeNode(Composer.java:154) at org.yaml.snakeyaml.composer.Composer.composeValueNode(Composer.java:249) at org.yaml.snakeyaml.composer.Composer.composeMappingChildren(Composer.java:240) at org.yaml.snakeyaml.composer.Composer.composeMappingNode(Composer.java:228) at org.yaml.snakeyaml.composer.Composer.composeNode(Composer.java:154) at org.yaml.snakeyaml.composer.Composer.composeValueNode(Composer.java:249) at org.yaml.snakeyaml.composer.Composer.composeMappingChildren(Composer.java:240) at org.yaml.snakeyaml.composer.Composer.composeMappingNode(Composer.java:228) at org.yaml.snakeyaml.composer.Composer.composeNode(Composer.java:154) at org.yaml.snakeyaml.composer.Composer.composeDocument(Composer.java:122) at org.yaml.snakeyaml.composer.Composer.getNode(Composer.java:84) at org.yaml.snakeyaml.constructor.BaseConstructor.getData(BaseConstructor.java:123) at org.yaml.snakeyaml.Yaml$1.next(Yaml.java:547)
Here had part of application.yml
opendata: file: diskdrive: C: subdirectory: opendata
How-To
I should add double quote to C: in head and tail. application.yml should modify as bellows:
opendata: file: diskdrive: "C:" subdirectory: opendata
Labels:
Spring
Subscribe to:
Posts (Atom)