remm 01/09/06 18:23:25
Modified: catalina/src/share/org/apache/catalina/loader
WebappClassLoader.java
Log:
- Should make the classloading fully thread safe (apparently synchronizing on
the defineClass is not enough).
- The critical path of findResourceInternal or findClassInternal should not be
synchronized for performance reasons, because it is called very often (unlike
the call to defineClass which only happens once).
- I assume Peter will tell me it still doesn't work (in which case I would appreciate
a test case) ;-)
Revision Changes Path
1.14 +23 -9
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java
Index: WebappClassLoader.java
===================================================================
RCS file:
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- WebappClassLoader.java 2001/08/28 18:12:37 1.13
+++ WebappClassLoader.java 2001/09/07 01:23:25 1.14
@@ -1,7 +1,7 @@
/*
- * $Header:
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java,v
1.13 2001/08/28 18:12:37 remm Exp $
- * $Revision: 1.13 $
- * $Date: 2001/08/28 18:12:37 $
+ * $Header:
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java,v
1.14 2001/09/07 01:23:25 remm Exp $
+ * $Revision: 1.14 $
+ * $Date: 2001/09/07 01:23:25 $
*
* ====================================================================
*
@@ -123,7 +123,7 @@
*
* @author Remy Maucherat
* @author Craig R. McClanahan
- * @version $Revision: 1.13 $ $Date: 2001/08/28 18:12:37 $
+ * @version $Revision: 1.14 $ $Date: 2001/09/07 01:23:25 $
*/
public class WebappClassLoader
extends URLClassLoader
@@ -1482,11 +1482,17 @@
}
synchronized(this) {
- clazz = defineClass(name, entry.binaryContent, 0,
- entry.binaryContent.length, codeSource);
+ // Since all threads use the same ResourceEntry instance, it is
+ // the one which will contain the class
+ if (entry.loadedClass == null) {
+ clazz = defineClass(name, entry.binaryContent, 0,
+ entry.binaryContent.length, codeSource);
+ entry.loadedClass = clazz;
+ } else {
+ clazz = entry.loadedClass;
+ }
}
- entry.loadedClass = clazz;
return clazz;
@@ -1635,8 +1641,16 @@
entry.binaryContent = binaryContent;
// Add the entry in the local resource repository
- synchronized (resourceEntries) {
- resourceEntries.put(name, entry);
+ synchronized (this) {
+ // Ensures that all the threads which may be in a race to load
+ // a particular class all end up with the same ResourceEntry
+ // instance
+ ResourceEntry entry2 = (ResourceEntry) resourceEntries.get(name);
+ if (entry2 == null) {
+ resourceEntries.put(name, entry);
+ } else {
+ entry = entry2;
+ }
}
return entry;