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

AspectJ annotation pointcuts fail to evaluate against interface-based proxies [SPR-16803] #21343

Closed
spring-issuemaster opened this Issue May 9, 2018 · 2 comments

Comments

Projects
None yet
2 participants
@spring-issuemaster
Copy link
Collaborator

spring-issuemaster commented May 9, 2018

Yanming Zhou opened SPR-16803 and commented

If target object is JDK dynamic proxy, Aspectj annotation pointcut match failed since proxy class method lost annotations, here is a simple test

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;

import java.lang.reflect.Method;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.junit.Test;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.transaction.annotation.Transactional;

public class AopUtilsTest {

	@Test
	public void getMostSpecificMethod() throws Exception {
		MyInterface proxy = (MyInterface) new ProxyFactory(MyInterface.class, new MyMethodInterceptor())
				.getProxy(MyInterface.class.getClassLoader());
		Method interfaceMethod = MyInterface.class.getMethod("test");
		Method proxyMethod = proxy.getClass().getMethod("test");
		Method mostSpecificMethod = AopUtils.getMostSpecificMethod(interfaceMethod, proxy.getClass());
		assertNotEquals(proxyMethod, interfaceMethod);
		assertEquals(interfaceMethod, mostSpecificMethod); //failed
		assertNotNull(mostSpecificMethod.getAnnotation(Transactional.class));
	}

	public static interface MyInterface {

		@Transactional
		public String test();

	}

	public static class MyMethodInterceptor implements MethodInterceptor {

		@Override
		public Object invoke(MethodInvocation mi) throws Throwable {
			return null;
		}

	}

}

We should add a short-circuit

if(Proxy.isProxyClass(targetClass))
     return method;

I'm not sure this change should apply for AopUtils.getMostSpecificMethod() or ClassUtils.getMostSpecificMethod()


Affects: 5.0.6

Attachments:

Issue Links:

  • #21264 AspectJ execution pointcut does not detect methods in superinterface anymore
  • #21298 AopUtils.getMostSpecificMethod should expose dynamic proxy class methods
  • #21218 Mixed use BeanNameAutoProxyCreator and AnnotationAwareAspectJAutoProxyCreator to proxy same bean
  • #21541 Spring 5.x DataSource proxying does not work with Oracle UCP on JDK 9+

Referenced from: commits bba5dca, 416dee7

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator

spring-issuemaster commented May 9, 2018

Juergen Hoeller commented

#21298 intentionally restored our original behavior of returning proxy class methods from AopUtils.getMostSpecificMethod, as it was pre 5.0.5. If you're seeing a regression with AspectJ pointcuts there, let's rather try to address this at the AspectJ evaluation level. Could you provide a test case for a corresponding AspectJ pointcut? Did your scenario work against 5.0.4 before or just against 5.0.5, i.e. is this actually a regression against 5.0.4 or just against a 5.0.5 side effect?

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator

spring-issuemaster commented May 10, 2018

Yanming Zhou commented

I upload a maven project, It works since 5.0.5, but soon failed with 5.0.6, It's a regression affected by 8b051ab#diff-41acc8f24cd73cb3d6eb62635bfb2938L195

&& !Proxy.isProxyClass(targetClass)
``` is removed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment