Project: Tomcat
Bug 54497 RuntimeException in WebappClassLoader.checkThreadLocalMapForLeaks() causes LifecycleException
Reported: 2013-01-25 23:16:17 | Status: resolved fixed

Observed this when testing Tomcat trunk at r1438747, at WinXP 32-bit, JDK 7u11. (running TestWsWebSocketContainer with APR, Tomcat-Native 1.1.26 RC) There occurred an NPE in WebappClassLoader.checkThreadLocalMapForLeaks(). It was uncaught and caused LifecycleException and ultimately a failure to stop Tomcat. =============== In stderr: SEVERE: A child container failed during stop java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to stop component [StandardEngine[Tomcat].StandardHost[localhost].StandardContext[]] at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:252) at java.util.concurrent.FutureTask.get(FutureTask.java:111) at org.apache.catalina.core.ContainerBase.stopInternal(ContainerBase.java:974) at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232) at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1404) at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1393) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) at java.util.concurrent.FutureTask.run(FutureTask.java:166) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:722) Caused by: org.apache.catalina.LifecycleException: Failed to stop component [StandardEngine[Tomcat].StandardHost[localhost].StandardContext[]] at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:236) ... 7 more Caused by: org.apache.catalina.LifecycleException: Failed to stop component [WebappLoader[]] at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:236) at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5365) at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232) ... 7 more Caused by: java.lang.NullPointerException at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:54) at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36) at java.lang.reflect.Field.get(Field.java:372) at org.apache.catalina.loader.WebappClassLoader.checkThreadLocalMapForLeaks(WebappClassLoader.java:2247) at org.apache.catalina.loader.WebappClassLoader.checkThreadLocalsForLeaks(WebappClassLoader.java:2188) at org.apache.catalina.loader.WebappClassLoader.clearReferences(WebappClassLoader.java:1731) at org.apache.catalina.loader.WebappClassLoader.stop(WebappClassLoader.java:1641) at org.apache.catalina.loader.WebappLoader.stopInternal(WebappLoader.java:491) at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232) ... 9 more =============== In testcase: Testcase: testSmallTextBufferClientTextMessage took 2,328 sec Caused an ERROR Failed to stop component [StandardServer[-1]] org.apache.catalina.LifecycleException: Failed to stop component [StandardServer[-1]] at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:236) at org.apache.catalina.startup.Tomcat.stop(Tomcat.java:336) at org.apache.catalina.startup.TomcatBaseTest.tearDown(TomcatBaseTest.java:163) Caused by: org.apache.catalina.LifecycleException: Failed to stop component [StandardService[Tomcat]] at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:236) at org.apache.catalina.core.StandardServer.stopInternal(StandardServer.java:766) at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232) Caused by: org.apache.catalina.LifecycleException: Failed to stop component [StandardEngine[Tomcat]] at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:236) at org.apache.catalina.core.StandardService.stopInternal(StandardService.java:501) at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232) Caused by: org.apache.catalina.LifecycleException: A child container failed during stop at org.apache.catalina.core.ContainerBase.stopInternal(ContainerBase.java:981) at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232) =============== Thoughts: 1. We should catch throwables in those checkFor**Leaks methods. It should not cause a "failed to stop component" failure. 2. In that method there are many calls to "table[j]". The array member should be evaluated only once, so that it does not become null unexpectedly.

Files changed in fix:
java/org/apache/catalina/loader/WebappClassLoader.java