What is the reason for having 3 Class loaders in Java - java

Java has 3 class loaders:
BootStrap,
Extension and
System
and they have one role; loading classes from different packages.
But why does Java have 3 different class loaders instead of just one, since one class loader can load all the necessary classes?

The reason for having the three basic class loaders (Bootstrap, extension, system) is mostly security.
Prior to version 1.2 of the JVM, there was just one default class loader, which is what is currently called the "Bootstrap" class loader.
The way classes are loaded by class loaders is that each class loader first calls its parent, and if that parent doesn't find the requested class, the current one is looking for it itself.
A key concept is the fact that the JVM will not grant package access (the access that methods and fields have if you didn't specifically mention private, public or protected) unless the class that asks for this access comes from the same class loader that loaded the class it wishes to access.
So, suppose a user calls his class java.lang.MyClass. Theoretically, it could get package access to all the fields and methods in the java.lang package and change the way they work. The language itself doesn't prevent this. But the JVM will block this, because all the real java.lang classes were loaded by bootstrap class loader. Not the same loader = no access.
There are other security features built into the class loaders that make it hard to do certain types of hacking.
So why three class loaders? Because they represent three levels of trust. The classes that are most trusted are the core API classes. Next are installed extensions, and then classes that appear in the classpath, which means they are local to your machine.
For a more extended explanation, refer to Bill Venners's "Inside the Java Virtual Machine".

The main usage of class loaders is in application servers.
You want to be able to start Tomcat (for example). This already needs at least one classloader to run tomcat itself.
Then you want to be able to deploy an application into Tomcat. So Tomcat itself needs to load an analyze the classes of the application, which didn't even exist when Tomcat was started.
Then you want to be able todeploy another application in Tomcat. Maybe this second application uses a library that the first one also uses, but in a different version. So you want each app to have its own isolated class loader, otherwise the classes of app 2 might interfere badly with the classes from app 1.
Then you want to be able to undeploy one of the webapps. So its class loader must be destroyed and garbage-collected, to avoid a huge memory leak.
There are of course many other usages, but that's the one that is the most commonly used (in my experience).

Multiple class loaders are present to load multiple applications
simultaneously(One to load Server & Other to deploy in the server).
Each loader has a hierarchy to load only certain
classes to ensure security among them.

Related

Significance of class loader in loading resource bundle

I am having difficulty in understanding the significance of classLoader in ResourceBundle.getBundle(bundleName, locale, classLoader) API .
What could be the practical scenario where someone would want to provide custom loader for this API?
A Java application might have multiple class loaders. For example, a J2EE application running on Tomcat or Glassfish has multiple tiers of classloaders - some belonging to the J2EE server itself, some being specifically made for your webapp (otherwise your webapp would be able to access classes belonging to other webapps) and even custom classloaders that you might have instantiated yourself.
Standalone Java apps might also have multiple classloaders. For example, if your application supports plugins and each of these plugins is contained in its own JAR file (local or remote) then in order to load the plugin's classes at runtime you would have to create your own classloaders to do so.
Therefore, when you load a ResourceBundle you have to select the appropriate classloader to ensure that the resource is loaded from the correct source. Here's a simple example... imagine that your application contains a /version.properties file and your JVM also has a similar, yet different, /version.properties (e.g. IBM's Java has this properties file). Trying to load this resource file using the system's default classloader returns the version.properties that is included in the JVM and in order to load your own version of this file, you must use a custom classloader or one whose context is specific to your app.
There is an old but still very interesting explanation of how class loaders work and how hierarchies and loading contexts are useful in practice. For more info, check Internals of Java Class Loading.

Java EE and Java SE classloading

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.

How to use two incompartible classes with same full name?

A problem: My application uses two libraries which use incompatible versions of a third library. Does someone know any method for classes isolation?
I have heard about class loaders, but I do not understand, how they could help - if we will load one version of class, we cannot load another - class is already loaded?
I also thinking about Spring, but do not know if it provides such isolation.
ClassLoaders are basically the elements that gives meaning to classes in the JVM. They form a hierarchy for wich the root lies in the JVM and loads java classes. The ApplicationClassLoader is the first ClassLoader you have to consider, as it loads all the classes of your application.
When a class is loaded, all its references to other classes are resolved and theses classes are loaded. The JVM by default provides a system where classloaders ask their parent first to see if they have already loaded a class. If not, they search in their classpath
Two classes can be isolated if they live in 2 different classloader, and not in the app classloader. It's not difficult to do. You only have to create a classloader (like URLClassLoader) while specifying its parent and its classpath(the place where the bytecode is)
then, you tell him to load a class. It will ask its parent, and if the class is not loaded yet, it will search its classpath and load it. If you create another classloader attached to the same parent, the classes loaded by the first will never be seen by the seconds as they are siblings. And the second can loads a class with the same name without any problem
That's quite a good isolation
App Servers use another form of delegation to have a frank isolation between applications. they redefine a classloader extending, for example, URLClassLoader and reverse the delegation process by starting to search for classes in their classpath first, then ask to the parent
if we will load one version of class, we cannot load another - class
is already loaded?
Not true. The class loader is considered part of the class's identity. If it's loaded by a different classloader, it's considered a different class.
If at least one of the libraries is open source, and the library they depend on is open source, no need for messing about with classloaders. Just bulk rename all the packages in one of the versions of the library being depended on, making sure to also change all code which refers to those packages. Hey presto - no name clashes. This is what Sun actually did for the JDK, when they included Xerces and Xalan behind the scenes.

What exactly are class loaders in Java?

When a client says "Code should not have custom classloaders" in Java, what does that exactly mean? What can't I do?
A class loader is an object in Java responsible for finding binary representations of Java classes and loading them into the JVM. All JVMs begin with a boot class loader responsible for loading the user's initial class, along with some of the built-in types like Class and SecurityManager, but users can provide their own class loaders to find classes from other sources. For example, a custom class loader could generate its own classes by composing its own bytecode, or it could find classes from a networked source.
To comply with what your client is asking, you should not define your own class loader and should rely on the boot class loader to find all your classes. This is almost universally what's done in simple Java programs because the use cases for custom boot loaders are usually fairly complex and nuanced. You shouldn't need to worry about this restriction unless you specifically want to change the way that that JVM finds and loads classes.
Custom class loaders are usually used to dynamically generate code or to enhance existing classes.
For example some ORM implementations (JDO) use this to create code that handles translating Java objects to database tables. Other use is in transparent-clustering solutions (like Terracota) where objects are enhanced so that they automatically replicate themselves across the cluster.
This basically prevents you to dynamically generate and inject code into an existing application.
A class loader is an object that is responsible for loading classes. Whenever you instantiate a class using new the runtime system attempts load the class using one or more instances of the ClassLoader abstract class. You can define custom class loaders to load classes from the network, databases, other processes, or any conceivable data source.
So, if your client does not want you to use custom class loaders then be sure to never write a class that extends ClassLoader or any of it's derivatives. Please see the ClassLoader java API docs for more details.
A custom classloader would let you load classes from unconventional sources (from anywhere you can imagine, including out of nowhere, i.e. created on-the-fly). Since your client is saying giving that message, then classes can be loaded only from standard sources (e.g. filesystem, jar files, etc).

Why is the setContextClassLoader() method placed on Thread?

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()

Categories