When you call Class.forName(className, initialize, classLoader)
you are asking the JVM to load a class using that custom class loader. If you don't specify a ClassLoader
-- for example just by calling Class.forName(className)
, then the JVM will use the ClassLoader
known as the "context ClassLoader" for the thread. Each thread has one of these, and your code can change the context classloader somewhat easily.
If you have some code that causes a class to be loaded -- something like this:
MyClass foo = new MyClass();
The MyClass
class will be loaded by the ClassLoader
if it's not already loaded. It's not possible to call a constructor and supply a ClassLoader
to load the class in case it's not already loaded. In this case, the thread's context ClassLoader
is user.
Furthermore, if you call some code that you don't control, there are many ways in which that code could cause other classes to be loaded, and since you have no control over that code, the thread's context ClassLoader
will also be used.
So, how do you set the thread's context ClassLoader
? Easy:
ClassLoader cl = Thread.currentThread().getContextClassLoader();
ClassLoader myClassLoader = ...; // You figure this out
try
{
Thread.currentThread().setContextClassLoader(myClassLoader);
// Do work that requires your ClassLoader to work
}
finally
{
// Always restore the previous CCL after work is done
Thread.currentThread().setContextClassLoader(cl);
}
Another thing you'll want to do it make sure that your custom ClassLoader
delegates any requests for class-loading to a parent ClassLoader
. That parent ClassLoader
should probably be the ClassLoader
that would naturally be used if you weren't trying to use your own: the thread's context ClassLoader
.
So, you probably want something like the following:
ClassLoader cl = Thread.currentThread().getContextClassLoader();
ClassLoader myClassLoader = new MyClassLoader(cl); // Try 'cl' before your custom class loading
try
{
Thread.currentThread().setContextClassLoader(myClassLoader);
// Do work that requires your ClassLoader to work
}
finally
{
// Always restore the previous CCL after work is done
Thread.currentThread().setContextClassLoader(cl);
}
You can find more information about ClassLoader
s, and, specifically the TCCL, in these few references: