I have a class named UserHelper (source code included below) that puts a User object on the thread using the java.lang.InheritableThreadLocal API. The UserHelper class is part of a common Enterprise level JAR that is used by many applications throughout our company. The UserHelper class has been in use for the past 3+ years. Just this week one application reported a problem where they were receiving a java.lang.ClassCastException at line 20 of the UserHelper. The ClassCastException occurred attempting to cast from org.apache.log4j.Logger to com.xxx.yyy.zzz.User:
As you can see from the UserHelper.setUserOnThread method, only objects of type User can be set onto the thread by the helper class. The UserHelper.setUserOnThread method is invoked from a UserFilter class, which is an implementation of javax.servlet.Filter interface. The stack trace shown above is only a partial stack trace, the complete stack trace does show the UserFilter in the stack.
This is the first and only time a problem has been reported with the ThreadLocal implementation within our Enterprise APIs. Thus far the problem appears to be sporadic. It occurred on one JVM instance in the cluster, in which case they shutdown the JVM instance and restarted, then a day later it occurred on the second JVM instance in the cluster.
Our runtime environment is WebSphere Application Server v7.0.
I have no idea how our UserHelper implementation can be returning a Log4j Logger instance. Does anyone have an idea as to how such a thing could happen? Based upon my understanding of ThreadLocal implementations I believe our implementation is correct/appropriate. Do I have an improper ThreadLocal implementation?