You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Craig Ringer (JIRA)" <ji...@apache.org> on 2011/06/26 04:42:47 UTC

[jira] [Commented] (POOL-161) ContextClassLoader problems for the Evictor thread

    [ https://issues.apache.org/jira/browse/POOL-161?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13055006#comment-13055006 ] 

Craig Ringer commented on POOL-161:
-----------------------------------

This has been biting me rather severely. It's not "only" a classloader leak because, by leaking the classloader it can become impossible to unload huge parts of the web application because so many Java libraries like to keep static caches.

Mark Thomas: It's not correct to state that having each app use its own copy of commons-pool will fix the issue. In fact, I encountered the issue precisely *because* my app deploys its own copy of commons-pool. I landed up with a timer thread used by commons-pool in a ThreadGroup owned by the app server. The timer thread holds a reference to my classloader via contextClassLoader, so my app's classloader cannot be unloaded.

An effective workaround appears to be to move apache commons pool into the application server's set of provided classes. For Glassfish, that's glassfish/domains/domain1/lib .

> ContextClassLoader problems for the Evictor thread
> --------------------------------------------------
>
>                 Key: POOL-161
>                 URL: https://issues.apache.org/jira/browse/POOL-161
>             Project: Commons Pool
>          Issue Type: Bug
>    Affects Versions: 1.5.4
>            Reporter: Sylvain Laurent
>             Fix For: 2.0
>
>         Attachments: TestGenericObjectPoolClassLoader.patch.txt, patch_Evictor_CCL.txt
>
>
> Since a single Timer is used for several GenericObjectPool instances, this may create classloader issues and a memory leak of one classloader :
> Let's imagine the following scenario :
> - commons-pool.jar is in the classpath of a webapp container (e.g. tomcat).
> - 2 webapps A and B are deployed, each creating an instance of GenericObjectPool for its own usage.
> - each webapp makes use of the idle object evictor and sets a positive number for minIdle
> - first, webapp A instantiates its GenericObjectPool. Since this is the first TimerTask to be created, the Timer instance is created, thus creating a Thread whose ContextClassLoader is the current one, that is webapp A's ContextClassLoader.
> The TimerTask properly creates instances of idle objects in the pool, making use of the ObjectFactory provided by A.
> - then B instantiates its GenericObjectPool. A new TimerTask is created, and it tries to invoke the ObjectFactory provided by B. But when it needs a class that only exists in B webapp, it cannot find it because the ContextClassLoader of the Timer Thread is A's classloader.
> Other side effect : if webapp A is undeployed, but B is still running, then A's webappClassLoader cannot be GCed because the Timer Thread keeps a strong reference to A's classloader (as its context classloader).

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira