Search code examples
javaclassloadercontextclassloader

Can Thread.setContextClassLoader set a different ClassLoader than returned by getCCL?


Background:

Recently I implemented a piece of code that would set the appropratie ClassLoader for a specific operation, and finally restore the original ClassLoader once the operation was completed.

For example:

ClassLoader originalCL = Thread.currentThread().getContextClassLoader();
try {
    Thread.currentThread().setContextClassLoader(specialCL);
    // do operation here that requires 'specialCL'
} finally {
    Thread.currentThread().setContextClassLoader(originalCL);
}

According to the getContextClassLoader() doc, a null being returned could mean two things. 1) The system CL or 2) if getting the sys CL failed, the bootstrap CL.

returns: the context ClassLoader for this Thread, or null indicating the system class loader (or, failing that, the bootstrap class loader)

According to the setContextClassLoader(Classloader cl) doc, if a null CL is provided then either the 1) the system CL or 2) if setting the sys CL failed, the bootstrap CL.

cl - the context ClassLoader for this Thread, or null indicating the system class loader (or, failing that, the bootstrap class loader)


Question:

Is it possible that using the above try-finally-restore programming model, I could end up with a different ClassLoader on the Thread than I originally started with?

For example:

// start out with System CL

ClassLoader original = getContextClassLoader(); // returns null

Thread.currentThread().setContextClassLoader(otherCL);

Thread.currentThread().setContextClassLoader(original); // i.e. set to null
// setCCL() tries to set System CL... fails 
// setCCL() tries to set Bootstrap CL... succeeds

The reverse of this could also be true where we start out with the Bootstrap CL and when we try to restore using setContextClassLoader(null) the System CL gets restored. Is either case possible?


Solution

  • No, when you set the context class loader to null, it is simply set to null. So it will continue using whatever class loader it had used initially.