LANG-1310: MethodUtils.invokeMethod throws ArrayStoreException if using varargs arguments and smaller types than the method defines (closes #256)
This commit is contained in:
parent
7ac12154b0
commit
1a20867d01
|
@ -700,6 +700,20 @@ public class MethodUtils {
|
||||||
if (bestMatch != null) {
|
if (bestMatch != null) {
|
||||||
MemberUtils.setAccessibleWorkaround(bestMatch);
|
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;
|
return bestMatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,10 @@ public class MethodUtilsTest {
|
||||||
return "bar(String...)";
|
return "bar(String...)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String bar(final long... s) {
|
||||||
|
return "bar(long...)";
|
||||||
|
}
|
||||||
|
|
||||||
public static String bar(final Integer i, final String... s) {
|
public static String bar(final Integer i, final String... s) {
|
||||||
return "bar(int, String...)";
|
return "bar(int, String...)";
|
||||||
}
|
}
|
||||||
|
@ -138,7 +142,6 @@ public class MethodUtilsTest {
|
||||||
return "privateStringStuff(Object)";
|
return "privateStringStuff(Object)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String foo() {
|
public String foo() {
|
||||||
return "foo()";
|
return "foo()";
|
||||||
}
|
}
|
||||||
|
@ -155,6 +158,10 @@ public class MethodUtilsTest {
|
||||||
return "foo(double)";
|
return "foo(double)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String foo(final long l) {
|
||||||
|
return "foo(long)";
|
||||||
|
}
|
||||||
|
|
||||||
public String foo(final String s) {
|
public String foo(final String s) {
|
||||||
return "foo(String)";
|
return "foo(String)";
|
||||||
}
|
}
|
||||||
|
@ -167,6 +174,10 @@ public class MethodUtilsTest {
|
||||||
return "foo(String...)";
|
return "foo(String...)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String foo(final long... l) {
|
||||||
|
return "foo(long...)";
|
||||||
|
}
|
||||||
|
|
||||||
public String foo(final Integer i, final String... s) {
|
public String foo(final Integer i, final String... s) {
|
||||||
return "foo(int, String...)";
|
return "foo(int, String...)";
|
||||||
}
|
}
|
||||||
|
@ -356,7 +367,7 @@ public class MethodUtilsTest {
|
||||||
NumberUtils.INTEGER_ONE));
|
NumberUtils.INTEGER_ONE));
|
||||||
assertEquals("foo(int)", MethodUtils.invokeMethod(testBean, "foo",
|
assertEquals("foo(int)", MethodUtils.invokeMethod(testBean, "foo",
|
||||||
NumberUtils.BYTE_ONE));
|
NumberUtils.BYTE_ONE));
|
||||||
assertEquals("foo(double)", MethodUtils.invokeMethod(testBean, "foo",
|
assertEquals("foo(long)", MethodUtils.invokeMethod(testBean, "foo",
|
||||||
NumberUtils.LONG_ONE));
|
NumberUtils.LONG_ONE));
|
||||||
assertEquals("foo(double)", MethodUtils.invokeMethod(testBean, "foo",
|
assertEquals("foo(double)", MethodUtils.invokeMethod(testBean, "foo",
|
||||||
NumberUtils.DOUBLE_ONE));
|
NumberUtils.DOUBLE_ONE));
|
||||||
|
@ -366,6 +377,15 @@ public class MethodUtilsTest {
|
||||||
"a", "b", "c"));
|
"a", "b", "c"));
|
||||||
assertEquals("foo(int, String...)", MethodUtils.invokeMethod(testBean, "foo",
|
assertEquals("foo(int, String...)", MethodUtils.invokeMethod(testBean, "foo",
|
||||||
5, "a", "b", "c"));
|
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"}),
|
TestBean.verify(new ImmutablePair<String, Object[]>("String...", new String[]{"x", "y"}),
|
||||||
MethodUtils.invokeMethod(testBean, "varOverloadEcho", "x", "y"));
|
MethodUtils.invokeMethod(testBean, "varOverloadEcho", "x", "y"));
|
||||||
|
@ -433,12 +453,12 @@ public class MethodUtilsTest {
|
||||||
TestBean.class, "bar", NumberUtils.INTEGER_ONE));
|
TestBean.class, "bar", NumberUtils.INTEGER_ONE));
|
||||||
assertEquals("bar(int)", MethodUtils.invokeStaticMethod(TestBean.class,
|
assertEquals("bar(int)", MethodUtils.invokeStaticMethod(TestBean.class,
|
||||||
"bar", NumberUtils.BYTE_ONE));
|
"bar", NumberUtils.BYTE_ONE));
|
||||||
assertEquals("bar(double)", MethodUtils.invokeStaticMethod(
|
|
||||||
TestBean.class, "bar", NumberUtils.LONG_ONE));
|
|
||||||
assertEquals("bar(double)", MethodUtils.invokeStaticMethod(
|
assertEquals("bar(double)", MethodUtils.invokeStaticMethod(
|
||||||
TestBean.class, "bar", NumberUtils.DOUBLE_ONE));
|
TestBean.class, "bar", NumberUtils.DOUBLE_ONE));
|
||||||
assertEquals("bar(String...)", MethodUtils.invokeStaticMethod(
|
assertEquals("bar(String...)", MethodUtils.invokeStaticMethod(
|
||||||
TestBean.class, "bar", "a", "b"));
|
TestBean.class, "bar", "a", "b"));
|
||||||
|
assertEquals("bar(long...)", MethodUtils.invokeStaticMethod(
|
||||||
|
TestBean.class, "bar", 1L, 2L));
|
||||||
assertEquals("bar(int, String...)", MethodUtils.invokeStaticMethod(
|
assertEquals("bar(int, String...)", MethodUtils.invokeStaticMethod(
|
||||||
TestBean.class, "bar", NumberUtils.INTEGER_ONE, "a", "b"));
|
TestBean.class, "bar", NumberUtils.INTEGER_ONE, "a", "b"));
|
||||||
|
|
||||||
|
@ -576,9 +596,9 @@ public class MethodUtilsTest {
|
||||||
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
|
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
|
||||||
singletonArray(Integer.TYPE), singletonArray(Integer.TYPE));
|
singletonArray(Integer.TYPE), singletonArray(Integer.TYPE));
|
||||||
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
|
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
|
||||||
singletonArray(Long.class), singletonArray(Double.TYPE));
|
singletonArray(Long.class), singletonArray(Long.TYPE));
|
||||||
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
|
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
|
||||||
singletonArray(Long.TYPE), singletonArray(Double.TYPE));
|
singletonArray(Long.TYPE), singletonArray(Long.TYPE));
|
||||||
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
|
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
|
||||||
singletonArray(Float.class), singletonArray(Double.TYPE));
|
singletonArray(Float.class), singletonArray(Double.TYPE));
|
||||||
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
|
expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo",
|
||||||
|
|
Loading…
Reference in New Issue