ggregory 2004/02/11 16:45:10
Modified: lang/src/java/org/apache/commons/lang/enum Enum.java
lang/src/test/org/apache/commons/lang/enum EnumTest.java
Log:
PR: http://issues.apache.org/bugzilla/show_bug.cgi?id=26876
[lang] Enum.equals does not handle different class loaders.
Revision Changes Path
1.24 +16 -23
jakarta-commons/lang/src/java/org/apache/commons/lang/enum/Enum.java
Index: Enum.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/lang/src/java/org/apache/commons/lang/enum/Enum.java,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- Enum.java 29 Nov 2003 15:03:54 -0000 1.23
+++ Enum.java 12 Feb 2004 00:45:09 -0000 1.24
@@ -567,34 +567,27 @@
} else if (other == null) {
return false;
} else if (other.getClass() == this.getClass()) {
- // shouldn't happen, but...
+ // Ok to do a class cast to Enum here since the test above
+ // guarantee both
+ // classes are in the same class loader.
return iName.equals(((Enum) other).iName);
- } else if (((Enum)
other).getEnumClass().getName().equals(getEnumClass().getName())) {
- // different classloaders
+ } else {
+ // This and other are in different class loaders, we must use
reflection.
try {
- // try to avoid reflection
- return iName.equals(((Enum) other).iName);
-
- } catch (ClassCastException ex) {
- // use reflection
- try {
- Method mth = other.getClass().getMethod("getName", null);
- String name = (String) mth.invoke(other, null);
- return iName.equals(name);
- } catch (NoSuchMethodException ex2) {
- // ignore - should never happen
- } catch (IllegalAccessException ex2) {
- // ignore - should never happen
- } catch (InvocationTargetException ex2) {
- // ignore - should never happen
- }
- return false;
+ Method mth = other.getClass().getMethod("getName", null);
+ String name = (String) mth.invoke(other, null);
+ return iName.equals(name);
+ } catch (NoSuchMethodException ex2) {
+ // ignore - should never happen
+ } catch (IllegalAccessException ex2) {
+ // ignore - should never happen
+ } catch (InvocationTargetException ex2) {
+ // ignore - should never happen
}
- } else {
return false;
}
}
-
+
/**
* <p>Returns a suitable hashCode for the enumeration.</p>
*
1.13 +43 -2
jakarta-commons/lang/src/test/org/apache/commons/lang/enum/EnumTest.java
Index: EnumTest.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/lang/src/test/org/apache/commons/lang/enum/EnumTest.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- EnumTest.java 29 Nov 2003 15:03:54 -0000 1.12
+++ EnumTest.java 12 Feb 2004 00:45:09 -0000 1.13
@@ -53,6 +53,10 @@
*/
package org.apache.commons.lang.enum;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -62,7 +66,6 @@
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
-
import org.apache.commons.lang.SerializationUtils;
/**
@@ -465,4 +468,42 @@
// are just extra references.
}
+ public void testEqualsWithDifferentClassLoaders() throws
ClassNotFoundException, SecurityException, NoSuchMethodException,
IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+ // Sanity check:
+ ColorEnum.RED.equals(ColorEnum.RED);
+ assertNotNull(ColorEnum.class.getClassLoader());
+ // set up:
+ ClassLoader scl = ClassLoader.getSystemClassLoader();
+ if (!(scl instanceof URLClassLoader)) {
+ fail("Need a better test set up.");
+ }
+ URLClassLoader urlScl = (URLClassLoader)scl;
+ ClassLoader classLoader = URLClassLoader.newInstance(urlScl.getURLs(),
null);
+ assertNotNull(classLoader);
+ assertFalse(classLoader.equals(ColorEnum.class.getClassLoader()));
+ Class otherColorEnumClass =
classLoader.loadClass("org.apache.commons.lang.enum.ColorEnum");
+ assertNotNull(otherColorEnumClass);
+ assertNotNull(otherColorEnumClass.getClassLoader());
+ assertTrue(classLoader.equals(otherColorEnumClass.getClassLoader()));
+
assertFalse(otherColorEnumClass.getClassLoader().equals(ColorEnum.class.getClassLoader()));
+ Method method = otherColorEnumClass.getMethod("getEnum", new
Class[]{String.class});
+ Object enumObject = method.invoke(otherColorEnumClass, new Object[]{"Red"});
+ assertNotNull(enumObject);
+ // the real test, part 1.
+ try {
+ ColorEnum testCase = (ColorEnum)enumObject;
+ fail("Should have thrown a ClassCastException");
+ } catch (ClassCastException e) {
+ // normal.
+ }
+ // the real test, part 2.
+ assertEquals("The two objects should match even though they are from
different class loaders", ColorEnum.RED, enumObject);
+ }
+
+ public void testEqualsToWrongInstance() {
+ ColorEnum.RED.equals("test");
+ ColorEnum.RED.equals(new Integer(1));
+ ColorEnum.RED.equals(new Boolean(true));
+ ColorEnum.RED.equals(new StringBuffer("test"));
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]