What Is a Java Classloader

What is a Java ClassLoader?

Taken from this nice tutorial from Sun:

Motivation

Applications written in statically compiled programming languages, such as C and C++, are compiled into native, machine-specific instructions and saved as an executable file. The process of combining the code into an executable native code is called linking - the merging of separately compiled code with shared library code to create an executable application. This is different in dynamically compiled programming languages such as Java. In Java, the .class files generated by the Java compiler remain as-is until loaded into the Java Virtual Machine (JVM) -- in other words, the linking process is performed by the JVM at runtime. Classes are loaded into the JVM on an 'as needed' basis. And when a loaded class depends on another class, then that class is loaded as well.

When a Java application is launched, the first class to run (or the entry point into the application) is the one with public static void method called main(). This class usually has references to other classes, and all attempts to load the referenced classes are carried out by the class loader.

To get a feeling of this recursive class loading as well as the class loading idea in general, consider the following simple class:

public class HelloApp {
public static void main(String argv[]) {
System.out.println("Aloha! Hello and Bye");
}
}

If you run this class specifying the -verbose:class command-line option, so that it prints what classes are being loaded, you will get an output that looks as follows. Note that this is just a partial output since the list is too long to show here.

prmpt>java -verbose:class HelloApp

[Opened C:\Program Files\Java\jre1.5.0\lib\rt.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jsse.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jce.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\charsets.jar]
[Loaded java.lang.Object from shared objects file]
[Loaded java.io.Serializable from shared objects file]
[Loaded java.lang.Comparable from shared objects file]
[Loaded java.lang.CharSequence from shared objects file]
[Loaded java.lang.String from shared objects file]
[Loaded java.lang.reflect.GenericDeclaration from shared objects file]
[Loaded java.lang.reflect.Type from shared objects file]
[Loaded java.lang.reflect.AnnotatedElement from shared objects file]
[Loaded java.lang.Class from shared objects file]
[Loaded java.lang.Cloneable from shared objects file]
[Loaded java.lang.ClassLoader from shared objects file]
[Loaded java.lang.System from shared objects file]
[Loaded java.lang.Throwable from shared objects file]
.
.
.
[Loaded java.security.BasicPermissionCollection from shared objects file]
[Loaded java.security.Principal from shared objects file]
[Loaded java.security.cert.Certificate from shared objects file]
[Loaded HelloApp from file:/C:/classes/]
Aloha! Hello and Bye
[Loaded java.lang.Shutdown from shared objects file]
[Loaded java.lang.Shutdown$Lock from shared objects file]

As you can see, the Java runtime classes required by the application class (HelloApp) are loaded first.

Class Loaders in the Java 2 Platform

The Java programming language keeps evolving to make the life of applications developers easier everyday. This is done by providing APIs that simplify your life by allowing you to concentrate on business logic rather than implementation details of fundamental mechanisms. This is evident by the recent change of J2SE 1.5 to J2SE 5.0 in order to reflect the maturity of the Java platform.

As of JDK 1.2, a bootstrap class loader that is built into the JVM is responsible for loading the classes of the Java runtime. This class loader only loads classes that are found in the boot classpath, and since these are trusted classes, the validation process is not performed as for untrusted classes. In addition to the bootstrap class loader, the JVM has an extension class loader responsible for loading classes from standard extension APIs, and a system class loader that loads classes from a general class path as well as your application classes.

Since there is more than one class loader, they are represented in a tree whose root is the bootstrap class loader. Each class loader has a reference to its parent class loader. When a class loader is asked to load a class, it consults its parent class loader before attempting to load the item itself. The parent in turn consults its parent, and so on. So it is only after all the ancestor class loaders cannot find the class that the current class loader gets involved. In other words, a delegation model is used.

The java.lang.ClassLoader Class

The java.lang.ClassLoader is an abstract class that can be subclassed by applications that need to extend the manner in which the JVM dynamically loads classes. Constructors in java.lang.ClassLoader (and its subclasses) allow you to specify a parent when you instantiate a new class loader. If you don't explicitly specify a parent, the virtual machine's system class loader will be assigned as the default parent. In other words, the ClassLoader class uses a delegation model to search for classes and resources. Therefore, each instance of ClassLoader has an associated parent class loader, so that when requested to find a class or resources, the task is delegated to its parent class loader before attempting to find the class or resource itself. The loadClass() method of the ClassLoader performs the following tasks, in order, when called to load a class:

If a class has already been loaded, it returns it.
Otherwise, it delegates the search for the new class to the parent class loader.
If the parent class loader doesn't find the class, loadClass() calls the method findClass() to find and load the class.
The finalClass() method searches for the class in the current class loader if the class wasn't found by the parent class loader.


There's more in the original article, which also shows you how to implement your own network class loaders, which answers your question as to why (and how). See also the API docs.

classloader in java is a class itself then who will load the classloader class?

The term “System class loader” is a misnomer. As you stated correctly, it’s responsible for loading the classes from locations of the class path, which are the application classes.

As of Java 8, both, AppClassLoader and ExtClassLoader, are subclasses of java.net.URLClassLoader, which is a subclass of java.security.SecureClassLoader, which is a subclass of java.lang.ClassLoader. All of these classes are loaded by the Bootstrap loader, solving the chicken-and-egg problem.

Each runtime class has a defining class loader. For those classes defined by the Bootstrap loader during startup, the defining class loader is the Bootstrap loader. When the JVM initialization is completed and an attempt to start an application is made, the Application class loader (aka System class loader) will be queried for the main class. The Application class loader will follow the standard delegation model querying the parent first, likewise does the Extension class loader and whichever class loader will create the class will be the class’ defining class loader.

Now, when resolving a class referenced by another class or when Class.forName(String) is invoked, the defining loader of the class containing the reference will be used to resolve the class. So when the Application class loader has loaded your class myapp.foo.Bar and it contains a reference to javax.swing.JButton, its defining class loader, i.e. the Application class loader, will be queried for that class, follow the delegation model to end up with a javax.swing.JButton defined by the Bootstrap loader. So class references within javax.swing.JButton are resolved only through the Bootstrap loader, which implies that javax.swing.JButton can not contain a reference to your myapp.foo.Bar class, as it is not in scope.

So, the JVM does not always starts with “System class loader” for loading a class, but only for resolving class references of classes defined by it (or a child loader) or when being queried explicitly, like when resolving the main class.

There are 3rd party class loaders not strictly following the parent delegation model, but regardless of how and to which loader they delegate, there will be a defining loader for each class (the one returned by getClassLoader()), which will be the one used for resolving references within the class. The JVM ensures that identical symbolic names within one class always resolve to the same runtime class, regardless of how the particular class loader implements lookups.

Note that in Java 9, the Extension class loader has been replaced by the Platform class loader. This class loader may deviate from the simple parent delegation, i.e. it might delegate to the Application class loader for loading application provided modules that supersede a platform provided module. Also, the builtin class loaders are not subclasses of URLClassLoader anymore.

Why is ClassLoader's cache checked in ascending sequence?

ClassLoader in Java works on three principle: delegation, visibility and uniqueness. Delegation principle forward request of class loading to parent class loader and only loads the class, if parent is not able to find or load class. Visibility principle allows child class loader to see all the classes loaded by parent ClassLoader, but parent class loader can not see classes loaded by child. Uniqueness principle allows to load a class exactly once, which is basically achieved by delegation and ensures that child ClassLoader doesn't reload the class already loaded by parent.

In other words as described here:

The class loaders in Java are organized in a tree. By request a class
loader determines if the class has already been loaded in the past,
looking up in its own cache. If the class is present in the cache the
CL returns the class, if not, it delegates the request to the parent.
If the parent is not set (is Null) or can not load the class and
throws a ClassNotFoundException the classloader tries to load the
class itself and searches its own path for the class file. If the
class can be loaded it is returned, otherwise a ClassNotFoundException
is thrown. The cache lookup goes on recursively from child to
parent, until the tree root is reached or a class is found in cache.

If the root is reached the class loaders try to load the class and
unfold the recursion from parent to child. Summarizing that we have
following order:

  • Cache

    • Parent
    • Self

This mechanism ensures that classes tending to be loaded by class loaders nearest to the root.

What is user-defined classloader?

What is user-defined classloader?

A user-defined classloader is a class (that is not provided by the standard Java libraries or 3rd-party libraries) that extends java.lang.Classloader or a subclass.

Does programmer writes user-defined classloader?

Yes.

how it works in jvm

Just like any other classloader. More specifically, to load a class, it loads the classfile into a byte[] and then calls the defineClass method implemented by the ClassLoader class. Other things may entail delegating to a parent classloader.

and why it is required?

It would be required if you need your classloader to behave differently to a normal classloader. For example, you might want to transform the bytecodes, or load them from a place that the standard implementations cannot cope with. Or you may want to implement resource loading differently to the normal pattern.

Please try to explain in a easy to understand way so I can exactly understand that what it is.

I suggest you read this IBM tutorial on classloaders: http://www.ibm.com/developerworks/java/tutorials/j-classloader/j-classloader.html It is designed to be easy to understand, and includes a worked example of a custom classloader. (It is a bit old, but that shouldn't matter.)

Alternatively, there are lots of alternatives ... as Google will tell you.

And if you just want to understand classloaders in general, read: What is a Java ClassLoader?

Is reflection is for classloader?

Nothing in this cited text allows the conclusion that Reflection is “for classloaders”.

The text ends with “… and from JDK 1.1, developers can analyze these classes through reflection” which is an additional information that stands for itself. The fact that the text talked about class loaders before, has no relevance here.

Mentioning the version number when it boils down to “practically since the beginning”, suggests that this is a rather old text. This explains the part

Therefore, the classloader should be able to obtain the necessary information when loading a class and check whether the class is correct.

Class loaders don’t do this at all. But in Java 1.0 and partly in Java 1.1, class loaders were indeed deemed responsible for linking and verification tasks. This has been cleaned up with JDK 1.2, also known as Java 2. Since then, the class loader’s responsibility is restricted to locating the necessary resource and loading it into a byte array, to be passed to the JVM. Linking and Verification is the JVM’s job, which implies that it will also protect itself against potentially broken class loaders.

Since the class loader’s job is just reading files, sockets, or other resources into byte arrays and passing them to the JVM, they don’t have any need for Reflection APIs on their own.

What is the use of Custom Class Loader

Custom class loaders are useful in larger architectures consisting of several module/applications. Here are the advantages of the custom class loader:

  • Provides Modular architecture Allows to define multiple class loader allowing modular architecture.
  • Avoiding conflicts Clearly defines the scope of the class to within the class loader.
  • Support Versioning Supports different versions of class within same VM for different modules.
  • Better Memory Management Unused modules can be removed which unloads the classes used by that module, which cleans up memory.
  • Load classes from anywhere Classes can be loaded from anywhere, for ex, Database, Networks, or even define it on the fly.
  • Add resources or classes dynamically All the above features allows you add classes or resources dynamically.
  • Runtime Reloading Modified Classes Allows you to reload a class or classes runtime by creating a child class loader to the actual class loader, which contains the modified classes.


Related Topics



Leave a reply



Submit