leosutic 2003/08/10 17:20:05
Modified: attributes/api maven.xml
attributes/api/src/test/org/apache/avalon/attributes/test
AttributesTestCase.java
attributes/api/src/java/org/apache/avalon/attributes
Attributes.java
Added: attributes/api/src/cl1 TestClass.java TestAttribute.java
attributes/api/src/cl2 TestClass.java TestAttribute.java
Log:
Added test case to prove that classes with the same name loaded via different
classloaders behave correctly in the attribute repository cache.
Revision Changes Path
1.1 avalon-sandbox/attributes/api/src/cl1/TestClass.java
Index: TestClass.java
===================================================================
/**
* @TestAttribute ("1")
*/
public class TestClass {
}
1.1 avalon-sandbox/attributes/api/src/cl1/TestAttribute.java
Index: TestAttribute.java
===================================================================
public class TestAttribute {
private final String key;
public TestAttribute (String key) {
this.key = key;
}
public String getKey () {
return key;
}
public String toString () {
return "[TestAttribute " + key + "]";
}
}
1.1 avalon-sandbox/attributes/api/src/cl2/TestClass.java
Index: TestClass.java
===================================================================
/**
* @TestAttribute ("2")
*/
public class TestClass {
}
1.1 avalon-sandbox/attributes/api/src/cl2/TestAttribute.java
Index: TestAttribute.java
===================================================================
public class TestAttribute {
private final String key;
public TestAttribute (String key) {
this.key = key;
}
public String getKey () {
return key;
}
public String toString () {
return "[TestAttribute " + key + "]";
}
}
1.2 +28 -0 avalon-sandbox/attributes/api/maven.xml
Index: maven.xml
===================================================================
RCS file: /home/cvs/avalon-sandbox/attributes/api/maven.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- maven.xml 10 Aug 2003 22:26:54 -0000 1.1
+++ maven.xml 11 Aug 2003 00:20:05 -0000 1.2
@@ -17,6 +17,34 @@
</classpath>
</taskdef>
+ <!-- Set up the classloader tests -->
+ <attributes destDir="target/cl1/">
+ <fileset dir="src/cl1/" includes="**/*.java"/>
+ </attributes>
+ <attributes destDir="target/cl2/">
+ <fileset dir="src/cl2/" includes="**/*.java"/>
+ </attributes>
+ <javac destdir="target/cl1/"
+ classpath="target/cl1/"
+ debug="true"
+ deprecation="true">
+ <src>
+ <pathelement path="target/cl1/"/>
+ <pathelement path="src/cl1/"/>
+ <pathelement path="src/java/"/>
+ </src>
+ </javac>
+ <javac destdir="target/cl2/"
+ classpath="target/cl2/"
+ debug="true"
+ deprecation="true">
+ <src>
+ <pathelement path="target/cl2/"/>
+ <pathelement path="src/cl2/"/>
+ <pathelement path="src/java/"/>
+ </src>
+ </javac>
+
<!-- Create the Attribute Repository Classes. -->
<attributes destDir="target/temp/">
<fileset dir="src/test/" includes="**/*.java"/>
1.2 +18 -0
avalon-sandbox/attributes/api/src/test/org/apache/avalon/attributes/test/AttributesTestCase.java
Index: AttributesTestCase.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/attributes/api/src/test/org/apache/avalon/attributes/test/AttributesTestCase.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- AttributesTestCase.java 10 Aug 2003 21:47:57 -0000 1.1
+++ AttributesTestCase.java 11 Aug 2003 00:20:05 -0000 1.2
@@ -3,6 +3,9 @@
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
+import java.io.File;
+import java.net.URL;
+import java.net.URLClassLoader;
import org.apache.avalon.attributes.Attributes;
import junit.framework.TestCase;
@@ -128,5 +131,20 @@
public void testNoAttributes () throws Exception {
Method m = Sample.class.getMethod ("methodWithNoAttributes", new Class[0]);
assertEquals (0, Attributes.getAttributes (m).size ());
+ }
+
+ /**
+ * Ensure that loading a class with the same name from two different class
loaders
+ * won't mess up the attribute cache.
+ */
+ public void testClassLoaderKeying () throws Exception {
+ URLClassLoader cl1 = new URLClassLoader (new URL[]{new File
("api/target/cl1/").toURL ()}, getClass().getClassLoader ());
+ URLClassLoader cl2 = new URLClassLoader (new URL[]{new File
("api/target/cl2/").toURL ()}, getClass().getClassLoader ());
+
+ Class cl1Class = cl1.loadClass ("TestClass");
+ Class cl2Class = cl2.loadClass ("TestClass");
+
+ assertEquals ("[[TestAttribute 1]]", Attributes.getAttributes
(cl1Class).toString ());
+ assertEquals ("[[TestAttribute 2]]", Attributes.getAttributes
(cl2Class).toString ());
}
}
1.5 +17 -2
avalon-sandbox/attributes/api/src/java/org/apache/avalon/attributes/Attributes.java
Index: Attributes.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/attributes/api/src/java/org/apache/avalon/attributes/Attributes.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- Attributes.java 10 Aug 2003 22:19:23 -0000 1.4
+++ Attributes.java 11 Aug 2003 00:20:05 -0000 1.5
@@ -11,13 +11,28 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.WeakHashMap;
/**
* API for accessing attributes.
*/
public class Attributes {
- private final static Map classRepositories = new HashMap ();
+ /**
+ * A cache of attribute repositories. The map used is a WeakHashMap keyed on the
+ * Class owning the attribute repository. This works because Class objects use
+ * the identity function to compare for equality - i.e. if the two classes
+ * have the same name, and are loaded from the same two ClassLoaders, then
+ * <code>class1 == class2</code>. Also, <code>(class1.equals(class2)) ==
(class1 ==
+ * class2)</code>. This means that a once a Class reference has been
garbage-collected,
+ * it can't be re-created. Thus we can treat the cache map as a normal map -
the only
+ * entries that will ever disappear are those we can't look up anyway because we
+ * can't ever create the key for them!
+ *
+ * <p>Also, this will keep the cache from growing too big in environments where
+ * classes are loaded and unloaded all the time (i.e. application servers).
+ */
+ private final static Map classRepositories = new WeakHashMap ();
private static List initList = new ArrayList ();
@@ -52,7 +67,7 @@
throw new RepositoryError (iae);
}
- classRepositories.put (clazz, cached); // Should be keyed on
ClassLoader as well.
+ classRepositories.put (clazz, cached);
initList.remove (initList.size () - 1);
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]