Java Reference
In-Depth Information
First, consider loadClass() . The initiating class loader is used to initiate the load
request. It may delegate through several class loaders before finding one that has
already loaded the class or can load it. The class loader that defines the class (by
converting its byte code into an actual class) is called the defining class loader . The
result of the load request is cached in the defining class loader in case anyone else
wants this class.
Now consider forName() . Although it behaves like loadClass() when looking for
new classes, it caches the result in both the defining and initiating class loaders. It
also consults the initiating loader cache before delegating any load request. With
loadClass() , the resulting class can depend on your context, perhaps according to
which module you're currently running in. But with forName() , you get the same re-
sult regardless of context. Because this extra caching may lead to unexpected results
in a dynamic environment such as OSGi, we strongly recommend you use load-
Class() instead of forName() .
In the last example, you found the client class loader by examining one of the argu-
ments passed into your method and used that to look up the client's Auditor class.
What if none of the method arguments relate to the client bundle? Perhaps you can
use a feature specifically introduced for application frameworks in Java 2: the Thread
Context Class Loader.
Following the Thread Context Class Loader
The Thread Context Class Loader ( TCCL ) is, as you may expect, a thread-specific class
loader. Each thread can have its own TCCL ; and, by default, a thread inherits the TCCL
of its parent. You can access the TCCL with a single line of Java code:
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
The TCCL is useful when you're writing code
that needs dynamic access to classes or
resources but must also run inside a number
of different containers such as OSG i. Instead
of adding a class-loader parameter to each
method call, you can instead use the previ-
ous code to access the current TCCL . All the
container needs to do is update the TCCL for
each thread as it enters and leaves the con-
tainer. When done properly, this approach
also supports nesting of containers, as shown
in figure 8.13.
You should use a try-catch-finally
block to guarantee that the correct TCCL is
restored even if an exception or error occurs
somewhere inside the container code:
Save old TCCL
Set new TCCL
Save old TCCL
Set new TCCL
Save old TCCL
Set new TCCL
Restore old TCCL
Restore old TCCL
Restore old TCCL
Figure 8.13 Using TCCL with nested containers
Search WWH ::

Custom Search