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]

Reply via email to