LANG-1310: MethodUtils.invokeMethod throws ArrayStoreException if using varargs arguments and smaller types than the method defines (closes #256)

This commit is contained in:
drajakumar 2017-03-13 22:21:12 +05:30 committed by pascalschumacher
parent 7ac12154b0
commit 1a20867d01
2 changed files with 40 additions and 6 deletions

View File

@ -700,6 +700,20 @@ public class MethodUtils {
if (bestMatch != null) {
MemberUtils.setAccessibleWorkaround(bestMatch);
}
if (bestMatch != null && bestMatch.isVarArgs() && bestMatch.getParameterTypes().length > 0 && parameterTypes.length > 0) {
final Class<?>[] methodParameterTypes = bestMatch.getParameterTypes();
final Class<?> methodParameterComponentType = methodParameterTypes[methodParameterTypes.length - 1].getComponentType();
final String methodParameterComponentTypeName = ClassUtils.primitiveToWrapper(methodParameterComponentType).getName();
final String parameterTypeName = parameterTypes[parameterTypes.length - 1].getName();
final String parameterTypeSuperClassName = parameterTypes[parameterTypes.length - 1].getSuperclass().getName();
if (!methodParameterComponentTypeName.equals(parameterTypeName)
&& !methodParameterComponentTypeName.equals(parameterTypeSuperClassName)) {
return null;
}
}
return bestMatch;
}

View File

@ -96,6 +96,10 @@ public class MethodUtilsTest {
return "bar(String...)";
}
public static String bar(final long... s) {
return "bar(long...)";
}
public static String bar(final Integer i, final String... s) {
return "bar(int, String...)";
}
@ -138,7 +142,6 @@ public class MethodUtilsTest {
return "privateStringStuff(Object)";
}
public String foo() {
return "foo()";
}
@ -155,6 +158,10 @@ public class MethodUtilsTest {
return "foo(double)";
}
public String foo(final long l) {
return "foo(long)";
}
public String foo(final String s) {
return "foo(String)";
}
@ -167,6 +174,10 @@ public class MethodUtilsTest {
return "foo(String...)";
}
public String foo(final long... l) {
return "foo(long...)";
}
public String foo(final Integer i, final String... s) {
return "foo(int, String...)";
}
@ -356,7 +367,7 @@ public class MethodUtilsTest {
NumberUtils.INTEGER_ONE));
assertEquals("foo(int)", MethodUtils.invokeMethod(testBean, "foo",
NumberUtils.BYTE_ONE));
assertEquals("foo(double)", MethodUtils.invokeMethod(testBean, "foo",
assertEquals("foo(long)", MethodUtils.invokeMethod(testBean, "foo",
NumberUtils.LONG_ONE));
assertEquals("foo(double)", MethodUtils.invokeMethod(testBean, "foo",
NumberUtils.DOUBLE_ONE));
@ -366,6 +377,15 @@ public class MethodUtilsTest {
"a", "b", "c"));
assertEquals("foo(int, String...)", MethodUtils.invokeMethod(testBean, "foo",
5, "a", "b", "c"));
assertEquals("foo(long...)", MethodUtils.invokeMethod(testBean, "foo",
1L, 2L));
try {
MethodUtils.invokeMethod(testBean, "foo",
1, 2);
fail("should throw NoSuchMethodException");
} catch (NoSuchMethodException expected) {
}
TestBean.verify(new ImmutablePair<String, Object[]>("String...", new String[]{"x", "y"}),
MethodUtils.invokeMethod(testBean, "varOverloadEcho", "x", "y"));
@ -433,12 +453,12 @@ public class MethodUtilsTest {
TestBean.class, "bar", NumberUtils.INTEGER_ONE));
assertEquals("bar(int)", MethodUtils.invokeStaticMethod(TestBean.class,
"bar", NumberUtils.BYTE_ONE));
assertEquals("bar(double)", MethodUtils.invokeStaticMethod(
TestBean.class, "bar", NumberUtils.LONG_ONE));
assertEquals("bar(double)", MethodUtils.invokeStaticMethod(
TestBean.class, "bar", NumberUtils.DOUBLE_ONE));
assertEquals("bar(String...)", MethodUtils.invokeStaticMethod(
TestBean.class, "bar", "a", "b"));
assertEquals("bar(long...)", MethodUtils.invokeStaticMethod(
TestBean.class, "bar", 1L, 2L));
assertEquals("bar(int, String...)", MethodUtils.invokeStaticMethod(
TestBean.class, "bar", NumberUtils.INTEGER_ONE, "a", "b"));
@ -576,9 +596,9 @@ public class MethodUtilsTest {
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(Integer.TYPE), singletonArray(Integer.TYPE));
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(Long.class), singletonArray(Double.TYPE));
singletonArray(Long.class), singletonArray(Long.TYPE));
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(Long.TYPE), singletonArray(Double.TYPE));
singletonArray(Long.TYPE), singletonArray(Long.TYPE));
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
singletonArray(Float.class), singletonArray(Double.TYPE));
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",