-
Notifications
You must be signed in to change notification settings - Fork 668
Fix enhanced instance causes Spring Application startup failure #762
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
I am on vacation, can't review this until 26th. |
|
@lujiajing1126 Is this a case you are familiar with? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR fixes a Spring Application startup failure caused by enhanced instances in the SkyWalking agent. The fix introduces interceptors to handle enhanced instances during Spring's proxy creation process, preventing startup failures when beans have been enhanced by the agent.
Key changes:
- Adds interceptors for Spring's
ProxyProcessorSupportandAbstractAutoProxyCreatorclasses - Creates a test scenario for Spring Retry functionality to validate the fix
- Updates the CI configuration to include the new test scenario
Reviewed Changes
Copilot reviewed 16 out of 17 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
apm-sniffer/apm-sdk-plugin/spring-plugins/core-patch/src/main/resources/skywalking-plugin.def |
Registers two new interceptors for Spring proxy creation |
apm-sniffer/apm-sdk-plugin/spring-plugins/core-patch/src/main/java/org/apache/skywalking/apm/plugin/spring/patch/define/ProxyProcessorSupportInstrumentation.java |
Instrumentation for ProxyProcessorSupport class |
apm-sniffer/apm-sdk-plugin/spring-plugins/core-patch/src/main/java/org/apache/skywalking/apm/plugin/spring/patch/define/AutoProxyCreatorInstrumentation.java |
Instrumentation for AbstractAutoProxyCreator class |
apm-sniffer/apm-sdk-plugin/spring-plugins/core-patch/src/main/java/org/apache/skywalking/apm/plugin/spring/patch/ProxyProcessorSupportInterceptor.java |
Interceptor to handle EnhancedInstance in proxy processing |
apm-sniffer/apm-sdk-plugin/spring-plugins/core-patch/src/main/java/org/apache/skywalking/apm/plugin/spring/patch/AutoProxyCreatorInterceptor.java |
Interceptor to handle EnhancedInstance in auto proxy creation |
test/plugin/scenarios/spring-retry-scenario/ |
Complete test scenario to validate the fix with Spring Retry |
.github/workflows/plugins-test.2.yaml |
Updates CI to include the new test scenario |
...ain/java/org/apache/skywalking/apm/plugin/spring/patch/ProxyProcessorSupportInterceptor.java
Show resolved
Hide resolved
...src/main/java/org/apache/skywalking/apm/plugin/spring/patch/AutoProxyCreatorInterceptor.java
Show resolved
Hide resolved
...try-scenario/src/main/java/test/apache/skywalking/apm/testcase/spring/retry/Application.java
Show resolved
Hide resolved
| spanType: Local | ||
| peer: '' | ||
| skipAnalysis: false | ||
| - operationName: HEAD:/case/healthCheck |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not required from the expectation file.
| segments: | ||
| - segmentId: not null | ||
| spans: | ||
| - operationName: test.apache.skywalking.apm.testcase.spring.retry.service.CaseService.handle() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no client span and I can't see the retry working in the expectation file.
I think you should enhance your test scenario.
@tjuwangning Ning Wang also works in our team. We've already discussed this patch offline. I suppose he has to add some more detailed technical comments for this PR and explain better how the test case works. |
|
Yes, please. I am a little confused about reviewing this test scenario. |
Actually, the original issue can be reproduced in any case that an additional interface is added for the original class. In the |
Is this error caused by adding retry annotation, or retry actually happened? |
Spring cannot startup when add the retry annotation. |
|
Then, I think you just need to add this retry annotation to existing scenario. |
| import java.lang.reflect.Method; | ||
|
|
||
| /** | ||
| * <code>AutoProxyCreatorInterceptor</code> check that the bean has been implement {@link EnhancedInstance}. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am clear about your new description, but a little confused about this comment word.
I think the original method is returning true/false, and we are just checking EnhancedInstance implementation when the original return is false.
When the original return is false? We should write this comment according to #isConfigurationCallbackInterface purpose, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I have updated it.
|
And please update changes.md |
| @@ -0,0 +1,9 @@ | |||
| package test.apache.skywalking.apm.testcase.spring3.config; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You missed the APLv2 header.


Fix apache/skywalking#13221
After Spring Framework 4.0.2.RELEASE, if we use a Spring Advisor to add an interface to a class and that same class is also enhanced by SkyWalking, Spring will fail to start.
Reproduce (using spring-retry as an example):
@EnableRetryand the method with@Retryable, the Spring Retry's annotations cause the bean class to implement theRetryableinterface at runtime.Root cause:
SkyWalking's enhancement changes how Spring decides which proxy type to use. As mentioned in #13221, SkyWalking modifies Spring's
hasNoUserSuppliedProxyInterfaces()to avoid affecting the choice of proxy type. But once Spring Retry has addedRetryableto the list of interfaces,hasNoUserSuppliedProxyInterfaces()will find a user-supplied interface and return false, which changes the proxy type and leads to a startup failure.Starting in 4.0.2.RELEASE, Spring adds a new hook method
evaluateProxyInterfaces(), which allows proxy-related flags (like proxyTargetClass) to be determined earlier in the lifecycle. We also need to enhanceevaluateProxyInterfaces()(and its related callbacks) so that SkyWalking's EnhancedInstance interface is always ignored.CHANGESlog.