You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by "Taras Tielkes (JIRA)" <ji...@apache.org> on 2006/06/27 20:48:29 UTC

[jira] Created: (LOGGING-108) Classloader reference leak on Tomcat 5.5.17 with log4j in webapp

Classloader reference leak on Tomcat 5.5.17 with log4j in webapp
----------------------------------------------------------------

         Key: LOGGING-108
         URL: http://issues.apache.org/jira/browse/LOGGING-108
     Project: Commons Logging
        Type: Bug

    Versions: 1.1 Final    
 Environment: JDK 1.5.0_07, Tomcat 5.5.17
commons-logging-api-1.1.jar is configured for the Tomcat bootstrap
commons-logging-adapters-1.1.jar is deployed with a webapp
log4j-1.2.11 is deployed with webapp

This is the configuration specifically described in the release notes for 1.1:

" New jar file commons-logging-adapters-xxx.jar is now provided. This can be
  used to resolve class cast conflicts where parts of commons-logging are
  deployed via different classloaders. It is not expected to be frequently
  used; it is only necessary in situations where a container has deployed
  commons-logging-api.jar and a webapp wants to bind to a third-party
  logging implementation such as log4j. In this case, the webapp can
  experience problems if it deploys commons-logging.jar as this causes
  duplicates of the core commons-logging classes, but commons-logging-adapters
  can be safely used."
    Reporter: Taras Tielkes


Some Tomcat Jasper implementation classes are initialized (that mean static fields and static initializer) when the current thread has the webapp classloader set as the context classloader.

An example of this is org.apache.jasper.runtime.PageContextImpl

If the first JSP page rendered on a freshly started Tomcat 5.5.17 is for a webapp that contains the configuration described in the "Environment" section above, a leak will occur:

The class PageContextImpl (loader by CL above Webapp classloader in delegation chain) stays loaded for the duration of the JVM
The "log" field in this class refers to a class loaded from a WebappClassloader.

This produces a classloader reference leak to the webapp, even after undeployment.






-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


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


[jira] Closed: (LOGGING-108) Classloader reference leak on Tomcat 5.5.17 with log4j in webapp

Posted by "Simon Kitching (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/LOGGING-108?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Simon Kitching closed LOGGING-108.
----------------------------------

    Resolution: Won't Fix

As no responses were received on my last comment, closing as wontfix (tomcat/jasper issue, not JCL issue).

> Classloader reference leak on Tomcat 5.5.17 with log4j in webapp
> ----------------------------------------------------------------
>
>                 Key: LOGGING-108
>                 URL: https://issues.apache.org/jira/browse/LOGGING-108
>             Project: Commons Logging
>          Issue Type: Bug
>    Affects Versions: 1.1.0
>         Environment: JDK 1.5.0_07, Tomcat 5.5.17
> commons-logging-api-1.1.jar is configured for the Tomcat bootstrap
> commons-logging-adapters-1.1.jar is deployed with a webapp
> log4j-1.2.11 is deployed with webapp
> This is the configuration specifically described in the release notes for 1.1:
> " New jar file commons-logging-adapters-xxx.jar is now provided. This can be
>   used to resolve class cast conflicts where parts of commons-logging are
>   deployed via different classloaders. It is not expected to be frequently
>   used; it is only necessary in situations where a container has deployed
>   commons-logging-api.jar and a webapp wants to bind to a third-party
>   logging implementation such as log4j. In this case, the webapp can
>   experience problems if it deploys commons-logging.jar as this causes
>   duplicates of the core commons-logging classes, but commons-logging-adapters
>   can be safely used."
>            Reporter: Taras Tielkes
>         Attachments: path.gif
>
>
> Some Tomcat Jasper implementation classes are initialized (that mean static fields and static initializer) when the current thread has the webapp classloader set as the context classloader.
> An example of this is org.apache.jasper.runtime.PageContextImpl
> If the first JSP page rendered on a freshly started Tomcat 5.5.17 is for a webapp that contains the configuration described in the "Environment" section above, a leak will occur:
> The class PageContextImpl (loader by CL above Webapp classloader in delegation chain) stays loaded for the duration of the JVM
> The "log" field in this class refers to a class loaded from a WebappClassloader.
> This produces a classloader reference leak to the webapp, even after undeployment.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

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


[jira] Commented: (LOGGING-108) Classloader reference leak on Tomcat 5.5.17 with log4j in webapp

Posted by "Taras Tielkes (JIRA)" <ji...@apache.org>.
    [ http://issues.apache.org/jira/browse/LOGGING-108?page=comments#action_12418088 ] 

Taras Tielkes commented on LOGGING-108:
---------------------------------------

Last comment (screenshot description) should read: ...showing the reference graph from a GC root, through...

> Classloader reference leak on Tomcat 5.5.17 with log4j in webapp
> ----------------------------------------------------------------
>
>          Key: LOGGING-108
>          URL: http://issues.apache.org/jira/browse/LOGGING-108
>      Project: Commons Logging
>         Type: Bug

>     Versions: 1.1 Final
>  Environment: JDK 1.5.0_07, Tomcat 5.5.17
> commons-logging-api-1.1.jar is configured for the Tomcat bootstrap
> commons-logging-adapters-1.1.jar is deployed with a webapp
> log4j-1.2.11 is deployed with webapp
> This is the configuration specifically described in the release notes for 1.1:
> " New jar file commons-logging-adapters-xxx.jar is now provided. This can be
>   used to resolve class cast conflicts where parts of commons-logging are
>   deployed via different classloaders. It is not expected to be frequently
>   used; it is only necessary in situations where a container has deployed
>   commons-logging-api.jar and a webapp wants to bind to a third-party
>   logging implementation such as log4j. In this case, the webapp can
>   experience problems if it deploys commons-logging.jar as this causes
>   duplicates of the core commons-logging classes, but commons-logging-adapters
>   can be safely used."
>     Reporter: Taras Tielkes
>  Attachments: path.gif
>
> Some Tomcat Jasper implementation classes are initialized (that mean static fields and static initializer) when the current thread has the webapp classloader set as the context classloader.
> An example of this is org.apache.jasper.runtime.PageContextImpl
> If the first JSP page rendered on a freshly started Tomcat 5.5.17 is for a webapp that contains the configuration described in the "Environment" section above, a leak will occur:
> The class PageContextImpl (loader by CL above Webapp classloader in delegation chain) stays loaded for the duration of the JVM
> The "log" field in this class refers to a class loaded from a WebappClassloader.
> This produces a classloader reference leak to the webapp, even after undeployment.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


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


[jira] Commented: (LOGGING-108) Classloader reference leak on Tomcat 5.5.17 with log4j in webapp

Posted by "Simon Kitching (JIRA)" <ji...@apache.org>.
    [ http://issues.apache.org/jira/browse/LOGGING-108?page=comments#action_12422527 ] 
            
Simon Kitching commented on LOGGING-108:
----------------------------------------

Thanks for reporting this. Your analyis is excellent, thanks.

however I think this is really the responsibility of the tomcat/jasper team to fix, though. As you say, jasper classes present in the container classpath contain static references to Log objects, and this is just plain wrong:
  http://wiki.apache.org/jakarta-commons/Logging/StaticLog

Any sane logging library is going to have problems if this is done. The fix is probably to make that Log member non-static.

One solution is to remove all commons-logging libs from the webapp completely (and ensure log4j is deployed at the container level). In this setup, the only log4j adapter class (Log4JLogger) is the one loaded by the container classloader so its existence won't lock the webapp classloader. However that does mean you lose the ability to configure your logging per-webapp.

Actually, log4j does have its own approach to providing per-webapp configurability, even when only one instance of log4j is in the classpath. See:
  http://www.qos.ch/logging/sc.jsp
Here's another example using log4j's hierachy stuff:
  http://wiki.jboss.org/wiki/Wiki.jsp?page=Log4jRepositorySelector

In both cases, the code doesn't look quite right to me; It holds a HashMap keyed by context classloader, so that will effectively lock the webapp classloader :-). A weak hashmap should do the trick though, in most cases. Or a ContextListener in your webapp that calls a method on the selector class to clear out the entry for the webapp classloader.


> Classloader reference leak on Tomcat 5.5.17 with log4j in webapp
> ----------------------------------------------------------------
>
>                 Key: LOGGING-108
>                 URL: http://issues.apache.org/jira/browse/LOGGING-108
>             Project: Commons Logging
>          Issue Type: Bug
>    Affects Versions: 1.1 Final
>         Environment: JDK 1.5.0_07, Tomcat 5.5.17
> commons-logging-api-1.1.jar is configured for the Tomcat bootstrap
> commons-logging-adapters-1.1.jar is deployed with a webapp
> log4j-1.2.11 is deployed with webapp
> This is the configuration specifically described in the release notes for 1.1:
> " New jar file commons-logging-adapters-xxx.jar is now provided. This can be
>   used to resolve class cast conflicts where parts of commons-logging are
>   deployed via different classloaders. It is not expected to be frequently
>   used; it is only necessary in situations where a container has deployed
>   commons-logging-api.jar and a webapp wants to bind to a third-party
>   logging implementation such as log4j. In this case, the webapp can
>   experience problems if it deploys commons-logging.jar as this causes
>   duplicates of the core commons-logging classes, but commons-logging-adapters
>   can be safely used."
>            Reporter: Taras Tielkes
>         Attachments: path.gif
>
>
> Some Tomcat Jasper implementation classes are initialized (that mean static fields and static initializer) when the current thread has the webapp classloader set as the context classloader.
> An example of this is org.apache.jasper.runtime.PageContextImpl
> If the first JSP page rendered on a freshly started Tomcat 5.5.17 is for a webapp that contains the configuration described in the "Environment" section above, a leak will occur:
> The class PageContextImpl (loader by CL above Webapp classloader in delegation chain) stays loaded for the duration of the JVM
> The "log" field in this class refers to a class loaded from a WebappClassloader.
> This produces a classloader reference leak to the webapp, even after undeployment.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

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


[jira] Commented: (LOGGING-108) Classloader reference leak on Tomcat 5.5.17 with log4j in webapp

Posted by "Taras Tielkes (JIRA)" <ji...@apache.org>.
    [ http://issues.apache.org/jira/browse/LOGGING-108?page=comments#action_12418089 ] 

Taras Tielkes commented on LOGGING-108:
---------------------------------------

Last comment: in this case I need to load the log4j adapter classes from WEB-INF\lib, and cannot use "use_tccl=false" (I think)

> Classloader reference leak on Tomcat 5.5.17 with log4j in webapp
> ----------------------------------------------------------------
>
>          Key: LOGGING-108
>          URL: http://issues.apache.org/jira/browse/LOGGING-108
>      Project: Commons Logging
>         Type: Bug

>     Versions: 1.1 Final
>  Environment: JDK 1.5.0_07, Tomcat 5.5.17
> commons-logging-api-1.1.jar is configured for the Tomcat bootstrap
> commons-logging-adapters-1.1.jar is deployed with a webapp
> log4j-1.2.11 is deployed with webapp
> This is the configuration specifically described in the release notes for 1.1:
> " New jar file commons-logging-adapters-xxx.jar is now provided. This can be
>   used to resolve class cast conflicts where parts of commons-logging are
>   deployed via different classloaders. It is not expected to be frequently
>   used; it is only necessary in situations where a container has deployed
>   commons-logging-api.jar and a webapp wants to bind to a third-party
>   logging implementation such as log4j. In this case, the webapp can
>   experience problems if it deploys commons-logging.jar as this causes
>   duplicates of the core commons-logging classes, but commons-logging-adapters
>   can be safely used."
>     Reporter: Taras Tielkes
>  Attachments: path.gif
>
> Some Tomcat Jasper implementation classes are initialized (that mean static fields and static initializer) when the current thread has the webapp classloader set as the context classloader.
> An example of this is org.apache.jasper.runtime.PageContextImpl
> If the first JSP page rendered on a freshly started Tomcat 5.5.17 is for a webapp that contains the configuration described in the "Environment" section above, a leak will occur:
> The class PageContextImpl (loader by CL above Webapp classloader in delegation chain) stays loaded for the duration of the JVM
> The "log" field in this class refers to a class loaded from a WebappClassloader.
> This produces a classloader reference leak to the webapp, even after undeployment.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


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


[jira] Updated: (LOGGING-108) Classloader reference leak on Tomcat 5.5.17 with log4j in webapp

Posted by "Taras Tielkes (JIRA)" <ji...@apache.org>.
     [ http://issues.apache.org/jira/browse/LOGGING-108?page=all ]

Taras Tielkes updated LOGGING-108:
----------------------------------

    Attachment: path.gif

Screenshot from commercial JVMTI tool (YourKit) showing the reference graph from a GC, through the leak described, to the user deployed classes.

JVMTI memory snapshot was taken after application undeployment (otherwise you see more GC roots)

> Classloader reference leak on Tomcat 5.5.17 with log4j in webapp
> ----------------------------------------------------------------
>
>          Key: LOGGING-108
>          URL: http://issues.apache.org/jira/browse/LOGGING-108
>      Project: Commons Logging
>         Type: Bug

>     Versions: 1.1 Final
>  Environment: JDK 1.5.0_07, Tomcat 5.5.17
> commons-logging-api-1.1.jar is configured for the Tomcat bootstrap
> commons-logging-adapters-1.1.jar is deployed with a webapp
> log4j-1.2.11 is deployed with webapp
> This is the configuration specifically described in the release notes for 1.1:
> " New jar file commons-logging-adapters-xxx.jar is now provided. This can be
>   used to resolve class cast conflicts where parts of commons-logging are
>   deployed via different classloaders. It is not expected to be frequently
>   used; it is only necessary in situations where a container has deployed
>   commons-logging-api.jar and a webapp wants to bind to a third-party
>   logging implementation such as log4j. In this case, the webapp can
>   experience problems if it deploys commons-logging.jar as this causes
>   duplicates of the core commons-logging classes, but commons-logging-adapters
>   can be safely used."
>     Reporter: Taras Tielkes
>  Attachments: path.gif
>
> Some Tomcat Jasper implementation classes are initialized (that mean static fields and static initializer) when the current thread has the webapp classloader set as the context classloader.
> An example of this is org.apache.jasper.runtime.PageContextImpl
> If the first JSP page rendered on a freshly started Tomcat 5.5.17 is for a webapp that contains the configuration described in the "Environment" section above, a leak will occur:
> The class PageContextImpl (loader by CL above Webapp classloader in delegation chain) stays loaded for the duration of the JVM
> The "log" field in this class refers to a class loaded from a WebappClassloader.
> This produces a classloader reference leak to the webapp, even after undeployment.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


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


[jira] Commented: (LOGGING-108) Classloader reference leak on Tomcat 5.5.17 with log4j in webapp

Posted by "Taras Tielkes (JIRA)" <ji...@apache.org>.
    [ http://issues.apache.org/jira/browse/LOGGING-108?page=comments#action_12418592 ] 

Taras Tielkes commented on LOGGING-108:
---------------------------------------

Here's some proof this is happening.

Change the following code (package org.apache.jasper.runtime):
----------------------
    // Logger
    private static Log log = LogFactory.getLog(PageContextImpl.class);
----------------------

to this:

----------------------
    // Logger
    private static Log log;
	    
    static {
	System.err.println(">> CCL loader: " + Thread.currentThread().getContextClassLoader().getClass().getCanonicalName());
	System.err.println(">> our loader: " + PageContextImpl.class.getClassLoader().getClass().getCanonicalName());
	log = LogFactory.getLog(PageContextImpl.class);
	System.err.println(">> log loader: " + log.getClass().getClassLoader().getClass().getCanonicalName());
    }
----------------------

You'll see the following output (on the console) the first time a JSP page is rendered:
----------------------
...
>> CCL loader: org.apache.catalina.loader.WebappClassLoader
>> our loader: org.apache.catalina.loader.StandardClassLoader
>> log loader: org.apache.catalina.loader.WebappClassLoader
...
----------------------
You can see that the current class (PageContextImpl) was loaded by a container classloader (above the webapp CL).
You also see that commons-logging 1.1 used the context classloader to find an implementation of Log.

Since the PageContextImpl class will never be unloaded while Tomcat runs, a WebappClassLoader leak is the result.


> Classloader reference leak on Tomcat 5.5.17 with log4j in webapp
> ----------------------------------------------------------------
>
>          Key: LOGGING-108
>          URL: http://issues.apache.org/jira/browse/LOGGING-108
>      Project: Commons Logging
>         Type: Bug

>     Versions: 1.1 Final
>  Environment: JDK 1.5.0_07, Tomcat 5.5.17
> commons-logging-api-1.1.jar is configured for the Tomcat bootstrap
> commons-logging-adapters-1.1.jar is deployed with a webapp
> log4j-1.2.11 is deployed with webapp
> This is the configuration specifically described in the release notes for 1.1:
> " New jar file commons-logging-adapters-xxx.jar is now provided. This can be
>   used to resolve class cast conflicts where parts of commons-logging are
>   deployed via different classloaders. It is not expected to be frequently
>   used; it is only necessary in situations where a container has deployed
>   commons-logging-api.jar and a webapp wants to bind to a third-party
>   logging implementation such as log4j. In this case, the webapp can
>   experience problems if it deploys commons-logging.jar as this causes
>   duplicates of the core commons-logging classes, but commons-logging-adapters
>   can be safely used."
>     Reporter: Taras Tielkes
>  Attachments: path.gif
>
> Some Tomcat Jasper implementation classes are initialized (that mean static fields and static initializer) when the current thread has the webapp classloader set as the context classloader.
> An example of this is org.apache.jasper.runtime.PageContextImpl
> If the first JSP page rendered on a freshly started Tomcat 5.5.17 is for a webapp that contains the configuration described in the "Environment" section above, a leak will occur:
> The class PageContextImpl (loader by CL above Webapp classloader in delegation chain) stays loaded for the duration of the JVM
> The "log" field in this class refers to a class loaded from a WebappClassloader.
> This produces a classloader reference leak to the webapp, even after undeployment.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


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