From 9ae88e77d54e485d56160f1457c6ed4f2d456e0e Mon Sep 17 00:00:00 2001 From: markt Date: Wed, 24 Nov 2010 21:28:33 +0000 Subject: [PATCH] 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. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1038831 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/catalina/loader/WebappClassLoader.java | 41 ++++++++++++++++++---- webapps/docs/changelog.xml | 6 ++++ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/java/org/apache/catalina/loader/WebappClassLoader.java b/java/org/apache/catalina/loader/WebappClassLoader.java index 36b7d52c2..13f071453 100644 --- a/java/org/apache/catalina/loader/WebappClassLoader.java +++ b/java/org/apache/catalina/loader/WebappClassLoader.java @@ -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 true 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. */ diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index ab8467dc2..23de11a73 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -40,6 +40,12 @@
+ + 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. (markt) + 49650: Remove unnecessary entries package.access property defined in catalina.properties. Patch provided by Owen Farrell. (markt) -- 2.11.0