commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From skitch...@apache.org
Subject svn commit: r370464 - /jakarta/commons/proper/logging/trunk/src/java/org/apache/commons/logging/impl/ServletContextCleaner.java
Date Thu, 19 Jan 2006 12:17:05 GMT
Author: skitching
Date: Thu Jan 19 04:16:56 2006
New Revision: 370464

URL: http://svn.apache.org/viewcvs?rev=370464&view=rev
Log:
Walk the entire hierarchy of ClassLoaders, releasing memory for the
current webapp from each copy of LogFactory found.

Modified:
    jakarta/commons/proper/logging/trunk/src/java/org/apache/commons/logging/impl/ServletContextCleaner.java

Modified: jakarta/commons/proper/logging/trunk/src/java/org/apache/commons/logging/impl/ServletContextCleaner.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/logging/trunk/src/java/org/apache/commons/logging/impl/ServletContextCleaner.java?rev=370464&r1=370463&r2=370464&view=diff
==============================================================================
--- jakarta/commons/proper/logging/trunk/src/java/org/apache/commons/logging/impl/ServletContextCleaner.java
(original)
+++ jakarta/commons/proper/logging/trunk/src/java/org/apache/commons/logging/impl/ServletContextCleaner.java
Thu Jan 19 04:16:56 2006
@@ -17,8 +17,11 @@
 
 package org.apache.commons.logging.impl;
 
-import javax.servlet.ServletContextListener;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
 import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
 
 import org.apache.commons.logging.LogFactory;
 
@@ -48,6 +51,8 @@
  */
 
 public class ServletContextCleaner implements ServletContextListener {
+
+    private Class[] RELEASE_SIGNATURE = {ClassLoader.class};
     
     /**
      * Invoked when a webapp is undeployed, this tells the LogFactory
@@ -55,7 +60,47 @@
      * contextClassloader.
      */
     public void contextDestroyed(ServletContextEvent sce) {
-        LogFactory.release(Thread.currentThread().getContextClassLoader());
+        ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+
+        Object[] params = new Object[1];
+        params[0] = tccl;
+
+        // Walk up the tree of classloaders, finding all the available
+        // LogFactory classes and releasing any objects associated with
+        // the tccl (ie the webapp).
+        ClassLoader loader = tccl;
+        while (loader != null) {
+            // Load via the current loader. Note that if the class is not accessable
+            // via this loader, but is accessable via some ancestor then that class
+            // will be returned.
+            try {
+                Class logFactoryClass = loader.loadClass("org.apache.commons.logging.LogFactory");
+                Method releaseMethod = logFactoryClass.getMethod("release", RELEASE_SIGNATURE);
+                releaseMethod.invoke(null, params);
+                loader = logFactoryClass.getClassLoader().getParent();
+            } catch(ClassNotFoundException ex) {
+                // Neither the current classloader nor any of its ancestors could find
+                // the LogFactory class, so we can stop now.
+                loader = null;
+            } catch(NoSuchMethodException ex) {
+                // This is not expected; every version of JCL has this method
+                System.err.println("LogFactory instance found which does not support release
method!");
+                loader = null;
+            } catch(IllegalAccessException ex) {
+                // This is not expected; every ancestor class should be accessable
+                System.err.println("LogFactory instance found which is not accessable!");
+                loader = null;
+            } catch(InvocationTargetException ex) {
+                // This is not expected
+                System.err.println("LogFactory instance release method failed!");
+                loader = null;
+            }
+        }
+        
+        // Just to be sure, invoke release on the LogFactory that is visible from
+        // this ServletContextCleaner class too. This should already have been caught
+        // by the above loop but just in case...
+        LogFactory.release(tccl);
     }
     
     /**



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message