Skip to content
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

@annotation pointcut is not matched with complex hierarchy and generics against classes compiled by Eclipse [SPR-17310] #21843

Closed
spring-projects-issues opened this issue Sep 28, 2018 · 8 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

Yanming Zhou opened SPR-17310 and commented

Persistable   <-  BaseUser   <-  User
BaseManager<T extends Persistable>   <-  BaseUserManager<T extends BaseUser>  <-     UserManager<User> 
 
BaseManagerImpl<T extends Persistable>  <-  BaseUserManagerImpl<T extends BaseUser>  <-     UserManagerImpl<User>

The mostSpecificMethod should return method UserManagerImpl.save(User), but return BaseUserManagerImpl.save(BaseUser) which doesn't annotated, it will cause @annotation pointcut broken.


Affects: 5.1 GA

Attachments:

@spring-projects-issues
Copy link
Collaborator Author

Yanming Zhou commented

It seems eclipse compiler bug. I'm not sure it has relation with https://bugs.eclipse.org/bugs/show_bug.cgi?id=495396

@spring-projects-issues
Copy link
Collaborator Author

Yanming Zhou commented

I have reported https://bugs.eclipse.org/bugs/show_bug.cgi?id=539651

@spring-projects-issues
Copy link
Collaborator Author

Yanming Zhou commented

Finally I figure it out, method.getDeclaringClass() return wrong class with eclipse compiler, it cause spring ClassUtils.getMostSpecificMethod() return wrong method.

@Test
public void test() throws Exception {
	Class<?> targetClass = UserManagerImpl.class;
	Method method = targetClass.getMethod("save", Persistable.class);
	assertEquals(targetClass, method.getDeclaringClass()); // eclipse compiler fail
}

@spring-projects-issues
Copy link
Collaborator Author

Yanming Zhou commented

javac create two bridge methods:

public void com.example.UserManagerImpl.save(com.example.Persistable)
public void com.example.UserManagerImpl.save(com.example.BaseUser)

ecj create only one bridge method:

public void com.example.UserManagerImpl.save(com.example.BaseUser)

It seems a corner case that JLS not covered, maybe it's not a bug of eclipse compiler, Juergen Hoeller could you make some changes to keep compatibility with both of them?

@spring-projects-issues
Copy link
Collaborator Author

Yanming Zhou commented

Workaround:

add two lines before return statement

resolvedMethod = BridgeMethodResolver.findBridgedMethod(resolvedMethod);
resolvedMethod = ClassUtils.getMostSpecificMethod(resolvedMethod, specificTargetClass);

https://github.com/spring-projects/spring-framework/blob/master/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java#L198

@spring-projects-issues spring-projects-issues added type: bug A general bug status: waiting-for-triage An issue we've not yet triaged or decided on in: core Issues in core modules (aop, beans, core, context, expression) and removed type: bug A general bug labels Jan 11, 2019
@quaff
Copy link
Contributor

quaff commented Mar 1, 2019

Minimized unit test, It will fail in eclipse.

import static org.junit.Assert.assertEquals;

import java.lang.reflect.Method;

import org.junit.Test;
import org.springframework.aop.support.AopUtils;

public class AopUtilsTest {

	@Test
	public void testGetMostSpecificMethod() throws Exception {
		String methodName = "feed";
		Class<?> targetClass = DogService.class;
		Method targetMethod = targetClass.getDeclaredMethod(methodName, Dog.class);
		Method originalMethod = AnimalService.class.getDeclaredMethod(methodName, Animal.class);
		Method actualMethod = AopUtils.getMostSpecificMethod(originalMethod, targetClass);
		assertEquals("Please ensure class compiled with javac not eclipse", targetMethod, actualMethod);
	}

	public static class Animal {

	}

	public static abstract class Mammal extends Animal {

	}

	public static class Dog extends Mammal {

	}

	public static class AnimalService<T extends Animal> {
		public void feed(T obj) {
		}
	}

	public static class MammalService<T extends Mammal> extends AnimalService<T> {
		@Override
		public void feed(T obj) {
		}
	}

	public static class DogService extends MammalService<Dog> {
		@Override
		public void feed(Dog obj) {
		}
	}

}

@snicoll
Copy link
Member

snicoll commented Sep 20, 2023

Courtesy of @wilkinsona, the test is still failing with the latest Spring Framework 6.1 milestone.

@jhoeller wondering if we could accommodate with this difference between the eclipse and Java compiler?

@snicoll snicoll self-assigned this Sep 20, 2023
@snicoll snicoll removed their assignment Jan 5, 2024
@jhoeller jhoeller added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jan 7, 2024
@jhoeller jhoeller self-assigned this Jan 7, 2024
@jhoeller jhoeller added this to the 6.1.3 milestone Jan 7, 2024
@jhoeller jhoeller changed the title @annotation pointcut is not matched with complex hierarchy and generics [SPR-17310] @annotation pointcut is not matched with complex hierarchy and generics against classes compiled by Eclipse [SPR-17310] Jan 7, 2024
@jhoeller
Copy link
Contributor

jhoeller commented Jan 7, 2024

I've addressed this through a new combined BridgeMethodResolver.getMostSpecificMethod(Method, Class) delegate which does ClassUtils.getMostSpecificMethod and then resolves the bridge method against the same target class, being able to find a matching signature even if no bridge method has been generated at the same class hierarchy level (as with the Eclipse compiler).

@sbrannen sbrannen changed the title @annotation pointcut is not matched with complex hierarchy and generics against classes compiled by Eclipse [SPR-17310] @annotation pointcut is not matched with complex hierarchy and generics against classes compiled by Eclipse [SPR-17310] Jan 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

4 participants