Skip to content

AopUtils.getMostSpecificMethod does not return original method for proxy-derived method anymore #32365

Closed
@chrismanning-elementsuite

Description

Affects: 5.3.30, 5.3.31, 5.3.32


Since 5.3.30 AopUtils.getMostSpecificMethod is no longer giving the correct result in our code. The problem was introduced in recent changes to ClassUtils.getMostSpecificMethod in the check to determine if the method is overridable and to only continue the search if it is - if it is not overridable then it is assumed that it is already the most specific method and returns it. However, this is not the correct logic in some cases.

In our case the method passed in comes from a runtime-generated Proxy and we use this util to get the original method (with generic params intact). This generated method appears to have a final modifier - thus is not considered overridable by the new code. I don't think this is the correct logic as the original method is in fact overridable - it has been overriden by the generated method. Previously, the final modifier was not considered so the logic was effectively "this method could not have been overriden". Now, the logic is "this method cannot be overriden further".

Minimal test case (passes on 5.3.29, fails on 5.3.30+):

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

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

public class AopTest {

   interface I {
      void f(List<String> a);
   }
   static class C implements I {
      public void f(List<String> a) {
      }
   }

   @Test
   public void aopMostSpecificMethod() throws Exception {
      final C c = new C();
      final ProxyFactory proxyFactory = new ProxyFactory(c);
      final I proxy = (I) proxyFactory.getProxy();
      final Type paramType = AopUtils.getMostSpecificMethod(
            proxy.getClass().getMethod("f", List.class),
            AopUtils.getTargetClass(proxy)).getParameters()[0].getParameterizedType();
      assertTrue(paramType instanceof ParameterizedType);
      assertEquals(String.class, ((ParameterizedType) paramType).getActualTypeArguments()[0]);
   }

}

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)status: backportedAn issue that has been backported to maintenance branchestype: regressionA bug that is also a regression

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions