Pavlo Shevchenko created LANG-1694:
--------------------------------------

             Summary: `MethodUtils.getMatchingMethod` fails with "Found 
multiple candidates" when the method is abstract
                 Key: LANG-1694
                 URL: https://issues.apache.org/jira/browse/LANG-1694
             Project: Commons Lang
          Issue Type: Bug
          Components: lang.reflect.*
    Affects Versions: 3.12.0
            Reporter: Pavlo Shevchenko


*Summary*

MethodUtils.getMatchingMethod() fails with "Found multiple candidates for 
method" message if the method is an override of an abstract method and 
parameter types do not exactly match the declared types.

*Reproducer*

 
{code:java}
public class App {

    static abstract class Base {
        abstract void handle(Exception e);
    }

    static class BaseImpl extends Base {
        @Override
        void handle(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        MethodUtils.getMatchingMethod(BaseImpl.class, "handle", 
RuntimeException.class);
    }
} {code}
 

When the the program is executed, you would observe the following exception:

 
{code:java}
Exception in thread "main" java.lang.IllegalStateException: Found multiple 
candidates for method handle(class java.lang.RuntimeException) on class 
dev.pshevche.App$BaseImpl : [void 
dev.pshevche.App$BaseImpl.handle(java.lang.Exception),abstract void 
dev.pshevche.App$Base.handle(java.lang.Exception)]
    at 
org.apache.commons.lang3.reflect.MethodUtils.getMatchingMethod(MethodUtils.java:784)
    at dev.pshevche.App.main(App.java:22) {code}
The behavior of this method has changed between versions 3.11 and 3.12.0. 
Previously, the method would pick the first method that matches the signature 
and replace it only if a method with a more specific signature is found. The 
methods would also be ordered according to the class hierarchy: 
[https://github.com/apache/commons-lang/blob/rel/commons-lang-3.11/src/main/java/org/apache/commons/lang3/reflect/MethodUtils.java#L760.]
 Starting with 3.12.0, all the methods would have an equal distance and the 
method will throw the above exception: 
[https://github.com/apache/commons-lang/blob/master/src/main/java/org/apache/commons/lang3/reflect/MethodUtils.java#L758]

I'd argue that overridden methods are more specific and have a smaller distance 
than those of the parent and should be preferred. But if it is by design, could 
you provide some guidance on how to work around this? Currently, we can't 
provide any parameter to change the behavior or fetch all matching methods and 
filter out abstract methods.

 



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to