On Nov 23, 2010, at 2:24 AM, Mark Thomas wrote: > On 23/11/2010 02:19, Blair Zajac wrote: > >> Any suggestions in tracking this down? Would a custom Tomcat build that >> gets each key and value in a try/catch block be useful? > > Almost certainly. As far as I can tell there is a collections object in > a thread local that is non-null yet returns null for a call to > iterator(). That seems wrong to me. > > The root cause could be a bug in the collection class or it might be a > side-effect of multiple threads accessing a non-thread-safe collection. > > Putting the value.toString() calls inside try-catches should make it > more robust. I'll do that for 7.0.x and propose it for 6.0.x. > > Do let us know what the problem was when you find it.
I got the type of object by logging the class of the object, it's a com.sun.jna.Structure$2.StructureSet. I'm using JNA 3.2.7 in my app. Nov 23, 2010 4:42:51 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap SEVERE: Calling toString on a com.sun.jna.Structure$2.StructureSet threw a NullPointerException. java.lang.NullPointerException at java.util.AbstractCollection.toString(AbstractCollection.java:415) at org.apache.catalina.loader.WebappClassLoader.clearThreadLocalMap(WebappClassLoader.java:2380) at org.apache.catalina.loader.WebappClassLoader.clearReferencesThreadLocals(WebappClassLoader.java:2304) at org.apache.catalina.loader.WebappClassLoader.clearReferences(WebappClassLoader.java:1886) at org.apache.catalina.loader.WebappClassLoader.stop(WebappClassLoader.java:1798) at org.apache.catalina.loader.WebappLoader.stop(WebappLoader.java:738) at org.apache.catalina.core.StandardContext.stop(StandardContext.java:4812) at org.apache.catalina.core.ContainerBase.removeChild(ContainerBase.java:924) at org.apache.catalina.startup.HostConfig.undeployApps(HostConfig.java:1319) at org.apache.catalina.startup.HostConfig.stop(HostConfig.java:1290) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:323) at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119) at org.apache.catalina.core.ContainerBase.stop(ContainerBase.java:1086) at org.apache.catalina.core.ContainerBase.stop(ContainerBase.java:1098) at org.apache.catalina.core.StandardEngine.stop(StandardEngine.java:450) at org.apache.catalina.core.StandardService.stop(StandardService.java:587) at org.apache.catalina.core.StandardServer.stop(StandardServer.java:744) at org.apache.catalina.startup.Catalina.stop(Catalina.java:648) at org.apache.catalina.startup.Catalina.start(Catalina.java:615) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414) Nov 23, 2010 4:42:51 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap SEVERE: The web application [/foobar] created a ThreadLocal with key of type [com.sun.jna.Structure$2] (value [com.sun.jna.structur...@2e4f7bc2]) and a value of type [com.sun.jna.Structure$2.StructureSet] (value [null]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak. Nov 23, 2010 4:42:51 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap SEVERE: The web application [/foobar] created a ThreadLocal with key of type [com.sun.jna.Native$3] (value [com.sun.jna.nativ...@6446154e]) and a value of type [java.lang.Integer] (value [2]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak. Does JNA provide its own clean up methods that I could run at shutdown? I haven't looked yet to see. BTW, there's code in this section: if (value != null) { args[3] = value.getClass().getCanonicalName(); args[4] = value.toString(); } if (value == null) { if (log.isDebugEnabled()) { log.debug(sm.getString( "webappClassLoader.clearThreadLocalDebug", args)); if (clearReferencesThreadLocals) { log.debug(sm.getString( "webappClassLoader.clearThreadLocalDebugClear")); } } } else { log.error(sm.getString( "webappClassLoader.clearThreadLocal", args)); if (clearReferencesThreadLocals) { log.info(sm.getString( "webappClassLoader.clearThreadLocalClear")); } } The code in the first block could be moved into the else block, removing an extra test. Regards, Blair --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org