0

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?

Andy Guibert
  • 41,446
  • 8
  • 38
  • 61

1 Answers1

0

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.

biziclop
  • 48,926
  • 12
  • 77
  • 104
  • Where is the reference to the initially used classloader stored? In my examples I'm setting the ClassLoader to something else, and then trying to restore it – Andy Guibert Jan 18 '16 at 22:24
  • @aguibert In the OpenJDK implementation the `Thread` class simply has a field called [`contextClassLoader`](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/lang/Thread.java?av=f). – biziclop Jan 18 '16 at 22:26
  • the part I'm not clear on is how the failover mechanism works, when does that come into play? Obviously setting a field to null would never fail, so why does the javadoc describe behavior for it? If someone could describe why this mention of failover is in place, I would consider that a sufficient answer – Andy Guibert Jan 18 '16 at 22:32
  • @aguibert I think you may be misunderstanding the idiom "failing that". It simply means something like "if that isn't available", not actual failure of anything. – biziclop Jan 18 '16 at 22:54
  • Hi, I'm working on a legacy project and saw that in the Kafka configurations, the developer tried to set ContextClassLoader to null! by calling this `Thread.currentThread().setContextClassLoader(null);`. do you know why he did this? What are the situations in which we should set ContextClassLoader to null? – Rasool Ghafari Apr 17 '23 at 08:46