Spring 可重试注释 ClassNotFoundException
Spring Retryable annotation ClassNotFoundException
我想为 restTemplate
使用 @Retryable
注释。我添加了:
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.2.1.RELEASE</version>
</dependency>
以及 @EnableRetry
配置 class。我标记了方法:
restTemplate.exchange(url, HttpMethod.POST, request, String.class);
with(在新线程中)
@Retryable(maxAttempts=4,value=Exception.class,backoff=@Backoff(delay = 2000))
但是我收到来自 catalina 的错误消息:
27-Oct-2017 18:11:41.023 SEVERE [http-nio-8080-exec-1] org.apache.catalina.core.StandardContext.listenerStart Exception sending context initialized event to listener instance of class [org.springframework.web.context.ContextLoaderListener]
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.config.internalAutoProxyCreator': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/aspectj/lang/annotation/Around
at
<ommitted>
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/aspectj/lang/annotation/Around
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:154)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:89)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1103)
... 61 more
Caused by: java.lang.NoClassDefFoundError: org/aspectj/lang/annotation/Around
at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.<clinit>(ReflectiveAspectJAdvisorFactory.java:76)
at org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.<init>(AnnotationAwareAspectJAutoProxyCreator.java:53)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:142)
... 63 more
Caused by: java.lang.ClassNotFoundException: org.aspectj.lang.annotation.Around
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1285)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1119)
... 70 more
27-Oct-2017 18:11:41.038 INFO [http-nio-8080-exec-1] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext
我做错了什么?
已编辑:
我向前移动了一点。发现 Spring Retry makes use of AOP 所以我补充说:
<dependency>
<groupid>org.springframework</groupid>
<artifactid>spring-aop</artifactid>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.8</version>
</dependency>
现在我遇到了不同的错误:
27-Oct-2017 21:11:12.071 SEVERE [http-nio-8088-exec-5] org.springframework.web.servlet.DispatcherServlet.initServletBean Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'homeController' defined in file [(...)\HomeController.class]: Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: Could not initialize class org.springframework.aop.framework.ObjenesisCglibAopProxy
<ommitted>
Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.springframework.aop.framework.ObjenesisCglibAopProxy
at org.springframework.aop.framework.DefaultAopProxyFactory.createAopProxy(DefaultAopProxyFactory.java:60)
at org.springframework.aop.framework.ProxyCreatorSupport.createAopProxy(ProxyCreatorSupport.java:105)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:109)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:468)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:349)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:298)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:421)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1558)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
... 35 more
为了找出问题,我创建了一个小的 springMVC
项目,它是一样的。为了保持一切简单,只使用了很少的依赖项。这是 mvn dependency:tree
:
的输出
[INFO] com.example:store:war:0.0.1-SNAPSHOT
[INFO] +- org.springframework:spring-webmvc:jar:4.0.3.RELEASE:compile
[INFO] | +- org.springframework:spring-beans:jar:4.0.3.RELEASE:compile
[INFO] | +- org.springframework:spring-context:jar:4.0.3.RELEASE:compile
[INFO] | +- org.springframework:spring-core:jar:4.0.3.RELEASE:compile
[INFO] | | \- commons-logging:commons-logging:jar:1.1.3:compile
[INFO] | +- org.springframework:spring-expression:jar:4.0.3.RELEASE:compile
[INFO] | \- org.springframework:spring-web:jar:4.0.3.RELEASE:compile
[INFO] +- javax.servlet:jstl:jar:1.2:compile
[INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
[INFO] +- org.springframework.retry:spring-retry:jar:1.2.1.RELEASE:compile
[INFO] +- com.mashape.unirest:unirest-java:jar:1.4.9:compile
[INFO] | +- org.apache.httpcomponents:httpasyncclient:jar:4.1.1:compile
[INFO] | | +- org.apache.httpcomponents:httpcore:jar:4.4.4:compile
[INFO] | | \- org.apache.httpcomponents:httpcore-nio:jar:4.4.4:compile
[INFO] | +- org.apache.httpcomponents:httpmime:jar:4.5.2:compile
[INFO] | \- org.json:json:jar:20160212:compile
[INFO] +- org.springframework:spring-aop:jar:4.2.5.RELEASE:compile
[INFO] | \- aopalliance:aopalliance:jar:1.0:compile
[INFO] \- org.aspectj:aspectjweaver:jar:1.8.8:compile
我会回答我自己的问题,因为它现在似乎可以正常工作了。所有必需的依赖项:
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.11.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.10</version>
</dependency>
检查是否没有重复的依赖项(f.e。通过 mvn dependency:tree
,必要时使用 <exclusions>
)。确保你用 @EnableRetry
装饰你的配置 class。出于某种原因,您需要将调用者与方法本身分开。 F.e.this:
@Retryable(maxAttempts = 4, value = {ResourceAccessException.class}, backoff = @Backoff(delay = 5000))
public ResponseEntity<String> tryToSendAndReturnResponseByRestTemplate(final RestTemplate restTemplate,
final HttpEntity<MyObjDTO>
request) {
return restTemplate.exchange(resolveUrl(ENDPOINT_ADDRESS), HttpMethod.POST, request, String.class);
}
转到 SenderManager
class 标记为 f.e。 @Service
和不同的 class f.e。 PhoneDirector
class 你打电话给:
senderManager.tryToSendAndReturnResponseByRestTemplate(restTemplate, request);
应该可以。 (如果您需要指定如果在 4
(仅此处)尝试之后您仍然遇到异常,则应该返回什么,您可以创建另一个方法(在 SenderManager
class 中)标记使用 @Recover
,像这样:
@Recover
public ResponseEntity<String> recoverWhenSendingMessageFailed(final ResourceAccessException e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.REQUEST_TIMEOUT);
}
但是如果您需要来自 @Retryable
的参数(在 @Recover
方法中),请记住 arguments are populated from the argument list of the failed method in the same order as the failed method, and with the same return type
添加 spring-boot-starter-aop 依赖项 后对我有用,如下所示:
compile ("org.springframework.boot:spring-boot-starter-aop:1.5.10.RELEASE")
spring-retry 使用 spring aop,确保你的 pom 中添加了 aop 并尝试清理构建应用程序。
对于 spring 应用:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
用于 spring 引导:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
我想为 restTemplate
使用 @Retryable
注释。我添加了:
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.2.1.RELEASE</version>
</dependency>
以及 @EnableRetry
配置 class。我标记了方法:
restTemplate.exchange(url, HttpMethod.POST, request, String.class);
with(在新线程中)
@Retryable(maxAttempts=4,value=Exception.class,backoff=@Backoff(delay = 2000))
但是我收到来自 catalina 的错误消息:
27-Oct-2017 18:11:41.023 SEVERE [http-nio-8080-exec-1] org.apache.catalina.core.StandardContext.listenerStart Exception sending context initialized event to listener instance of class [org.springframework.web.context.ContextLoaderListener]
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.config.internalAutoProxyCreator': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/aspectj/lang/annotation/Around
at
<ommitted>
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/aspectj/lang/annotation/Around
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:154)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:89)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1103)
... 61 more
Caused by: java.lang.NoClassDefFoundError: org/aspectj/lang/annotation/Around
at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.<clinit>(ReflectiveAspectJAdvisorFactory.java:76)
at org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.<init>(AnnotationAwareAspectJAutoProxyCreator.java:53)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:142)
... 63 more
Caused by: java.lang.ClassNotFoundException: org.aspectj.lang.annotation.Around
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1285)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1119)
... 70 more
27-Oct-2017 18:11:41.038 INFO [http-nio-8080-exec-1] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext
我做错了什么?
已编辑: 我向前移动了一点。发现 Spring Retry makes use of AOP 所以我补充说:
<dependency>
<groupid>org.springframework</groupid>
<artifactid>spring-aop</artifactid>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.8</version>
</dependency>
现在我遇到了不同的错误:
27-Oct-2017 21:11:12.071 SEVERE [http-nio-8088-exec-5] org.springframework.web.servlet.DispatcherServlet.initServletBean Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'homeController' defined in file [(...)\HomeController.class]: Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: Could not initialize class org.springframework.aop.framework.ObjenesisCglibAopProxy
<ommitted>
Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.springframework.aop.framework.ObjenesisCglibAopProxy
at org.springframework.aop.framework.DefaultAopProxyFactory.createAopProxy(DefaultAopProxyFactory.java:60)
at org.springframework.aop.framework.ProxyCreatorSupport.createAopProxy(ProxyCreatorSupport.java:105)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:109)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:468)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:349)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:298)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:421)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1558)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
... 35 more
为了找出问题,我创建了一个小的 springMVC
项目,它是一样的。为了保持一切简单,只使用了很少的依赖项。这是 mvn dependency:tree
:
[INFO] com.example:store:war:0.0.1-SNAPSHOT
[INFO] +- org.springframework:spring-webmvc:jar:4.0.3.RELEASE:compile
[INFO] | +- org.springframework:spring-beans:jar:4.0.3.RELEASE:compile
[INFO] | +- org.springframework:spring-context:jar:4.0.3.RELEASE:compile
[INFO] | +- org.springframework:spring-core:jar:4.0.3.RELEASE:compile
[INFO] | | \- commons-logging:commons-logging:jar:1.1.3:compile
[INFO] | +- org.springframework:spring-expression:jar:4.0.3.RELEASE:compile
[INFO] | \- org.springframework:spring-web:jar:4.0.3.RELEASE:compile
[INFO] +- javax.servlet:jstl:jar:1.2:compile
[INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
[INFO] +- org.springframework.retry:spring-retry:jar:1.2.1.RELEASE:compile
[INFO] +- com.mashape.unirest:unirest-java:jar:1.4.9:compile
[INFO] | +- org.apache.httpcomponents:httpasyncclient:jar:4.1.1:compile
[INFO] | | +- org.apache.httpcomponents:httpcore:jar:4.4.4:compile
[INFO] | | \- org.apache.httpcomponents:httpcore-nio:jar:4.4.4:compile
[INFO] | +- org.apache.httpcomponents:httpmime:jar:4.5.2:compile
[INFO] | \- org.json:json:jar:20160212:compile
[INFO] +- org.springframework:spring-aop:jar:4.2.5.RELEASE:compile
[INFO] | \- aopalliance:aopalliance:jar:1.0:compile
[INFO] \- org.aspectj:aspectjweaver:jar:1.8.8:compile
我会回答我自己的问题,因为它现在似乎可以正常工作了。所有必需的依赖项:
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.11.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.10</version>
</dependency>
检查是否没有重复的依赖项(f.e。通过 mvn dependency:tree
,必要时使用 <exclusions>
)。确保你用 @EnableRetry
装饰你的配置 class。出于某种原因,您需要将调用者与方法本身分开。 F.e.this:
@Retryable(maxAttempts = 4, value = {ResourceAccessException.class}, backoff = @Backoff(delay = 5000))
public ResponseEntity<String> tryToSendAndReturnResponseByRestTemplate(final RestTemplate restTemplate,
final HttpEntity<MyObjDTO>
request) {
return restTemplate.exchange(resolveUrl(ENDPOINT_ADDRESS), HttpMethod.POST, request, String.class);
}
转到 SenderManager
class 标记为 f.e。 @Service
和不同的 class f.e。 PhoneDirector
class 你打电话给:
senderManager.tryToSendAndReturnResponseByRestTemplate(restTemplate, request);
应该可以。 (如果您需要指定如果在 4
(仅此处)尝试之后您仍然遇到异常,则应该返回什么,您可以创建另一个方法(在 SenderManager
class 中)标记使用 @Recover
,像这样:
@Recover
public ResponseEntity<String> recoverWhenSendingMessageFailed(final ResourceAccessException e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.REQUEST_TIMEOUT);
}
但是如果您需要来自 @Retryable
的参数(在 @Recover
方法中),请记住 arguments are populated from the argument list of the failed method in the same order as the failed method, and with the same return type
添加 spring-boot-starter-aop 依赖项 后对我有用,如下所示:
compile ("org.springframework.boot:spring-boot-starter-aop:1.5.10.RELEASE")
spring-retry 使用 spring aop,确保你的 pom 中添加了 aop 并尝试清理构建应用程序。
对于 spring 应用:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
用于 spring 引导:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>