ClassLoader Leak Prevention library version 1.13.0 released

Version 1.13.0 of ClassLoader Leak Prevention library has just been released, and should propagate to Maven Central shortly.

This version changes the treatment of threads that uses the web apps ClassLoader as its contextClassLoader, while neither the Thread nor its Runnable are loaded by that ClassLoader. Previously the library would kill such Threads, assuming the ClassLoaderLeakPreventor.stopThreads setting was not explicitly disabled, which caused issues with Tomcat 7 executors.

Grab the new version via Maven central or download the jar manually.

<dependency>
  <groupId>se.jiderhamn</groupId>
  <artifactId>classloader-leak-prevention</artifactId>
  <version>1.13.0</version>
</dependency>
  • Neil 12345

    Hello,
    I’ve read your 5 articles on classloader leaks and they are brilliant. I’ve been trying out your code on the latest version of a CFX webapp (a completely empty webapp created from a wsdl) to see if it fixes the inability to simply stop the service (without even running it) where I’m getting SEVERE tomcat messages, but sadly it still fails. I guess I better resign myself to JAXB just being broken as I see a lot of people with the same issue.
    Anyway, this is the stack trace your code produced, is there anything useful in there to diagnose why JaxB is leaking?
    ClassLoaderLeakPreventor: Stopping Thread ‘Thread[default-workqueue-1,5,default-
    workqueue]’ of type java.lang.Thread running in web app after 5000 ms
    ClassLoaderLeakPreventor: Stopping Thread ‘Thread[default-workqueue-2,5,default-
    workqueue]’ of type java.lang.Thread running in web app after 5000 ms
    ClassLoaderLeakPreventor: Stopping Thread ‘Thread[default-workqueue-3,5,default-
    workqueue]’ of type java.lang.Thread running in web app after 5000 ms
    Exception in thread “default-workqueue-2” java.lang.IllegalMonitorStateException
    at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLoc
    k.java:155)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(Abstrac
    tQueuedSynchronizer.java:1260)
    at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:46
    0)
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.jav
    a:449)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.ja
    va:1043)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.
    java:1103)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor
    .java:603)
    at org.apache.cxf.workqueue.AutomaticWorkQueueImpl$AWQThreadFactory$1.ru
    n(AutomaticWorkQueueImpl.java:353)
    at java.lang.Thread.run(Thread.java:722)
    Exception in thread “default-workqueue-3” java.lang.IllegalMonitorStateException
    at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLoc
    k.java:155)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(Abstrac
    tQueuedSynchronizer.java:1260)
    at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:46
    0)ClassLoaderLeakPreventor: Custom ThreadLocal of type com.sun.xml.bind.v2.Class
    Factory$1: com.sun.xml.bind.v2.ClassFactory$1@311825f with value {class org.apac
    he.cxf.ws.discovery.wsdl.ScopesType=java.lang.ref.WeakReference@72862c8b, class
    java.util.ArrayList=java.lang.ref.WeakReference@46d6946a, class javax.xml.ws.wsa
    ddressing.W3CEndpointReference$Elements=java.lang.ref.WeakReference@31a9df7b, cl
    ass javax.xml.ws.wsaddressing.W3CEndpointReference$Address=java.lang.ref.WeakRef
    erence@78f1db6, class org.apache.cxf.ws.discovery.wsdl.HelloType=java.lang.ref.W
    eakReference@44e79b9a, class javax.xml.ws.wsaddressing.W3CEndpointReference=java
    .lang.ref.WeakReference@4198becd} of type java.util.WeakHashMap will be made sta
    le for later expunging from Thread[default-workqueue-3,5,default-workqueue]
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.jav
    a:449)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.ja
    va:1043)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.
    java:1103)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor
    .java:603)
    at org.apache.cxf.workqueue.AutomaticWorkQueueImpl$AWQThreadFactory$1.ru
    n(AutomaticWorkQueueImpl.java:353)ClassLoaderLeakPreventor: Since Java 1.6+ is u
    sed, we can call public static final void java.util.ResourceBundle.clearCache(ja
    va.lang.ClassLoader)
    at java.lang.Thread.run(Thread.java:722)
    ClassLoaderLeakPreventor: Releasing web app classloader from Apache Commons Logg
    ing

    • Hi Neal and thank you! Have you tried getting a heap dump after it has leaked? (Might require you running something other than Tomcat)

      If it is a completely empty app, maybe you could make it available for analysis?

      • Neil 12345

        I tried the cfx group and bug tracker but no replies. It’s repeatable by simply doing the above so I’ve no idea why nobody else has noticed…. And I’ve tried on three different computers and platforms.

        • Is this the problem you are seeing?
          Also check out the linked issues (JAXB-831, JAXB-563).

          At least that seems to be the answer to your question on StackOverflow and CFX bugtracker, although possibly not to the “workqueue” items in the stacktrace you provided here.

          • Neil 12345

            Thanks for taking the time to look, it’s appreciated. I think I saw those before and it’s either a bug not fixed/not on their radar to fix or I can’t unmarshall anything as I’m using CFX not jaxb directly.

  • pu

    You are brilliant! Your articles helped me a lot to learn and resolve so many class loader related issues. I still have some open issues with pig/ hive etc else all other possible leaks are taken care of. Thanks a lot 🙂

    • Thanks pu! Do you happen to have any references to open issues with Pig and/or Hive? I’d like to add them to the know offenders list if there have been issues, and if needed add some workarounds in the preventor library.

  • unicoletti

    Thanks, just used it to fix a leak (Oracle driver registering NotificationBroadcasterSupport) in our grails app. #awesome