diff --git a/core/src/main/java/hudson/PluginManager.java b/core/src/main/java/hudson/PluginManager.java index a23ee2899a..945da86116 100644 --- a/core/src/main/java/hudson/PluginManager.java +++ b/core/src/main/java/hudson/PluginManager.java @@ -18,6 +18,8 @@ import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; +import org.apache.commons.logging.LogFactory; + /** * Manages {@link PluginWrapper}s. * @@ -129,6 +131,9 @@ public final class PluginManager { for (PluginWrapper p : activePlugins) { p.stop(); } + // Work around a bug in commons-logging. + // See http://www.szegedi.org/articles/memleak.html + LogFactory.release(uberClassLoader); } private final class UberClassLoader extends ClassLoader { diff --git a/core/src/main/java/hudson/PluginWrapper.java b/core/src/main/java/hudson/PluginWrapper.java index 97f45ca3f6..a8a1754888 100644 --- a/core/src/main/java/hudson/PluginWrapper.java +++ b/core/src/main/java/hudson/PluginWrapper.java @@ -5,6 +5,7 @@ import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.Expand; import org.apache.tools.ant.types.FileSet; +import org.apache.commons.logging.LogFactory; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; @@ -356,6 +357,9 @@ public final class PluginWrapper { System.err.println("Failed to shut down "+shortName); System.err.println(t); } + // Work around a bug in commons-logging. + // See http://www.szegedi.org/articles/memleak.html + LogFactory.release(classLoader); } /** diff --git a/core/src/main/java/hudson/WebAppMain.java b/core/src/main/java/hudson/WebAppMain.java index 91d11deb22..4cf118e5eb 100644 --- a/core/src/main/java/hudson/WebAppMain.java +++ b/core/src/main/java/hudson/WebAppMain.java @@ -32,6 +32,7 @@ import java.util.logging.Logger; * @author Kohsuke Kawaguchi */ public class WebAppMain implements ServletContextListener { + private final RingBufferLogHandler handler = new RingBufferLogHandler(); /** * Creates the sole instance of {@link Hudson} and register it to the {@link ServletContext}. @@ -116,7 +117,6 @@ public class WebAppMain implements ServletContextListener { * Installs log handler to monitor all Hudson logs. */ private void installLogger() { - RingBufferLogHandler handler = new RingBufferLogHandler(); Hudson.logRecords = handler.getView(); Logger.getLogger("hudson").addHandler(handler); } @@ -168,5 +168,9 @@ public class WebAppMain implements ServletContextListener { Hudson instance = Hudson.getInstance(); if(instance!=null) instance.cleanUp(); + + // Logger is in the system classloader, so if we don't do this + // the whole web app will never be undepoyed. + Logger.getLogger("hudson").removeHandler(handler); } }