Friday, April 29, 2011

Process of Class loading

Class loaders are hierarchical. Classes are introduced into the JVM as they are referenced by name in a class that is already running in the JVM. So how is the very first class loaded?

Bootstrap class loading
The very first class is specially loaded with the help of static main() method declared in your class. All the subsequently loaded classes are loaded by the classes, which are already loaded and running. A class loader creates a namespace. All JVMs include at least one class loader that is embedded within the JVM called the primordial (or bootstrap) class loader. It is somewhat special because the virtual machine assumes that it has access to a repository of trusted classes which can be run by the VM without verification.

When a new JVM instance is started , the bootstrap class loader is responsible for loading key java classes like java.lang.Object and other runtime code into memory. The runtime classes are packaged inside jre/lib/rt.jar file. We cannot find the details of the bootstrap class loader in the java language specification, since this is a native implementation. For this reason the behavior of the bootstrap class loader will differ across JVMs.Java can change its class storage model simply by changing the set of functions that implements the class loader.

Non-primordial class loaders
Now let’s look at non-primordial class loaders. The JVM has hooks in it to allow user defined class loaders to be used in place of primordial class loader.
ex : Bootstrap (primordial) Loads JDK internal classes, java.* packages. (as defined in the sun.boot.class.path system property, typically loads rt.jar and i18n.jar) and is the parent in the Class loaders hierarchy.
Next comes the Extensions (Loads jar files from JDK extensions directory (as defined in the java.ext.dirs system property – usually lib/ext directory of the JRE) and then System (Loads classes from system classpath (as defined by the java.class.path property, which is set by the CLASSPATH environment variable or –classpath or –cp command line options) ClassLoaders.

Classes loaded by Bootstrap class loader have no visibility into classes loaded by its descendants (ie Extensions and Systems class loaders).
The classes loaded by system class loader have visibility into classes loaded by its parents (ie Extensions and Bootstrap class loaders).
If there were any sibling class loaders they cannot see classes loaded by each other. They can only see the classes loaded by their parent class loader. For example Sibling1 class loader cannot see classes loaded by
Sibling2 class loader. Both Sibling1 and Sibling2 class loaders have visibilty into classes loaded by their parent class loaders (eg: System, Extensions, and Bootstrap)

Class loaders are hierarchical and use a delegation model when loading a class. Class loaders request their parent to load the class first before attempting to load it themselves. When a class loader loads a class, the child class loaders in the hierarchy will never reload the class again. Hence uniqueness is maintained. Classes loaded by a child class loader have visibility into classes loaded by its parents up the hierarchy but the reverse is not true
Note : Two objects loaded by different class loaders are never equal even if they carry the same values, which mean a class is uniquely identified in the context of the associated class loader. This applies to singletons too, where each class loader will have its own singleton.

At its simplest, a class loader creates a flat name space of class bodies that are referenced by a string name. The method definition is:
         Class r = loadClass(String className, boolean resolveIt);
The variable className contains a string that is understood by the class loader and is used to uniquely identify a class implementation. The variable resolveIt is a flag to tell the class loader that classes referenced by this class name should be resolved (that is, any referenced class should be loaded as well).
We can build our own ClassLoader by being a subclass of java.lang.ClassLoader. The only abstract method that must be implemented is loadClass().

Dynamic vs Static classloading

Class loading proceeds according to the following general algorithm:
  • Determine whether the class has been loaded before. If so, return the previously loaded class.
  • Consult the Primordial Class Loader to attempt to load the class from the CLASSPATH. This prevents external classes from spoofing trusted Java classes.
  • See whether the Class Loader is allowed to create the class being loaded. The Security Manager makes this decision. If not, throw a security exception.
  • Read the class file into an array of bytes. The way this happens differs according to particular class loaders. Some class loaders may load classes from a local database. Others may load classes across the network.
  • Construct a Class object and its methods from the class file.
  • Resolve classes immediately referenced by the class before it is used. These classes include classes used by static initializers of the class and any classes that the class extends.
  • Check the class file with the Verifier.

No comments:

Post a Comment