Application fails to start in Kubernetes when using target-class based (CGLIB) proxies (e.g., with EnableAsync)
See original GitHub issueDescribe the bug Hi there,
I’m currently using Spring Cloud Kubernetes, but run into an application startup issue after attempting to use an asynchronous method. A sample Maven project to help reproduce the issue can be found in this repo : rm3l/sck-issue-with-target-class-proxies
The error message (stack trace below) explicitly tells me to Either pull the async method up to an interface or switch to CGLIB proxies by enforcing proxy-target-class mode
.
I don’t understand why, since the use of CGLIB proxies is already being enforced application-wide (via the .spring.aop.proxy-target-class
Spring Boot property and the proxyTargetClass=true
attribute of the EnableAsync
annotation)
I am not sure though if this is an issue related to Spring Cloud Kubernetes itself, or if it relates to Spring Boot instead.
Maybe I missed something, but the application starts and works like a charm when started outside of Kubernetes or when I explicitly set spring.cloud.kubernetes.enabled=false
, which makes me suspect an issue with Spring Cloud Kubernetes.
Is there anything in Spring Cloud Kubernetes forcing the use of standard Java interface-based proxies, irrespective of how the application is configured ?
Below is an excerpt from the error log:
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-05-02 20:38:53.179 ERROR 1 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanInitializationException: Failed to process @EventListener annotation on bean with name 'testServiceImpl'; nested exception is java.lang.IllegalStateException: Need to invoke method 'handleEvent' declared on target class 'TestServiceImpl', but not found in any interface(s) of the exposed proxy type. Either pull the method up to an interface or switch to CGLIB proxies by enforcing proxy-target-class mode in your configuration.
at org.springframework.context.event.EventListenerMethodProcessor.afterSingletonsInstantiated(EventListenerMethodProcessor.java:157) ~[spring-context-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:963) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.6.jar:5.3.6]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.6.jar:5.3.6]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.5.jar:2.4.5]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:782) ~[spring-boot-2.4.5.jar:2.4.5]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:774) ~[spring-boot-2.4.5.jar:2.4.5]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-2.4.5.jar:2.4.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:339) ~[spring-boot-2.4.5.jar:2.4.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1340) ~[spring-boot-2.4.5.jar:2.4.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1329) ~[spring-boot-2.4.5.jar:2.4.5]
at org.rm3l.springcloudkubernetesissuewithtargetclassproxies.SpringCloudKubernetesIssueWithTargetClassProxiesApplication.main(SpringCloudKubernetesIssueWithTargetClassProxiesApplication.java:12) ~[classes/:na]
Caused by: java.lang.IllegalStateException: Need to invoke method 'handleEvent' declared on target class 'TestServiceImpl', but not found in any interface(s) of the exposed proxy type. Either pull the method up to an interface or switch to CGLIB proxies by enforcing proxy-target-class mode in your configuration.
at org.springframework.core.MethodIntrospector.selectInvocableMethod(MethodIntrospector.java:132) ~[spring-core-5.3.6.jar:5.3.6]
at org.springframework.aop.support.AopUtils.selectInvocableMethod(AopUtils.java:135) ~[spring-aop-5.3.6.jar:5.3.6]
at org.springframework.context.event.EventListenerMethodProcessor.processBean(EventListenerMethodProcessor.java:198) ~[spring-context-5.3.6.jar:5.3.6]
at org.springframework.context.event.EventListenerMethodProcessor.afterSingletonsInstantiated(EventListenerMethodProcessor.java:154) ~[spring-context-5.3.6.jar:5.3.6]
... 11 common frames omitted
For reference, I am using the following versions:
- Spring Boot : 2.4.5
- Spring Cloud Kubernetes : 2.0.2
Sample I’ve created this sample Maven project to help reproduce the issue: https://github.com/rm3l/sck-issue-with-target-class-proxies
This repo contains a simple Helm Chart for deploying to Kubernetes. It also contains a GitHub Workflow that tests this Chart. This job currently does not pass due to this issue. Please do let me know if there is anything missing or if I can help further investigate. Thanks.
Issue Analytics
- State:
- Created 2 years ago
- Comments:10 (5 by maintainers)
After speaking with the team today, we think the right approach is to create our own scheduler in the autoconfiguration and remove the
@EnableAsync
annotation altogether so we can avoid any collisions with apps.Yeah the dependencies changed in main.
If you change the Boot version to 2.3.10.RELEASE, the spring cloud version to Hoxton.BUILD-SNAPSHOT and switch the dependency to
spring-cloud-starter-kubernetes-config
in your sample you should be able to test the changes (which would be greatly appreciated!).