Author: markt
Date: Wed Nov 24 21:28:33 2010
New Revision: 1038831

URL: http://svn.apache.org/viewvc?rev=1038831&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=48837
Extend thread local memory leak detection to include classes loaded by 
subordinate class loaders to the web application's class loader such as the 
Jasper class loader.
Based on a patch by Sylvain Laurent.

Modified:
    tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java?rev=1038831&r1=1038830&r2=1038831&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java Wed Nov 
24 21:28:33 2010
@@ -2183,7 +2183,7 @@ public class WebappClassLoader
         for (Thread thread : threads) {
             if (thread != null) {
                 ClassLoader ccl = thread.getContextClassLoader();
-                if (ccl != null && ccl == this) {
+                if (ccl == this) {
                     // Don't warn about this thread
                     if (thread == Thread.currentThread()) {
                         continue;
@@ -2424,8 +2424,8 @@ public class WebappClassLoader
                         boolean remove = false;
                         // Check the key
                         Object key = ((Reference<?>) table[j]).get();
-                        if (this.equals(key) || (key != null &&
-                                this == key.getClass().getClassLoader())) {
+                        if (this.equals(key) ||
+                                isLoadedByThisWebAppClassLoader(key)) {
                             remove = true;
                         }
                         // Check the value
@@ -2433,15 +2433,15 @@ public class WebappClassLoader
                             table[j].getClass().getDeclaredField("value");
                         valueField.setAccessible(true);
                         Object value = valueField.get(table[j]);
-                        if (this.equals(value) || (value != null &&
-                                this == value.getClass().getClassLoader())) {
+                        if (this.equals(value) ||
+                                isLoadedByThisWebAppClassLoader(value)) {
                             remove = true;
                         }
                         if (remove) {
                             Object[] args = new Object[5];
                             args[0] = contextName;
                             if (key != null) {
-                                args[1] = key.getClass().getCanonicalName();
+                                args[1] = getPrettyClassName(key.getClass());
                                 try {
                                     args[2] = key.toString();
                                 } catch (Exception e) {
@@ -2453,7 +2453,7 @@ public class WebappClassLoader
                                 }
                             }
                             if (value != null) {
-                                args[3] = value.getClass().getCanonicalName();
+                                args[3] = getPrettyClassName(value.getClass());
                                 try {
                                     args[4] = value.toString();
                                 } catch (Exception e) {
@@ -2503,6 +2503,33 @@ public class WebappClassLoader
         }
     }
 
+    private String getPrettyClassName(Class<?> clazz) {
+        String name = clazz.getCanonicalName();
+        if (name==null){
+            name = clazz.getName();
+        }
+        return name;
+    }
+    
+    /**
+     * @param o object to test
+     * @return <code>true</code> if o has been loaded by the current 
classloader
+     * or one of its descendants.
+     */
+    private boolean isLoadedByThisWebAppClassLoader(Object o) {
+        if (o == null) {
+            return false;
+        }
+        ClassLoader cl = o.getClass().getClassLoader();
+        while (cl != null) {
+            if(cl == this) {
+                return true;
+            }
+            cl = cl.getParent();
+        }
+        return false;
+    }
+        
     /*
      * Get the set of current threads as an array.
      */

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1038831&r1=1038830&r2=1038831&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Wed Nov 24 21:28:33 2010
@@ -40,6 +40,12 @@
 <section name="Tomcat 7.0.6 (markt)">
   <subsection name="Catalina">
     <changelog>
+      <add>
+        <bug>48837</bug>: Extend thread local memory leak detection to include
+        classes loaded by subordinate class loaders to the web
+        application&apos;s class loader such as the Jasper class loader. Based
+        on a patch by Sylvain Laurent. (markt)
+      </add>
       <fix>
         <bug>49650</bug>: Remove unnecessary entries package.access property
         defined in catalina.properties. Patch provided by Owen Farrell. 
(markt) 



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to