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: [email protected]
For additional commands, e-mail: [email protected]