DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://nagoya.apache.org/bugzilla/show_bug.cgi?id=24186>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND INSERTED IN THE BUG DATABASE.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=24186 Jasper SystemLogHandler memory leak Summary: Jasper SystemLogHandler memory leak Product: Tomcat 5 Version: 5.0.14 Platform: Other OS/Version: Other Status: NEW Severity: Normal Priority: Other Component: Jasper AssignedTo: [EMAIL PROTECTED] ReportedBy: [EMAIL PROTECTED] In an embedded setting it may be desirable to load and unload Jasper in an own classloader. This is impossible with Jasper right now without a memory leak. o.a.j.c.Compiler sets System.err to an instance of o.a.j.u.SystemLogHandler in its static initializer and never reset it. A new instance of Jasper will pick up this instance as its 'wrapped' PrintStream and so on ... This way, System.err retains a reference chain to each incarnation of SystemLogHandler and the whole classloader cannot be unloaded. I propose to move the redirection to the JspRuntimeContext constructor and to undo it in JspRuntimeContext#destroy. With that change, Jasper can be unloaded without memory leak. Actually, since Jasper uses Ant for compilation which seems to support System.{out,err} redirect, it is not clear to me why the SystemLogHandler is in there (legacy?). Workaround: manually reset System.err on unload. patch against current CVS: =================================================================== RCS file: /home/cvspublic/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Compiler.java,v retrieving revision 1.71 diff -u -r1.71 Compiler.java --- compiler/Compiler.java 1 Oct 2003 22:44:02 -0000 1.71 +++ compiler/Compiler.java 28 Oct 2003 17:38:06 -0000 @@ -98,12 +98,6 @@ // ----------------------------------------------------------------- Static - static { - - System.setErr(new SystemLogHandler(System.err)); - - } - // Some javac are not thread safe; use a lock to serialize compilation, static Object javacLock = new Object(); =================================================================== RCS file: /home/cvspublic/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/JspRuntimeContext.java,v retrieving revision 1.16 diff -u -r1.16 JspRuntimeContext.java --- compiler/JspRuntimeContext.java 2 Sep 2003 21:39:58 -0000 1.16 +++ compiler/JspRuntimeContext.java 28 Oct 2003 17:38:06 -0000 @@ -82,6 +82,7 @@ import org.apache.jasper.Constants; import org.apache.jasper.JspCompilationContext; import org.apache.jasper.Options; +import org.apache.jasper.util.SystemLogHandler; import org.apache.jasper.runtime.JspFactoryImpl; import org.apache.jasper.security.SecurityClassLoad; import org.apache.jasper.servlet.JspServletWrapper; @@ -125,6 +126,8 @@ */ public JspRuntimeContext(ServletContext context, Options options) { + System.setErr(new SystemLogHandler(System.err)); + this.context = context; this.options = options; @@ -271,7 +274,10 @@ /** * Process a "destory" event for this web application context. */ - public void destroy() { + public void destroy() { + + if(System.err instanceof SystemLogHandler) + System.setErr(((SystemLogHandler)System.err).getWrapped()); threadStop(); =================================================================== RCS file: /home/cvspublic/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/util/SystemLogHandler.java,v retrieving revision 1.2 diff -u -r1.2 SystemLogHandler.java --- util/SystemLogHandler.java 2 Sep 2003 21:40:00 -0000 1.2 +++ util/SystemLogHandler.java 28 Oct 2003 17:38:06 -0000 @@ -79,7 +79,7 @@ */ public SystemLogHandler(PrintStream wrapped) { super(wrapped); - out = wrapped; + this.wrapped = wrapped; } @@ -89,7 +89,7 @@ /** * Wrapped PrintStream. */ - protected PrintStream out = null; + protected PrintStream wrapped = null; /** @@ -107,6 +107,10 @@ // --------------------------------------------------------- Public Methods + public PrintStream getWrapped() { + return wrapped; + } + /** * Start capturing thread's output. */ @@ -142,7 +146,7 @@ protected PrintStream findStream() { PrintStream ps = (PrintStream) streams.get(Thread.currentThread()); if (ps == null) { - ps = out; + ps = wrapped; } return ps; } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]