Skip to content

Conversation

@tjuwangning
Copy link
Contributor

@tjuwangning tjuwangning commented Jul 10, 2025

Fix apache/skywalking#13221

  • Add a unit test to verify that the fix works.
  • Explain briefly why the bug exists and how to fix it.

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):

  • Enable Spring Retry by annotating a configuration with @EnableRetry and the method with @Retryable, the Spring Retry's annotations cause the bean class to implement the Retryable interface at runtime.
  • If SkyWalking has also instrumented the same class, Spring's startup will abort with an exception.
exception

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 added Retryable to 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 enhance evaluateProxyInterfaces() (and its related callbacks) so that SkyWalking's EnhancedInstance interface is always ignored.

@wu-sheng
Copy link
Member

I am on vacation, can't review this until 26th.
Please make CI passed and polish codes as much as you can.

@wu-sheng wu-sheng added enhancement New feature or request plugin labels Jul 10, 2025
@wu-sheng wu-sheng added this to the 9.5.0 milestone Jul 10, 2025
@wu-sheng wu-sheng requested a review from Copilot July 26, 2025 11:44
@wu-sheng
Copy link
Member

@lujiajing1126 Is this a case you are familiar with?

Copy link

Copilot AI left a 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 ProxyProcessorSupport and AbstractAutoProxyCreator classes
  • 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

@wu-sheng
Copy link
Member

Please update supported-list.d doc to add Spring retry support?
局部截取_20250727_103322

spanType: Local
peer: ''
skipAnalysis: false
- operationName: HEAD:/case/healthCheck
Copy link
Member

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()
Copy link
Member

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.

@lujiajing1126
Copy link
Contributor

lujiajing1126 commented Jul 28, 2025

@lujiajing1126 Is this a case you are familiar with?

@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.

@wu-sheng
Copy link
Member

Yes, please. I am a little confused about reviewing this test scenario.

@lujiajing1126
Copy link
Contributor

lujiajing1126 commented Jul 28, 2025

Please update supported-list.d doc to add Spring retry support? 局部截取_20250727_103322

Actually, the original issue can be reproduced in any case that an additional interface is added for the original class. In the spring-retry case, it is the marker interface Retryable

@wu-sheng
Copy link
Member

Actually, the original issue can be reproduced in any case that an additional interface is added for the original class. In the spring-retry case, it is the marker interface Retryable

Is this error caused by adding retry annotation, or retry actually happened?

@tjuwangning
Copy link
Contributor Author

Actually, the original issue can be reproduced in any case that an additional interface is added for the original class. In the spring-retry case, it is the marker interface Retryable

Is this error caused by adding retry annotation, or retry actually happened?

Spring cannot startup when add the retry annotation.
I hava revised the PR description to explain the issue more clearly. Furthermore, the current name of the test scenario is somewhat ambiguous, I will rename it later.

@wu-sheng
Copy link
Member

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}.
Copy link
Member

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?

Copy link
Contributor Author

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.

@wu-sheng
Copy link
Member

And please update changes.md

@@ -0,0 +1,9 @@
package test.apache.skywalking.apm.testcase.spring3.config;
Copy link
Member

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.

@wu-sheng wu-sheng merged commit c3a6fcb into apache:main Jul 29, 2025
198 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request plugin

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Use @Transcational annotation with enhanced instance causes Spring Application startup failure

3 participants