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)