commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bay...@apache.org
Subject svn commit: r395153 - in /jakarta/commons/proper/lang/trunk/src: java/org/apache/commons/lang/ClassUtils.java test/org/apache/commons/lang/ClassUtilsTest.java
Date Wed, 19 Apr 2006 06:30:16 GMT
Author: bayard
Date: Tue Apr 18 23:30:14 2006
New Revision: 395153

URL: http://svn.apache.org/viewcvs?rev=395153&view=rev
Log:
Added new method to allow work-arounds for Java bug 4071957; as specified in issue 34351

Modified:
    jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/ClassUtils.java
    jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/ClassUtilsTest.java

Modified: jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/ClassUtils.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/ClassUtils.java?rev=395153&r1=395152&r2=395153&view=diff
==============================================================================
--- jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/ClassUtils.java (original)
+++ jakarta/commons/proper/lang/trunk/src/java/org/apache/commons/lang/ClassUtils.java Tue
Apr 18 23:30:14 2006
@@ -15,6 +15,9 @@
  */
 package org.apache.commons.lang;
 
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -587,6 +590,53 @@
         ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
         ClassLoader loader = contextCL == null ? ClassUtils.class.getClassLoader() : contextCL;
         return getClass(loader, className, initialize );
+    }
+
+    
+    /**
+     * <p>Returns the desired Method much like <code>Class.getMethod</code>,
however 
+     * it ensures that the returned Method is from a public class or interface and not 
+     * from an anonymous inner class. This means that the Method is invokable and 
+     * doesn't fall foul of Java bug 
+     * <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4071957">4071957</a>).
+     *
+     *  <code><pre>Set set = Collections.unmodifiableSet(...);
+     *  Method method = ClassUtils.getPublicMethod(set.getClass(), "isEmpty",  new Class[0]);
+     *  Object result = method.invoke(set, new Object[]);</pre></code>
+     * </p>
+     */
+    public static Method getPublicMethod(Class cls, String methodName, Class parameterTypes[])

+        throws SecurityException, NoSuchMethodException 
+    {
+        
+        Method declaredMethod = cls.getMethod(methodName, parameterTypes);
+ 
+        if (Modifier.isPublic(declaredMethod.getDeclaringClass().getModifiers())) {
+            return declaredMethod;
+        }
+
+        List candidateClasses = new ArrayList();
+        candidateClasses.addAll(getAllInterfaces(cls));
+        candidateClasses.addAll(getAllSuperclasses(cls));
+
+        for (Iterator iter=candidateClasses.iterator(); iter.hasNext(); ) {
+            Class candidateClass = (Class) iter.next();
+            if (!Modifier.isPublic(candidateClass.getModifiers())) {
+                continue;
+            }
+            Method candidateMethod;
+            try {
+                candidateMethod = candidateClass.getMethod(methodName, parameterTypes);
+            } catch (NoSuchMethodException e) {
+                continue;
+            }
+            if (Modifier.isPublic(candidateMethod.getDeclaringClass().getModifiers())) {
+                return candidateMethod;
+            }
+        }
+        
+        String message = "Can't find an public method for " + methodName + " " + ArrayUtils.toString(parameterTypes);

+        throw new NoSuchMethodException(message);
     }
 
     /**

Modified: jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/ClassUtilsTest.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/ClassUtilsTest.java?rev=395153&r1=395152&r2=395153&view=diff
==============================================================================
--- jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/ClassUtilsTest.java
(original)
+++ jakarta/commons/proper/lang/trunk/src/test/org/apache/commons/lang/ClassUtilsTest.java
Tue Apr 18 23:30:14 2006
@@ -16,12 +16,16 @@
 package org.apache.commons.lang;
 
 import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
 
 import junit.framework.Test;
 import junit.framework.TestCase;
@@ -520,4 +524,35 @@
         return URLClassLoader.newInstance(urlScl.getURLs(), null);
     }
 
+    // Show the Java bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4071957
+    // We may have to delete this if a JDK fixes the bug.
+    public void testShowJavaBug() throws Exception {
+        // Tests with Collections$UnmodifiableSet
+        Set set = Collections.unmodifiableSet(new HashSet());
+        Method isEmptyMethod = set.getClass().getMethod("isEmpty",  new Class[0]);
+        try {
+            isEmptyMethod.invoke(set, new Object[0]);
+            fail("Failed to throw IllegalAccessException as expected");
+        } catch(IllegalAccessException iae) {
+            // expected
+        }
+    }
+
+    public void testGetPublicMethod() throws Exception {
+        // Tests with Collections$UnmodifiableSet
+        Set set = Collections.unmodifiableSet(new HashSet());
+        Method isEmptyMethod = ClassUtils.getPublicMethod(set.getClass(), "isEmpty",  new
Class[0]);
+            assertTrue(Modifier.isPublic(isEmptyMethod.getDeclaringClass().getModifiers()));
+ 
+        try {
+            isEmptyMethod.invoke(set, new Object[0]);
+        } catch(java.lang.IllegalAccessException iae) {
+            fail("Should not have thrown IllegalAccessException");
+        }
+               
+        // Tests with a public Class
+        Method toStringMethod = ClassUtils.getPublicMethod(Object.class, "toString",  new
Class[0]);
+            assertEquals(Object.class.getMethod("toString", new Class[0]), toStringMethod);
+    }
+ 
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message