What is the difference between?
Class.getClassLoader() and Thread.getContextClassLoader()?
From this thread:
Class.getClassLoader() returns the ClassLoader that loaded the class it is invoked on.
Thread.getContextClassLoader() returns the ClassLoader set as the context ClassLoader for the Thread it is invoked on, which can be different from the ClassLoader that loaded the Thread class itself if the Thread's setContextClassLoader(ClassLoader) method has been invoked.
This can be used to allow the object starting a thread to specify a ClassLoader that objects running in the thread should use, but the cooperation of some of those objects is required for that to work.
So if you are wondering why there are 3 API calls
Thread<instance>.getContextClassLoader()
Thread<instance>.getClassLoader()
Class<instance>.getClassLoader()
, you can find in this Find a way out of the ClassLoader maze an answer.
Why do thread context classloaders exist in the first place? They were introduced in J2SE without much fanfare. A certain lack of proper guidance and documentation from Sun Microsystems likely explains why many developers find them confusing.
In truth, context classloaders provide a back door around the classloading delegation scheme also introduced in J2SE. Normally, all classloaders in a JVM are organized in a hierarchy such that every classloader (except for the primordial classloader that bootstraps the entire JVM) has a single parent.
[...] To make matters worse, certain application servers set context and current classloaders to different ClassLoader instances that have the same classpaths and yet are not related as a delegation parent and child.
Class.getClassLoader() returns the classloader used to load that particular class.
Thread.getContextClassLoader() gets the ClassLoader set as context for that thread, which will be used to load needed classes.
This makes a difference for example in Tomcat. For java.lang.String the classloader will be the top level JVM classloader which won't have all classes on your classpath, but the Thread context classloader should do.
Related
As the javase 7 documentation describes
The ClassLoader class uses a delegation model to search for classes
and resources. Each instance of ClassLoader has an associated parent
class loader. When requested to find a class or resource, a
ClassLoader instance will delegate the search for the class or
resource to its parent class loader before attempting to find the
class or resource itself.
Why ClassLoader delegates the search for the class or resource to its parent? What is the purpose or the advantage of doing so?
There are several valid reasons for classloading delegation. I have listed them according to their priority(from my understanding):
Security
There are certain classes in Java which shouldn't be messed with. By having parent-first delegation model, JVM can be sure that it is executing only those classes and not the one loaded by custom classloaders.
Avoid duplicate class instances
Classloading is a costly operation as it requires reading data from external storage or network, parsing the bytecode, allocating memory and so on. So restricting the JVM to load the classes only once is one of the reasons. By forming classloader hierarchy with the parent-first rule will achieve this.
Class Scope
There are certain classes which are the core part of Java, like java.lang.*. These classes are part of Java language and will be used at almost all the places. Since a class is identified uniquely by its fully qualified name along with the classloader which loaded that class, it is important to have a single classloader to load such classes. Thus the bootstrap and extension classloader take care of this.
Also, by loading the classes and resources at top level gives them a broader scope than loading at the bottom of the classloader hierarchy.
The difference that I read on the Internet between Java EE and Java SE classloading is that
In Java SE, a classloader delegates the classloading to its parent
classloader and then tries to load the class itself
However, In Java EE, a classloader first tries to load the class itself and then
delegate the classloading of that class to its parent classloader.
Kindly validate my understanding.
Also, why is it designed like that in Java EE (Any advantages of keeping it like this.)
This is the link where I heard this [http://www.youtube.com/watch?v=t8sQw3pGJzM]
Alright then,
A common application has 3 standard classloaders:
Bootstrap Classloader
Extensions Classloader
System-Classpath Classloader
So far, so good. Now, this works for a single application running alone and free.
But what happens when you say J2EE? You have multiple applications running on the same place, so you have to figure out a way to prevent them from stumbling on each other. That's where these extra classloaders come into play.
Think about a server instance. There's a JBoss with two deployed EARs. What would happen if there were to be conflicting classes between applications? They're ok on their own particular context but as a whole they're inconsistent.
These extra classloaders are introduced in an application-wise way to ensure the isolation between them. Classloaders below System-Classpath Classloader recognize a class only if it is specified in the manifest file for one of its childs.
In J2SE, the three basic classloaders work in a parent-child relationship based on three principles:
Delegation: If a class is not loaded (cache), the request is delegated to its parent. This goes on until the top of the hierarchy (Bootstrap classloader) who loads basic J2SE related classes (i.e. Integer, ArrayList, amongst others). This is what you reference in your question: A classloader delegates the loading until the top of the hierarchy, then each classloader tries to load the class if its parent couldn't find it, until someone loads it. Otherwise: ClassNotFound.
Visibility: Classes loaded by a parent classloader are visible to its children, not the other way around.
Uniqueness: If a parent classloader loads a class, a children will never reload it.
In Java SE, a classloader delegates the classloading to its parent classloader and then tries to load the class itself.
True, due to the principles explained above.
There's no determined classloader structure in J2EE (a vendor has "poetic license" to implement it), but they kind of follow a hierarchy. In this case, the System-classpath classloader loads the main application: The server. The server libraries (its classes, more specifically) are available, then, to every application due to the visibility principle.
Down there, the applications have particular classloader structures, but as a whole they are different children of the System-classpath classloader. Each application loads its related and particular classes (both application and libraries).
The loading here is not propagated to the parents outside the application context. Why? because if the System-classpath classloader were to load the applications as usual, the class of every application would be visible to others due to the visibility principle, completely breaking the isolation between themselves. So:
However, In Java EE, a classloader first tries to load the class itself and then delegate the classloading of that class to its parent classloader.
This is partly true, but I'd rather limit this affirmation to the context of an application and leave out the Java related classes, that are indeed loaded by the top level classloaders.
Long story short: It's not a straightforward process but I wouldn't go as far as to say J2EE handles the classloading the opposite way around of J2SE.
I think Java EE class loading standard will help you on your way. As far as I know there is no mandated way of classloading for standard Java. For WebApps (WARs) however, it is specified that the classloading is parent-last.
When trying to solve this problem, I encountered some articles, etc. referring to "isolated" ClassLoaders. I was unable to find a definition for isolated classloader via Google search, so maybe the term is not widely-known jargon, and perhaps has a different meaning in different contexts.
Anyway, Maven's surefire plugin can use an isolated ClassLoader: http://maven.apache.org/plugins/maven-surefire-plugin/examples/class-loading.html
Also one of the answers below references an article explaining how to create an "isolated" ClassLoader.
Neither reference above gives a definition for an isolated ClassLoader; they seem to assume the reader knows what that means or can look it up. However, the second link does include a hint as to what it means by "isolated":
Bootstrapping lets you run your container without polluting the system classpath. This allows you to run your deployed applications with the unpolluted system classpath as its parent. You’ve achieved classloader isolation.
But I'm not quite clear on what is isolated from what and how from this paragraph or the rest of the article. I see that he's loading one version of a class w/o overriding / overwriting another version--maybe one classloader is isolated from another by being different instances w/o one being the parent of the other? I'm not sure.
I especially covet a Google or SO search link that contains a link clearly holding the answer. A direct link to an answer works too. :)
The author is using the term "isolation" basically to mean that the bootstrap classloader for the JVM (the "main" classloader) doesn't have any extra jars/classes in it (just one simple class which in turn sets up the child classloader(s)). The article isn't real obvious as to why this is "isolated" because it only sets up one child classloader. The "isolation" term becomes more obvious when you setup more than one child classloader. These children will be isolated from each other in that they won't share any classes (other than the core JRE classes). Thus, you can do things like have each child use a different version of the same jar.
Here's how to create an isolated classloader, you'd create one any time you want an unpolluted system classpath, useful for bootstrapping Java programs.
From my understanding from the article that you linked to that an isolated class loader is a class loader that is separate to the main system class loader. That is, classes loaded by the isolated class loader won't be available to every class in JRE (only the ones that the isolated class loader loaded itself [and any classes loaded by any child class loaders]).
This could be useful because two of your dependencies might require different versions of the same library to run. That is, your dependencies might expect to see different instantiations of the same class in the library. Thus giving them two separate isolated class loaders will allow them to load the classes they require and not interfere with each other.
By default classloaders form a tree with the system classloader at the root. New child classloaders will by default ask their parent first if it can load the class, and if not, load from their own sources.
The goal of an isolated classloader is to isolate yourself from the parent classloaders by checking your own sources FIRST, then your parent SECOND, so reversing the order. This allows you to create a new classloading context where you control the first place to look. You still want to fallback to the parent chain so you can load things like the jdk etc.
You also need to take care that the isolated classloader return instances of interfaces defined in the parent classloader, or else you will run into LinkageErrors or other issues.
Here's an article I wrote in 2006, but it's still fairly relevant (it's incomplete with respect to resource loading and the apis have changed a bit over the years):
http://tech.puredanger.com/2006/11/09/classloader/
Why is the setContextClassLoader() method placed on Thread?
What different thread have different classloaders?
The question is what if I extended a ClassLoader, loaded there some new classes. to the my custom classloader.
Now , I want it to be the context classloader , so I call the method Thread.currentThread().setContextClassLoader(loader).
Are these new classes awailable only in the context of the current thread ? Or how does it work?
Thanks
The Context class loader is the class loader that the thread will use to find classes. You primarily care about this when you are writing an application server or something similar. The idea is that you can start a thread from a class loaded in the application server's class loader, and yet pass it a child class loader that handles loading the classes of the deployed application.
The thread context class loader is a little bit of a hack.
When you load a class with reflection, you use either an explicit class loader or the one of the immediate calling class. When you link to a class using normal Java code, then class requesting the linking is used as the source for the loader.
Thread.setContextClassLoader is used to set the class loader for Thread.getContextClassLoader. This is used by random APIs (notably through ServiceLoader) to pick up classes through reflection so that you can change implementation. Having implementations change out from under your code depending upon which thread it is running on at a crucial moment is a bad idea.
Thread.setContextClassLoaderis used to set contextClassLoader, if not set manually, it will set to systemClassLoader which is Launcher.AppClassLoader ,this can be proved by checking the source code of Launcher.
Then what is the use of contextClassLoader?
contextClassLoader provides a back door around the classloading delegation scheme.
Then this question becomes why do we need this back door?
From the JavaWorld article Find a way out of the ClassLoader maze
Take JNDI for instance: its guts are implemented by bootstrap classes in rt.jar (starting with J2SE 1.3), but these core JNDI classes may load JNDI providers implemented by independent vendors and potentially deployed in the application's -classpath. This scenario calls for a parent classloader (the primordial one in this case) to load a class visible to one of its child classloaders (the system one, for example). Normal J2SE delegation does not work, and the workaround is to make the core JNDI classes use thread context loaders, thus effectively "tunneling" through the classloader hierarchy in the direction opposite to the proper delegation.
Java class loaders can be classified into below categories
1) Bootstrap Class Loader
Load classes from JAVA_HOME/jre/lib/rt.jar
2) Extensions Class Loader<
Load classes from JAVA_HOME/jre/lib/ext
3) System Class Loader
Classpath of the application
We can create own class loader and specify own location from which classes can be loaded , that is refer to ContextClassLoader
Hope that gives idea upon why we need to use setContextClassLoader()
What is the difference between a thread's context class loader and a normal class loader?
That is, if Thread.currentThread().getContextClassLoader() and getClass().getClassLoader() return different class loader objects, which one will be used?
This does not answer the original question, but as the question is highly ranked and linked for any ContextClassLoader query, I think it is important to answer the related question of when the context class loader should be used. Short answer: never use the context class loader! But set it to getClass().getClassLoader() when you have to call a method that is missing a ClassLoader parameter.
When code from one class asks to load another class, the correct class loader to use is the same class loader as the caller class (i.e., getClass().getClassLoader()). This is the way things work 99.9% of the time because this is what the JVM does itself the first time you construct an instance of a new class, invoke a static method, or access a static field.
When you want to create a class using reflection (such as when deserializing or loading a configurable named class), the library that does the reflection should always ask the application which class loader to use, by receiving the ClassLoader as a parameter from the application. The application (which knows all the classes that need constructing) should pass it getClass().getClassLoader().
Any other way to obtain a class loader is incorrect. If a library uses hacks such as Thread.getContextClassLoader(), sun.misc.VM.latestUserDefinedLoader(), or sun.reflect.Reflection.getCallerClass() it is a bug caused by a deficiency in the API. Basically, Thread.getContextClassLoader() exists only because whoever designed the ObjectInputStream API forgot to accept the ClassLoader as a parameter, and this mistake has haunted the Java community to this day.
That said, many many JDK classes use one of a few hacks to guess some class loader to use. Some use the ContextClassLoader (which fails when you run different apps on a shared thread pool, or when you leave the ContextClassLoader null), some walk the stack (which fails when the direct caller of the class is itself a library), some use the system class loader (which is fine, as long as it is documented to only use classes in the CLASSPATH) or bootstrap class loader, and some use an unpredictable combination of the above techniques (which only makes things more confusing). This has resulted in much weeping and gnashing of teeth.
When using such an API, first, try to find an overload of the method that accepts the class loader as a parameter. If there is no sensible method, then try setting the ContextClassLoader before the API call (and resetting it afterwards):
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
// call some API that uses reflection without taking ClassLoader param
} finally {
Thread.currentThread().setContextClassLoader(originalClassLoader);
}
Each class will use its own classloader to load other classes. So if ClassA.class references ClassB.class then ClassB needs to be on the classpath of the classloader of ClassA, or its parents.
The thread context classloader is the current classloader for the current thread. An object can be created from a class in ClassLoaderC and then passed to a thread owned by ClassLoaderD. In this case the object needs to use Thread.currentThread().getContextClassLoader() directly if it wants to load resources that are not available on its own classloader.
There is an article on infoworld.com that explains the difference
=> Which ClassLoader should you use
(1)
Thread context classloaders provide a
back door around the classloading
delegation scheme.
Take JNDI for instance: its guts are
implemented by bootstrap classes in
rt.jar (starting with J2SE 1.3), but
these core JNDI classes may load JNDI
providers implemented by independent
vendors and potentially deployed in
the application's -classpath. This
scenario calls for a parent
classloader (the primordial one in
this case) to load a class visible to
one of its child classloaders (the
system one, for example). Normal J2SE
delegation does not work, and the
workaround is to make the core JNDI
classes use thread context loaders,
thus effectively "tunneling" through
the classloader hierarchy in the
direction opposite to the proper
delegation.
(2) from the same source:
This confusion will probably stay with
Java for some time. Take any J2SE API
with dynamic resource loading of any
kind and try to guess which loading
strategy it uses. Here is a sampling:
JNDI uses context classloaders
Class.getResource() and Class.forName() use the current classloader
JAXP uses context classloaders (as of J2SE 1.4)
java.util.ResourceBundle uses the caller's current classloader
URL protocol handlers specified via java.protocol.handler.pkgs system property are looked up in the bootstrap and system classloaders only
Java Serialization API uses the caller's current classloader by default
Adding to #David Roussel answer, classes may be loaded by multiple class loaders.
Lets understand how class loader works.
From javin paul blog in javarevisited :
ClassLoader follows three principles.
Delegation principle
A class is loaded in Java, when its needed. Suppose you have an application specific class called Abc.class, first request of loading this class will come to Application ClassLoader which will delegate to its parent Extension ClassLoader which further delegates to Primordial or Bootstrap class loader
Bootstrap ClassLoader is responsible for loading standard JDK class files from rt.jar and it is parent of all class loaders in Java. Bootstrap class loader don't have any parents.
Extension ClassLoader delegates class loading request to its parent, Bootstrap and if unsuccessful, loads class form jre/lib/ext directory or any other directory pointed by java.ext.dirs system property
System or Application class loader and it is responsible for loading application specific classes from CLASSPATH environment variable, -classpath or -cp command line option, Class-Path attribute of Manifest file inside JAR.
Application class loader is a child of Extension ClassLoader and its implemented by sun.misc.Launcher$AppClassLoader class.
NOTE: Except Bootstrap class loader, which is implemented in native language mostly in C, all Java class loaders are implemented using java.lang.ClassLoader.
Visibility Principle
According to visibility principle, Child ClassLoader can see class loaded by Parent ClassLoader but vice-versa is not true.
Uniqueness Principle
According to this principle a class loaded by Parent should not be loaded by Child ClassLoader again