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

Michele Preti updated LANG-1648:
--------------------------------
    Description: 
I will use jackson {{ObjectMapper}} as an example, but this will happen on any 
class with multiple "candidates" methods (no exact matches)
{code:java}
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

Method method = ObjectMapper.class.getDeclaredMethod("writeTree",
    new Class<?>[] {JsonGenerator.class, JsonNode.class});
MethodUtils.getAnnotation(method, NonNull.class, true, true);
{code}
will fail with
{code:java}
Exception in thread "main" java.lang.IllegalStateException: Found multiple 
candidates for method writeTree(class 
com.fasterxml.jackson.core.JsonGenerator,class 
com.fasterxml.jackson.databind.JsonNode) on class 
com.fasterxml.jackson.core.ObjectCodec : [public abstract void 
com.fasterxml.jackson.core.ObjectCodec.writeTree(com.fasterxml.jackson.core.JsonGenerator,com.fasterxml.jackson.core.TreeNode)
 throws java.io.IOException,public abstract void 
com.fasterxml.jackson.core.TreeCodec.writeTree(com.fasterxml.jackson.core.JsonGenerator,com.fasterxml.jackson.core.TreeNode)
 throws 
java.io.IOException,com.fasterxml.jackson.core.JsonProcessingException]Exception
 in thread "main" java.lang.IllegalStateException: Found multiple candidates 
for method writeTree(class com.fasterxml.jackson.core.JsonGenerator,class 
com.fasterxml.jackson.databind.JsonNode) on class 
com.fasterxml.jackson.core.ObjectCodec : [public abstract void 
com.fasterxml.jackson.core.ObjectCodec.writeTree(com.fasterxml.jackson.core.JsonGenerator,com.fasterxml.jackson.core.TreeNode)
 throws java.io.IOException,public abstract void 
com.fasterxml.jackson.core.TreeCodec.writeTree(com.fasterxml.jackson.core.JsonGenerator,com.fasterxml.jackson.core.TreeNode)
 throws java.io.IOException,com.fasterxml.jackson.core.JsonProcessingException] 
    at 
org.apache.commons.lang3.reflect.MethodUtils.getMatchingMethod(MethodUtils.java:784)
 
    at 
org.apache.commons.lang3.reflect.MethodUtils.getAnnotation(MethodUtils.java:988)
    ...{code}
The problem is that {{getAnnotation()}} is using {{getMatchingMethod()}} to 
search for any overriden method in the superclasses

{{getMatchingMethod()}} will not return overriden methods in superclass, but 
any similar method: same name and with {{isAssignable()}} parameters.

{{getMatchingMethod()}} in itself is correct, even if a 
{{getMatchingMethod*s*()}} that could return multiple matchng methods might be 
usefull
 but {{getAnnotation()}} should not use it, instead it should simply use
{code:java}
acls.getDeclaredMethod(method.getName(), method.getParameterTypes())
{code}
or {{getMethod()}}
 because it is only interested in overridden methods (same name and exactly 
same parameters)

  was:
I will use jackson ObjectMapper as an example, but this will happen on any 
class with multiple "candidates" methods (no exact matches)
{code:java}
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

Method method = ObjectMapper.class.getDeclaredMethod("writeTree",
    new Class<?>[] {JsonGenerator.class, JsonNode.class});
MethodUtils.getAnnotation(method, NonNull.class, true, true);
{code}
will fail with
{code:java}
Exception in thread "main" java.lang.IllegalStateException: Found multiple 
candidates for method writeTree(class 
com.fasterxml.jackson.core.JsonGenerator,class 
com.fasterxml.jackson.databind.JsonNode) on class 
com.fasterxml.jackson.core.ObjectCodec : [public abstract void 
com.fasterxml.jackson.core.ObjectCodec.writeTree(com.fasterxml.jackson.core.JsonGenerator,com.fasterxml.jackson.core.TreeNode)
 throws java.io.IOException,public abstract void 
com.fasterxml.jackson.core.TreeCodec.writeTree(com.fasterxml.jackson.core.JsonGenerator,com.fasterxml.jackson.core.TreeNode)
 throws 
java.io.IOException,com.fasterxml.jackson.core.JsonProcessingException]Exception
 in thread "main" java.lang.IllegalStateException: Found multiple candidates 
for method writeTree(class com.fasterxml.jackson.core.JsonGenerator,class 
com.fasterxml.jackson.databind.JsonNode) on class 
com.fasterxml.jackson.core.ObjectCodec : [public abstract void 
com.fasterxml.jackson.core.ObjectCodec.writeTree(com.fasterxml.jackson.core.JsonGenerator,com.fasterxml.jackson.core.TreeNode)
 throws java.io.IOException,public abstract void 
com.fasterxml.jackson.core.TreeCodec.writeTree(com.fasterxml.jackson.core.JsonGenerator,com.fasterxml.jackson.core.TreeNode)
 throws java.io.IOException,com.fasterxml.jackson.core.JsonProcessingException] 
    at 
org.apache.commons.lang3.reflect.MethodUtils.getMatchingMethod(MethodUtils.java:784)
 
    at 
org.apache.commons.lang3.reflect.MethodUtils.getAnnotation(MethodUtils.java:988)
    ...{code}
The problem is that getAnnotation() is using getMatchingMethod() to search for 
any overriden method in the superclasses

getMatchingMethod() will not return overriden methods in superclass, but any 
similar method: same name and with isAssignable() parameters.

getMatchingMethod() in itself is correct, even if a getMatchingMethod*s*() that 
could return multiple matchng methods might be usefull
 but getAnnotation() should not use it, instead it should simply use
{code:java}
acls.getDeclaredMethod(method.getName(), method.getParameterTypes())
{code}
or getMethod()
 because it is only interested in overridden methods (same name and exactly 
same parameters)


> MethodUtils.getAnnotation fails with "Found multiple candidates for method 
> ..."
> -------------------------------------------------------------------------------
>
>                 Key: LANG-1648
>                 URL: https://issues.apache.org/jira/browse/LANG-1648
>             Project: Commons Lang
>          Issue Type: Bug
>          Components: lang.*
>    Affects Versions: 3.12.0
>            Reporter: Michele Preti
>            Priority: Major
>
> I will use jackson {{ObjectMapper}} as an example, but this will happen on 
> any class with multiple "candidates" methods (no exact matches)
> {code:java}
> import com.fasterxml.jackson.core.JsonGenerator;
> import com.fasterxml.jackson.databind.JsonNode;
> import com.fasterxml.jackson.databind.ObjectMapper;
> Method method = ObjectMapper.class.getDeclaredMethod("writeTree",
>     new Class<?>[] {JsonGenerator.class, JsonNode.class});
> MethodUtils.getAnnotation(method, NonNull.class, true, true);
> {code}
> will fail with
> {code:java}
> Exception in thread "main" java.lang.IllegalStateException: Found multiple 
> candidates for method writeTree(class 
> com.fasterxml.jackson.core.JsonGenerator,class 
> com.fasterxml.jackson.databind.JsonNode) on class 
> com.fasterxml.jackson.core.ObjectCodec : [public abstract void 
> com.fasterxml.jackson.core.ObjectCodec.writeTree(com.fasterxml.jackson.core.JsonGenerator,com.fasterxml.jackson.core.TreeNode)
>  throws java.io.IOException,public abstract void 
> com.fasterxml.jackson.core.TreeCodec.writeTree(com.fasterxml.jackson.core.JsonGenerator,com.fasterxml.jackson.core.TreeNode)
>  throws 
> java.io.IOException,com.fasterxml.jackson.core.JsonProcessingException]Exception
>  in thread "main" java.lang.IllegalStateException: Found multiple candidates 
> for method writeTree(class com.fasterxml.jackson.core.JsonGenerator,class 
> com.fasterxml.jackson.databind.JsonNode) on class 
> com.fasterxml.jackson.core.ObjectCodec : [public abstract void 
> com.fasterxml.jackson.core.ObjectCodec.writeTree(com.fasterxml.jackson.core.JsonGenerator,com.fasterxml.jackson.core.TreeNode)
>  throws java.io.IOException,public abstract void 
> com.fasterxml.jackson.core.TreeCodec.writeTree(com.fasterxml.jackson.core.JsonGenerator,com.fasterxml.jackson.core.TreeNode)
>  throws 
> java.io.IOException,com.fasterxml.jackson.core.JsonProcessingException] 
>     at 
> org.apache.commons.lang3.reflect.MethodUtils.getMatchingMethod(MethodUtils.java:784)
>  
>     at 
> org.apache.commons.lang3.reflect.MethodUtils.getAnnotation(MethodUtils.java:988)
>     ...{code}
> The problem is that {{getAnnotation()}} is using {{getMatchingMethod()}} to 
> search for any overriden method in the superclasses
> {{getMatchingMethod()}} will not return overriden methods in superclass, but 
> any similar method: same name and with {{isAssignable()}} parameters.
> {{getMatchingMethod()}} in itself is correct, even if a 
> {{getMatchingMethod*s*()}} that could return multiple matchng methods might 
> be usefull
>  but {{getAnnotation()}} should not use it, instead it should simply use
> {code:java}
> acls.getDeclaredMethod(method.getName(), method.getParameterTypes())
> {code}
> or {{getMethod()}}
>  because it is only interested in overridden methods (same name and exactly 
> same parameters)



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to