Fix CreateAopProxyInterceptor in the Spring core-patch indeed changes the implementation of the Spring AOP proxy#739
Conversation
…spring aop proxy implement
|
You missed the update of changes.md. Please fix it if all tests can pass. |
| private boolean onlyImplementsEnhancedInstanceAndSpringProxy(AdvisedSupport advisedSupport) { | ||
| Class<?>[] ifcs = advisedSupport.getProxiedInterfaces(); | ||
| Class targetClass = advisedSupport.getTargetClass(); | ||
| return ifcs.length == 2 && EnhancedInstance.class.isAssignableFrom(targetClass) && SpringProxy.class.isAssignableFrom(targetClass); |
There was a problem hiding this comment.
When is SpringProxy.class added into the hierarchy tree?
There was a problem hiding this comment.
Thank you for the review.
As shown below, the hasNoUserSuppliedProxyInterfaces method in DefaultAopProxyFactory is defined as follows:
spring4/spring5
/**
* Determine whether the supplied {@link AdvisedSupport} has only the
* {@link org.springframework.aop.SpringProxy} interface specified
* (or no proxy interfaces specified at all).
*/
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
Class<?>[] ifcs = config.getProxiedInterfaces();
return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
}
spring3
/**
* Determine whether the supplied {@link AdvisedSupport} has only the
* {@link org.springframework.aop.SpringProxy} interface specified
* (or no proxy interfaces specified at all).
*/
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
Class[] interfaces = config.getProxiedInterfaces();
return (interfaces.length == 0 || (interfaces.length == 1 && SpringProxy.class.equals(interfaces[0])));
}
There was a problem hiding this comment.
OK, this seems ok. Could you update the changelog? Then I could merge this PR.
There was a problem hiding this comment.
Thank you for the review.
The Changes.md file has been updated.
…spring aop proxy implement
| public void testInterceptClassImplementsEnhancedInstance() throws Throwable { | ||
| doReturn(MockClassImplementsEnhancedInstance.class).when(advisedSupport).getTargetClass(); | ||
| doReturn(MockClassImplementsEnhancedInstance.class.getInterfaces()).when(advisedSupport).getProxiedInterfaces(); | ||
| assertThat(true, is(interceptor.afterMethod(enhancedInstance, null, new Object[] {advisedSupport}, new Class[] {Object.class}, false))); |
There was a problem hiding this comment.
According to the answer in this SO thread, we basically should not expect classes that both use @Transactional annotation and being enhanced by SkyWalking Agent to use JDK Proxy.
We are facing startup failures after upgrading to SkyWalking 9.4.
Fix apache/skywalking#12858 The
CreateAopProxyInterceptorin the Spring core-patch indeed changes the implementation of the Spring AOP proxyThe current version of
CreateAopProxyInterceptordoes not account for scenarios where the proxy target class implementsUserSuppliedInterfaceand should work correctly with onlyJdkDynamicAopProxy. This can lead to inconsistencies in behavior when the SkyWalking agent is used.This PR fixes the issue by adding restrictions on when the behavior changes, ensuring that the proxy mechanism reverts to using
JdkDynamicAopProxywhen appropriate. Specifically, it ensures that the application's behavior remains consistent both with and without the SkyWalking agent enhancement.