Author: markt Date: Fri Jun 25 07:53:24 2010 New Revision: 957830 URL: http://svn.apache.org/viewvc?rev=957830&view=rev Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=49414 Try to differentiate between request threads and threads started by applications
Modified: tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java tomcat/trunk/webapps/docs/config/context.xml Modified: tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties?rev=957830&r1=957829&r2=957830&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/catalina/loader/LocalStrings.properties Fri Jun 25 07:53:24 2010 @@ -46,7 +46,8 @@ webappClassLoader.clearThreadLocalFail=F webappClassLoader.stopThreadFail=Failed to terminate thread named [{0}] for web application [{1}] webappClassLoader.stopTimerThreadFail=Failed to terminate TimerThread named [{0}] for web application [{1}] webappClassLoader.validationErrorJarPath=Unable to validate JAR entry with name {0} -webappClassLoader.warnThread=The web application [{0}] appears to have started a thread named [{1}] but has failed to stop it. This is very likely to create a memory leak. +webappClassLoader.warnRequestThread=The web application [{0}] is still processing a request that has yet to finish. This is very likely to create a memory leak. You can control the time allowed for requests to finish by using the unloadDelay attribute of the standard Context implementation. +webappClassLoader.warnThread=The web application [{0}] appears to have started a thread named [{1}] but has failed to stop it. This is very likely to create a memory leak. webappClassLoader.warnTimerThread=The web application [{0}] appears to have started a TimerThread named [{1}] via the java.util.Timer API but has failed to stop it. To prevent a memory leak, the timer (and hence the associated thread) has been forcibly canceled. webappClassLoader.wrongVersion=(unable to load class {0}) webappLoader.addRepository=Adding repository {0} 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=957830&r1=957829&r2=957830&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java (original) +++ tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader.java Fri Jun 25 07:53:24 2010 @@ -2184,8 +2184,13 @@ public class WebappClassLoader continue; } - log.error(sm.getString("webappClassLoader.warnThread", - contextName, thread.getName())); + if (isRequestThread(thread)) { + log.error(sm.getString("webappClassLoader.warnRequestThread", + contextName, thread.getName())); + } else { + log.error(sm.getString("webappClassLoader.warnThread", + contextName, thread.getName())); + } // Don't try an stop the threads unless explicitly // configured to do so @@ -2241,6 +2246,36 @@ public class WebappClassLoader } + /* + * Look at a threads stack trace to see if it is a request thread or not. It + * isn't perfect, but it should be good-enough for most cases. + */ + private boolean isRequestThread(Thread thread) { + + StackTraceElement[] elements = thread.getStackTrace(); + + if (elements == null || elements.length == 0) { + // Must have stopped already. Too late to ignore it. Assume not a + // request processing thread. + return false; + } + + // Step through the methods in reverse order looking for a + // CoyoteAdapter.service() call. All requests will have this unless + // Tomcat has been heavily modified - in which case there isn't much we + // can do. + for (int i = 0; i < elements.length; i++) { + StackTraceElement element = elements[elements.length - (i+1)]; + if ("org.apache.catalina.connector.CoyoteAdapter".equals( + element.getClassName()) && + "service".equals(element.getMethodName())) { + return true; + } + } + return false; + } + + private void clearReferencesStopTimerThread(Thread thread) { // Need to get references to: Modified: tomcat/trunk/webapps/docs/config/context.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/context.xml?rev=957830&r1=957829&r2=957830&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/config/context.xml (original) +++ tomcat/trunk/webapps/docs/config/context.xml Fri Jun 25 07:53:24 2010 @@ -465,9 +465,8 @@ </attribute> <attribute name="unloadDelay" required="false"> - <p>Amount of ms that the container will wait for servlets to unload. - If not specified, the default value of the flag is <code>2000</code> - ms.</p> + <p>Number of ms that the container will wait for servlets to unload. + If not specified, the default value is <code>2000</code> ms.</p> </attribute> <attribute name="unpackWAR" required="false"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org