Java Reference
In-Depth Information
12.2.2
Using and abusing the thread context ClassLoader
The thread context
ClassLoader
is used in Java
EE
as a
Get out of Jail Free
card. The
thread context
ClassLoader
is set by various Java
EE
containers, such as an
EJB
con-
tainer or a servlet container, before calling into a managed object. This
ClassLoader
is the same one used by the application, and the same delegation hierarchy. In a Java
SE
environment, the thread context
ClassLoader
is initialized to be the same as the
classloader of the class that created the thread.
The thread context
ClassLoader
is used in Java for a specific purpose: when a
piece of code on one classloader needs to act on classes or resources visible to another
classloader.
PROPER USE OF THE THREAD CONTEXT CLASSLOADER
A well-behaved piece of code can use the thread context
ClassLoader
to access classes
or resources only visible to another classloader. One example would be a library or
component that lives inside a server runtime, or at
EAR
scope within a Java
EE
applica-
tion. This library will be visible to any module inside the rest of the application, but
crucially the module won't be visible to the library.
If one of the things the library needs to do when it's accessed is locate some config-
uration or instantiate one of the module's classes, then it's stuck. Because the class-
loader that loads the library is the parent of the classloader that can load the
configuration, visibility is only one-way. To get around problems like this, libraries can
use the thread context
ClassLoader
to find the necessary classes or resources. The
thread context
ClassLoader
will have been set by the server immediately before the
invocation of a servlet or
EJB
, making it available to any libraries called by the servlet
or
EJB
.
This approach may seem a little haphazard, but it's part of a number of Java
EE
specifications. For example, if a
JMS
resource adapter receives an
ObjectMessage
,
then it needs access to the class of the
Object
to instantiate it. As with a library loading
a configuration file, this is problematic. The
JMS
resource adapter is almost always
part of the Java
EE
server runtime, not part of the application. In this case the
JMS
resource adapter is required to use the thread context
ClassLoader
to find the appli-
cation class stored in the
ObjectMessage
.
Although there are good reasons for using the thread context
ClassLoader
, there
are also times when it's used somewhat inappropriately.
POOR USE OF THE THREAD CONTEXT CLASSLOADER
The thread context
ClassLoader
is extremely useful, but as we've mentioned before
it's seen as something of a
Get out of Jail Free
card. This is a problem, because it means
the thread context
ClassLoader
is extensively used in places that it wasn't originally
intended for. This problem is exacerbated by the fact that most people using the
thread context
ClassLoader
make assumptions about it that aren't guaranteed to be
true, particularly if you have an
OSG
i classloading model.
The biggest assumption that most people make about the thread context
Class-
Loader
is that it can load internal library and server implementation classes. This may