You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Gary D. Gregory (Jira)" <ji...@apache.org> on 2023/03/01 22:49:00 UTC

[jira] [Resolved] (LANG-1694) `MethodUtils.getMatchingMethod` fails with "Found multiple candidates" when the method is abstract

     [ https://issues.apache.org/jira/browse/LANG-1694?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Gary D. Gregory resolved LANG-1694.
-----------------------------------
    Fix Version/s: 3.13.0
       Resolution: Fixed

In git master and  https://repository.apache.org/content/repositories/snapshots/org/apache/commons/commons-lang3/3.13.0-SNAPSHOT/

> `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
>            Priority: Major
>             Fix For: 3.13.0
>
>
> *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)