This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-beanutils.git
commit 7790d9591c2d0ab760ab675d7a6f4ee87245209e Author: Gary D. Gregory <garydgreg...@gmail.com> AuthorDate: Sat Aug 16 16:37:55 2025 -0400 Remove unused org.apache.commons.beanutils2.MethodUtils.invoke*(*) methods in favor of Apache Commons Lang's org.apache.commons.lang3.reflect.MethodUtils --- src/changes/changes.xml | 23 ++--- .../org/apache/commons/beanutils2/MethodUtils.java | 35 ------- .../apache/commons/beanutils2/MethodUtilsTest.java | 115 +-------------------- .../beanutils2/memoryleaktests/MemoryLeakTest.java | 2 +- 4 files changed, 10 insertions(+), 165 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index df57474b..08ffd567 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -37,23 +37,12 @@ <!-- UPDATE --> <action type="update" dev="ggregory" due-to="Gary Gregory, Dependabot">Bump org.apache.commons:commons-lang3 from 3.17.0 to 3.18.0 #357.</action> <!-- REMOVE --> - <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove unused ConstructorUtils in favor of Apache Commons Lang's org.apache.commons.lang3.ConstructorUtils. ConstructorUtils is unused in this component.</action> - <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove unused org.apache.commons.beanutils2.MethodUtils.invokeExactMethod(Object, String, Object) in favor of Apache Commons Lang's org.apache.commons.lang3.reflect.MethodUtils.</action> - <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove unused org.apache.commons.beanutils2.MethodUtils.invokeExactMethod(Object, String, Object[]) in favor of Apache Commons Lang's org.apache.commons.lang3.reflect.MethodUtils.</action> - <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove unused org.apache.commons.beanutils2.MethodUtils.invokeStaticMethod(Class, String, Object) in favor of Apache Commons Lang's org.apache.commons.lang3.reflect.MethodUtils.</action> - <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove unused org.apache.commons.beanutils2.MethodUtils.invokeExactStaticMethod(Class, String, Object) in favor of Apache Commons Lang's org.apache.commons.lang3.reflect.MethodUtils.</action> - <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove unused org.apache.commons.beanutils2.MethodUtils.invokeExactStaticMethod(Class, String, Object) in favor of Apache Commons Lang's org.apache.commons.lang3.reflect.MethodUtils.</action> - <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove unused org.apache.commons.beanutils2.MethodUtils.invokeExactStaticMethod(Class, String, Object[]) in favor of Apache Commons Lang's org.apache.commons.lang3.reflect.MethodUtils.</action> - <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove unused org.apache.commons.beanutils2.MethodUtils.invokeMethod(Object, String, Object) in favor of Apache Commons Lang's org.apache.commons.lang3.reflect.MethodUtils.</action> - <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove unused org.apache.commons.beanutils2.MethodUtils.invokeMethod(Object, String, Object[]) in favor of Apache Commons Lang's org.apache.commons.lang3.reflect.MethodUtils.</action> - <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove unused org.apache.commons.beanutils2.MethodUtils.invokeMethod(Object, String, Object[], Class[]) in favor of Apache Commons Lang's org.apache.commons.lang3.reflect.MethodUtils.</action> - <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove unused org.apache.commons.beanutils2.MethodUtils.invokeStaticMethod(Class, String, Object[]) in favor of Apache Commons Lang's org.apache.commons.lang3.reflect.MethodUtils.</action> - <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove unused org.apache.commons.beanutils2.MethodUtils.invokeStaticMethod(Class, String, Object[], Class[]) in favor of Apache Commons Lang's org.apache.commons.lang3.reflect.MethodUtils.</action> - <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove unused org.apache.commons.beanutils2.MethodUtils.invokeExactStaticMethod(Class, String, Object[], Class[]) in favor of Apache Commons Lang's org.apache.commons.lang3.reflect.MethodUtils.</action> - <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove unused org.apache.commons.beanutils2.MethodUtils.toNonPrimitiveClass(Class) in favor of org.apache.commons.lang3.ClassUtils.primitiveToWrapper(Class).</action> - <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove unused org.apache.commons.beanutils2.MethodUtils.getPrimitiveType(Class) in favor of org.apache.commons.lang3.ClassUtils.wrapperToPrimitive(Class).</action> - <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove org.apache.commons.beanutils2.MethodUtils.getPrimitiveWrapper(Class) in favor of org.apache.commons.lang3.ClassUtils.primitiveToWrapper(Class).</action> - <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove org.apache.commons.beanutils2.MethodUtils.isAssignmentCompatible(Class toClass, Class cls) in favor of org.apache.commons.lang3.ClassUtils.isAssignable(Class cls, Class toClass).</action> + <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove unused ConstructorUtils in favor of Apache Commons Lang's org.apache.commons.lang3.ConstructorUtils. ConstructorUtils is unused in this component (org.apache.commons:commons-lang3).</action> + <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove unused org.apache.commons.beanutils2.MethodUtils.invoke*(*) methods in favor of Apache Commons Lang's org.apache.commons.lang3.reflect.MethodUtils (org.apache.commons:commons-lang3).</action> + <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove unused org.apache.commons.beanutils2.MethodUtils.toNonPrimitiveClass(Class) in favor of org.apache.commons.lang3.ClassUtils.primitiveToWrapper(Class) (org.apache.commons:commons-lang3).</action> + <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove unused org.apache.commons.beanutils2.MethodUtils.getPrimitiveType(Class) in favor of org.apache.commons.lang3.ClassUtils.wrapperToPrimitive(Class) (org.apache.commons:commons-lang3).</action> + <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove org.apache.commons.beanutils2.MethodUtils.getPrimitiveWrapper(Class) in favor of org.apache.commons.lang3.ClassUtils.primitiveToWrapper(Class) (org.apache.commons:commons-lang3).</action> + <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove org.apache.commons.beanutils2.MethodUtils.isAssignmentCompatible(Class toClass, Class cls) in favor of org.apache.commons.lang3.ClassUtils.isAssignable(Class cls, Class toClass) (org.apache.commons:commons-lang3).</action> <action dev="ggregory" type="remove" due-to="Gary Gregory">Remove org.apache.commons.beanutils2.MethodUtils.getAccessibleMethod(Class, String, Class) in favor vararg variant.</action> </release> <release version="2.0.0-M2" date="2025-05-25" description="This is a major release and requires Java 8."> diff --git a/src/main/java/org/apache/commons/beanutils2/MethodUtils.java b/src/main/java/org/apache/commons/beanutils2/MethodUtils.java index ed2fbe69..46db6d31 100644 --- a/src/main/java/org/apache/commons/beanutils2/MethodUtils.java +++ b/src/main/java/org/apache/commons/beanutils2/MethodUtils.java @@ -19,7 +19,6 @@ package org.apache.commons.beanutils2; import java.lang.ref.Reference; import java.lang.ref.WeakReference; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; @@ -514,40 +513,6 @@ public final class MethodUtils { return totalCost; } - /** - * Invoke a method whose parameter types match exactly the parameter types given. - * - * <p> - * This uses reflection to invoke the method obtained from a call to {@code getAccessibleMethod()}. - * </p> - * - * @param object invoke method on this object. - * @param methodName get method with this name. - * @param args use these arguments - treat null as empty array (passing null will result in calling the parameterless method with name - * {@code methodName}). - * @param parameterTypes match these parameters - treat null as empty array. - * @return The value returned by the invoked method. - * @throws NoSuchMethodException if there is no such accessible method. - * @throws InvocationTargetException wraps an exception thrown by the method invoked. - * @throws IllegalAccessException if the requested method is not accessible via reflection. - */ - public static Object invokeExactMethod(final Object object, final String methodName, Object[] args, Class<?>[] parameterTypes) - throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - if (args == null) { - args = BeanUtils.EMPTY_OBJECT_ARRAY; - } - - if (parameterTypes == null) { - parameterTypes = BeanUtils.EMPTY_CLASS_ARRAY; - } - - final Method method = getAccessibleMethod(object.getClass(), methodName, parameterTypes); - if (method == null) { - throw new NoSuchMethodException("No such accessible method: " + methodName + "() on object: " + object.getClass().getName()); - } - return method.invoke(object, args); - } - /** * Sets whether methods should be cached for greater performance or not, default is {@code true}. * diff --git a/src/test/java/org/apache/commons/beanutils2/MethodUtilsTest.java b/src/test/java/org/apache/commons/beanutils2/MethodUtilsTest.java index 233dee49..837600ac 100644 --- a/src/test/java/org/apache/commons/beanutils2/MethodUtilsTest.java +++ b/src/test/java/org/apache/commons/beanutils2/MethodUtilsTest.java @@ -64,7 +64,7 @@ class MethodUtilsTest { void testClearCache() throws Exception { MethodUtils.clearCache(); // make sure it starts empty final PublicSubBean bean = new PublicSubBean(); - MethodUtils.invokeExactMethod(bean, "setFoo", new String[] { "alpha" }, new Class[] { String.class }); + assertNotNull(MethodUtils.getAccessibleMethod(bean.getClass(), "setFoo", new Class[] { String.class })); assertEquals(1, MethodUtils.clearCache()); assertEquals(0, MethodUtils.clearCache()); } @@ -99,56 +99,17 @@ class MethodUtilsTest { assertMethod(method, "methodBaz"); } - @Test - void testInvokeExactMethodNullArrayNullArray() throws Exception { - final Object result = MethodUtils.invokeExactMethod(new AlphaBean("parent"), "getName", null, null); - - assertEquals("parent", result); - } - @Test void testNoCaching() throws Exception { // no caching MethodUtils.setCacheMethods(false); - final PublicSubBean bean = new PublicSubBean(); - MethodUtils.invokeExactMethod(bean, "setFoo", new String[] { "alpha" }, new Class[] { String.class }); + MethodUtils.getAccessibleMethod(bean.getClass(), "setFoo", new Class[] { String.class }); assertEquals(0, MethodUtils.clearCache()); - // reset default MethodUtils.setCacheMethods(true); } - @Test - void testPublicSub() throws Exception { - // make sure that bean does what it should - final PublicSubBean bean = new PublicSubBean(); - assertEquals(bean.getFoo(), "This is foo", "Start value (foo)"); - assertEquals(bean.getBar(), "This is bar", "Start value (bar)"); - bean.setFoo("new foo"); - bean.setBar("new bar"); - assertEquals(bean.getFoo(), "new foo", "Set value (foo)"); - assertEquals(bean.getBar(), "new bar", "Set value (bar)"); - - // see if we can access public methods in a default access superclass - // from a public access subclass instance - MethodUtils.invokeExactMethod(bean, "setFoo", new String[] { "alpha" }, new Class[] { String.class }); - assertEquals(bean.getFoo(), "alpha", "Set value (foo:2)"); - MethodUtils.invokeExactMethod(bean, "setBar", new String[] { "beta" }, new Class[] { String.class }); - assertEquals(bean.getBar(), "beta", "Set value (bar:2)"); - - Method method = MethodUtils.getAccessibleMethod(PublicSubBean.class, "setFoo", String.class); - assertNotNull(method, "getAccessibleMethod() setFoo is Null"); - method.invoke(bean, "1111"); - assertEquals("1111", bean.getFoo(), "Set value (foo:3)"); - - method = MethodUtils.getAccessibleMethod(PublicSubBean.class, "setBar", String.class); - assertNotNull(method, "getAccessibleMethod() setBar is Null"); - method.invoke(bean, "2222"); - assertEquals("2222", bean.getBar(), "Set value (bar:3)"); - - } - /** * Test {@link MethodUtils#setCacheMethods(boolean)}. */ @@ -157,81 +118,11 @@ class MethodUtilsTest { MethodUtils.setCacheMethods(true); MethodUtils.clearCache(); // make sure it starts empty final PublicSubBean bean = new PublicSubBean(); - MethodUtils.invokeExactMethod(bean, "setFoo", new String[] { "alpha" }, new Class[] { String.class }); + MethodUtils.getAccessibleMethod(bean.getClass(), "setFoo", new Class[] { String.class }); assertEquals(1, MethodUtils.clearCache()); assertEquals(0, MethodUtils.clearCache()); } - /** - * Simple tests for accessing static methods via invokeMethod(). - */ - @Test - void testSimpleStatic1() throws Exception { - final TestBean bean = new TestBean(); - Object value = null; - int current = TestBean.currentCounter(); - // Return initial value of the counter - value = MethodUtils.invokeExactMethod(bean, "currentCounter", new Object[0], new Class[0]); - assertNotNull(value, "currentCounter exists"); - assertInstanceOf(Integer.class, value, "currentCounter type"); - assertEquals(current, ((Integer) value).intValue(), "currentCounter value"); - - // Increment via no-arguments version - MethodUtils.invokeExactMethod(bean, "incrementCounter", new Object[0], new Class[0]); - - // Validate updated value - current++; - value = MethodUtils.invokeExactMethod(bean, "currentCounter", new Object[0], new Class[0]); - assertNotNull(value, "currentCounter exists"); - assertInstanceOf(Integer.class, value, "currentCounter type"); - assertEquals(current, ((Integer) value).intValue(), "currentCounter value"); - - // Increment via specified-argument version - MethodUtils.invokeExactMethod(bean, "incrementCounter", new Object[] { Integer.valueOf(5) }, new Class[] { Integer.TYPE }); - - // Validate updated value - current += 5; - value = MethodUtils.invokeExactMethod(bean, "currentCounter", new Object[0], new Class[0]); - assertNotNull(value, "currentCounter exists"); - assertInstanceOf(Integer.class, value, "currentCounter type"); - assertEquals(current, ((Integer) value).intValue(), "currentCounter value"); - } - - /** - * Simple tests for accessing static methods via invokeExactMethod(). - */ - @Test - void testSimpleStatic2() throws Exception { - final TestBean bean = new TestBean(); - Object value = null; - int current = TestBean.currentCounter(); - // Return initial value of the counter - value = MethodUtils.invokeExactMethod(bean, "currentCounter", new Object[0], new Class[0]); - assertNotNull(value, "currentCounter exists"); - assertInstanceOf(Integer.class, value, "currentCounter type"); - assertEquals(current, ((Integer) value).intValue(), "currentCounter value"); - - // Increment via no-arguments version - MethodUtils.invokeExactMethod(bean, "incrementCounter", new Object[0], new Class[0]); - - // Validate updated value - current++; - value = MethodUtils.invokeExactMethod(bean, "currentCounter", new Object[0], new Class[0]); - assertNotNull(value, "currentCounter exists"); - assertInstanceOf(Integer.class, value, "currentCounter type"); - assertEquals(current, ((Integer) value).intValue(), "currentCounter value"); - - // Increment via specified-argument version - MethodUtils.invokeExactMethod(bean, "incrementCounter", new Object[] { Integer.valueOf(5) }, new Class[] { Integer.TYPE }); - - // Validate updated value - current += 5; - value = MethodUtils.invokeExactMethod(bean, "currentCounter", new Object[0], new Class[0]); - assertNotNull(value, "currentCounter exists"); - assertInstanceOf(Integer.class, value, "currentCounter type"); - assertEquals(current, ((Integer) value).intValue(), "currentCounter value"); - } - /** * Simple tests for accessing static methods via getAccessibleMethod() */ diff --git a/src/test/java/org/apache/commons/beanutils2/memoryleaktests/MemoryLeakTest.java b/src/test/java/org/apache/commons/beanutils2/memoryleaktests/MemoryLeakTest.java index 26cf1f88..5b10b666 100644 --- a/src/test/java/org/apache/commons/beanutils2/memoryleaktests/MemoryLeakTest.java +++ b/src/test/java/org/apache/commons/beanutils2/memoryleaktests/MemoryLeakTest.java @@ -382,7 +382,7 @@ public class MemoryLeakTest { // if you comment the following line, the test will work, and the ClassLoader will be released. // That proves that nothing is wrong with the test, and MethodUtils is holding a reference - assertEquals("initialValue", MethodUtils.invokeExactMethod(bean, "getName", new Object[0], new Class[0])); + assertNotNull(MethodUtils.getAccessibleMethod(bean.getClass(), "getName", new Class[0])); // this should make the reference go away. loader = null;