You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Blair Zajac <bl...@orcaware.com> on 2010/11/23 03:19:13 UTC

clearThreadLocalMap and NullPointerException

With Tomcat 6.0.29 and Java 6u22, when I'm stopping Tomcat I'm getting 
the attached log, which at the end is a NullPointerException thrown from 
AbstractCollection#toString() which is called from clearThreadLocalMap().

java.lang.NullPointerException
	at java.util.AbstractCollection.toString(AbstractCollection.java:415)
	at 
org.apache.catalina.loader.WebappClassLoader.clearThreadLocalMap(WebappClassLoader.java:2379)
	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)

Unfortunately, I can't tell what the key or value is due to this.

The web application does a GC when it unloads ZeroC's Ice runtime to 
ensure that all objects that implement #finialize() are properly 
finalized, otherwise I get even more exceptions.  This is seen in Java's 
GC stats in the log.

Any suggestions in tracking this down?  Would a custom Tomcat build that 
gets each key and value in a try/catch block be useful?

Regards,
Blair

Re: clearThreadLocalMap and NullPointerException

Posted by Blair Zajac <bl...@orcaware.com>.
On Nov 24, 2010, at 12:41 AM, Mark Thomas wrote:

> On 24/11/2010 01:28, Blair Zajac wrote:
>> On Nov 23, 2010, at 4:49 PM, Blair Zajac wrote:
>>> On Nov 23, 2010, at 2:24 AM, Mark Thomas wrote:
>>>> Do let us know what the problem was when you find it.
>>> 
>>> Does JNA provide its own clean up methods that I could run at shutdown?  I haven't looked yet to see.
>> 
>> I found the cause, it's an issue with JNA, they should be providing a real iterator() implementation, not one that just returns null.  Not that they expected anyone to call toString() on it.
>> 
>> http://article.gmane.org/gmane.comp.java.jna.user/4347
>> 
>> I guess it's up to you if you want to handle a case like this.  I could see other projects not bothering to provide real implementations of things if they don't expect anything to go looking into their internals.
> 
> Thanks for getting back with details of the problem. I agree with you that there are likely to be other libraries doing similar things. I think the general handling now in place is the right way to go. Hopefully, the issues it highlights in third party libraries they will get reported and fixed.

JNA just committed a fix for this and with the Tomcat improvement, we're all good.

Thanks for the help!
Blair


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: clearThreadLocalMap and NullPointerException

Posted by Mark Thomas <ma...@apache.org>.
On 24/11/2010 01:28, Blair Zajac wrote:
> On Nov 23, 2010, at 4:49 PM, Blair Zajac wrote:
>> On Nov 23, 2010, at 2:24 AM, Mark Thomas wrote:
>>> Do let us know what the problem was when you find it.
>>
>> Does JNA provide its own clean up methods that I could run at shutdown?  I haven't looked yet to see.
> 
> I found the cause, it's an issue with JNA, they should be providing a real iterator() implementation, not one that just returns null.  Not that they expected anyone to call toString() on it.
> 
> http://article.gmane.org/gmane.comp.java.jna.user/4347
> 
> I guess it's up to you if you want to handle a case like this.  I could see other projects not bothering to provide real implementations of things if they don't expect anything to go looking into their internals.

Thanks for getting back with details of the problem. I agree with you that there are likely to be other libraries doing similar things. I think the general handling now in place is the right way to go. Hopefully, the issues it highlights in third party libraries they will get reported and fixed.

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: clearThreadLocalMap and NullPointerException

Posted by Blair Zajac <bl...@orcaware.com>.
On Nov 23, 2010, at 4:49 PM, Blair Zajac wrote:

> 
> 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.
> 
> Does JNA provide its own clean up methods that I could run at shutdown?  I haven't looked yet to see.

I found the cause, it's an issue with JNA, they should be providing a real iterator() implementation, not one that just returns null.  Not that they expected anyone to call toString() on it.

http://article.gmane.org/gmane.comp.java.jna.user/4347

I guess it's up to you if you want to handle a case like this.  I could see other projects not bothering to provide real implementations of things if they don't expect anything to go looking into their internals.

Blair


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: clearThreadLocalMap and NullPointerException

Posted by Blair Zajac <bl...@orcaware.com>.
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.Structure$2@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.Native$3@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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: clearThreadLocalMap and NullPointerException

Posted by Mark Thomas <ma...@apache.org>.
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.

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org