Wednesday 28 May 2014

Java Class Loading Mechanism

Java Class Loading Mechanism



Class loading is one of the most powerful mechanisms provided by the Java language specification.

Whenever we compile any Java file, the compiler will embed a public, static, final field named class, of the type java.lang.Class, in the resultant byte code. Since this field is static, we can access this field using class name like this:
                  
   Java.lang.Class kClass = MyClass.class;

When the run time environment needs to load a new class for an application, it looks for the class in the following locations, in order:

1.  Bootstrap classes:  the runtime classes in rt.jar, internationalization classes in                      i18n.jar, and   others. 

2.  Installed extensions :  classes in JAR files in the lib/ext directory of the JRE

3. The class path : classes, including classes in JAR files, on paths specified by the system          property java.class.path

The precedence list tells you, for example, that the class path is searched only if a class to be loaded hasn't been found among the classes in rt.jar, i18n.jar or the installed extensions.

The class in java is loaded by some class loader instance. How class loader works? Once a class is loaded in JVM, the same class will not be loaded again. How?

In Java, a class is identified by its fully qualified class name. The fully qualified class name consists of the package name and the class name. But in JVM, a class is uniquely identified using fully qualified class name along with the instance of the ClassLoader that loaded the class in JVM.
Thus, if a class named Cl in the package Pkg is loaded by an instance kl1 of the class loader KlassLoader, the class instance (java.lang.Class instance inserted by compiler) of C1, i.e. C1.class is keyed in the JVM as (Cl, Pkg, kl1). So what if multiple instances (Kl1, Kl2, Kl3) of class Loader say KlassLoader, loads the same class? How many class loader instances do we have in a JVM? This is explained below.

Class Loaders

In a JVM, each and every class is loaded by some instance of java.lang.ClassLoader class. The ClassLoader is part of java.lang package and developers are free to subclass java.lang.ClassLoader class and add their own functionality of class loading. When the JVM is started, three class loaders are used:

 1.  Bootstrap class Loader

      Whenever a JVM is started by typing command in command prompt like “java MyClass” (MyClass is an example class) or whenever class is run through any IDE, the “Bootstrap class loader” is responsible for loading the key classes like “java.lang.Object” and other runtime code (java.lang.String, java.lang.* pkg etc)  packaged in to jre/lib/rt.jar, internationalization classes in i18n.jar into memory first.  rt.jar contains packages like :

java.lang.*,
java.math.*,
java.io.*,
java.sql.*,
java.nio.*,
java.awt.*,
java.rmi.*,
javax.annotation.*,
javax.lang. model.*
javax.rmi.*
etc.

Bootstrap class loader is a native implementation and thus the behavior of the bootstrap class loader will also vary across JVMs. 

If we try to get the class loader of the core java run time class like java.lang.String, we will get null, like this:   log (java.lang.String.class.getClassLoader());


2.Extension class loader:


Extension libraries provide features beyond core Java run time code. The extension mechanism provides a standard, scalable way to make custom APIs available to all applications running on the Java platform.

An extension library acts as “add-on” modules to the Java platform or Java core API.  The extension mechanism enables the run time environment to find and load extension classes without the extension classes having to be named on the class path. These extension libraries are normally placed in jre/lib/ext folder.

Developers can write their own extension libraries and can place these libraries under jre/lib/ext folder and these libraries are loaded same as java runtime classes without using class path.  Since this mechanism extends the platform's core API, its use should be judiciously applied.
 

                                                                      

Thus extension libraries provide features beyond the core Java runtime code. A developer can add his or her own application .jar files or whatever libraries he or she might need to add to the classpath to this extension directory so that they will be loaded by the extension class loader.

Thus extension class loader (ExtClassLoader class) is responsible for loading all .jar files under ext (most probably jre/lib/ext) folder.

3. Application Class Loader

The third and most important class loader from the developer perspective is the AppClassLoader. The application class loader is responsible for loading all of the classes kept in the class path corresponding to the java.class.path system property.

Above three class loaders are used mostly.  There are few more class loaders in JDL like:
  java.net.URLClassLoader
  java.security.SecureClassLoader
  java.rmi.server.RMIClassLoader
  sun.applet.AppletClassLoader


How class Loaders work:

Below points are very important for the correct working of any class loader written by developers:-

1. All class loaders except bootstrap class loader have a parent class loader.
2. All class loaders are of the type java.lang.ClassLoader.
3. Class loaders should (practically: must) delegate the loading of a class to the parent, but a custom class loader can define for itself when it should do so.
4. A class is defined by its class type and the class loader that has actually loaded the class.
5. A class is only loaded once and then cached in the class loader to ensure that the byte code cannot change.

The parent class loader for any class loader is the class loader instance that loaded the class loader. (Remember, a class loader is itself a class). The most important aspect is to correctly set the parent class loader. See below code snippet to set the parent class loader in a developer written class loader.

public class MyClassLoader extends ClassLoader{

    public MyClassLoader(){
        super(MyClassLoader.class.getClassLoader());
    }

}

A class is requested out of class loader using the loadClass() method of java.lang.ClassLoader class. Look below code snippet of loadClass() method.

protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
{
    // First check if the class is already loaded
    Class c = findLoadedClass(name);
    if (c == null) {
        try {
            if (parent != null) {
                c = parent.loadClass(name, false);
            } else {
                c = findBootstrapClass0(name);
            }
        } catch (ClassNotFoundException e) {
            // If still not found, then invoke
            // findClass to find the class.
            c = findClass(name);
        }
    }
    if (resolve) {
            resolveClass(c);
    }
    return c;
}

  1. This method first checks if class is already loaded using findLoadedClass() method.

22.  If class loader instance that invoked this method can’t find the class, and if parent (parent class loader) is set correctly, it would ask the parent class loader first to load the class.

33.  If the parent cannot find it (which again means that its parent also cannot find the class, and so on), and if the findBootstrapClass0() method also fails, the findClass() method is invoked. The default implementation of findClass() will throw ClassNotFoundException  as shown below:

protected Class<?> findClass(String name)throws ClassNotFoundException
{
        throw new ClassNotFoundException(name);
      } 

4. Developers are expected to implement findClass() method when they subclass  java.lang.ClassLoader to make custom class loader. Inside the findClass() method, the class  loader needs to fetch the byte codes from arbitrary source. The source can be the file  system,database, network URL etc. 

   5.  Once the byte code is retrieved, the findClass() method should call the defineClass() method     and runtime is very particular about which class loader instance calls this method.

Note: If two class loader instances define the byte codes from same or different sources, the defined classes are different.  


Below diagram explains the class loading mechanism using custom class loaders, how many class loader instances we have in JVM and what would be the impact of multiple instances of class loaders.    

      

                                               

 
Explanation:--     

1. Main class is MyMainClass.Java

2. As explained earlier, MyMainClass.class will be loaded by AppClassLoader as                           AppClassLoader is responsible for loading classes from class path.

3. MyMainClass creates instances of two class loaders, CustomClassLoader1 and CustomClassLoader2, which are capable of finding the byte code of 4th class named Target.class from some source say a network path, which means Target.Java is not in the classpath and hence is not loaded by AppClassLoader.

4.   In this scenario, MyMainClass asks the custom class loaders to load the target class, Target will be loaded and Target.class will be defined independently by both CustomClassLoader1 and CustomClassLoader2 instances and this will lead to serious implications in Java like if Target class has some static initialization code and if we want this code to be executed only once in JVM, but in current scenario the static code will be executed twice in the JVM: once each when class is loaded separately by both custom class loaders CustomClassLoader1 and CustomClassLoader2 .

5.  If the Target class is instantiated in both the CustomClassLoaders to have instances target1 and target2 as shown in above figure, then target1 and target2 are not type compatible. JVM can’t  execute the below code snippet:

Target target3 = (Target) target2;
                This will throw ClassCastException because JVM sees these two as separate, distinct class types since they are defined by different class loader instances.


The above explanation holds true even if MyMainClass doesn't use two separate class loader classes like CustomClassLoader1 and CustomClassLoader2, and instead uses two separate instances of a single CustomClassLoader class.


With above we can conclude, In JVM we have single class loader instance to load the class.

Relationships in Java

Relationships in Java

In Java world, classes are interrelated to each other in specific ways. In particular, the relationships in classes have different types of logical connections. 

These logical connections /relationships among classes are defined in UML in following ways:--

1.  Association
2. Aggregation
3.  Composition
4. Inheritance/specialization
5. Realization
6. Dependency


1. Association:

Association can be defined as any logical connection or link or relationship between classes. For example students study in school or a person works for a company.

Association is represented by a solid line between classes as shown below:--
                                                                                                                    

    
                   


Association has following properties:--

Name:  Indicates the name of the association. Here in above example, “works for” is the name of the association.

Role:  It indicates the role played by each entity in the association. Here in above example, person class plays the role of employee whereas Company plays the role of employer.

Multiplicity: It indicates how many objects of one class relate to one object of other class.  Below diagram indicates that that 1 or more person objects are associated with 1 company Object.



                       
                                                                                                                                                              
               
Direction: It indicates the direction of association. In above example, association is from Person class where employee works for a Company.

2. Aggregation:

It a specialized form of association where one object has reference to another object but both objects has their own life cycles (independent to each other). 

Aggregation is also known as “HAS-A” relationship because he containing object has a member object and the member object can survive or exist without the enclosing or containing class or can have a meaning after the lifetime of the enclosing object also.

For example:  Room has table and table can exist without room. Table has meaning without room also.

Aggregation can be represented as below:

Here Library has references to Books but instances of both classes has independent life cycle. Books have some meaning even if library doesn't exist. Books can still be there if library doesn't exist.                             

                                                                                
 (Note:  the direction of the diamond should be towards the container class)

3. Composition:

Composition is a special case of aggregation where one object contains other object but contained object can’t survive without container object. 

Composition is also known as a 'is a part of' or 'is a' relationship because the member object is a part of the containing class and the member object cannot survive or exist outside the enclosing or containing class or doesn't have a meaning after the lifetime of the enclosing object.

If parent object is deleted, all its children objects have to be deleted.
                               Any department say Computer Science department is part of college. The Computer Science Department cannot exist without the college and the department has no meaning after the lifetime of the college.

4. Inheritance/Specialization:
Generalization refers to the inheritance relationship where the attributes and behavior of the super (parent) class is inherited by the sub (child) class. 

Generalization in UML is denoted by solid line followed by a triangular arrow. The arrow will be directed from the child class to the parent class.Inheritance relationship is shown below:--
                                   
       
                             
                 

5. Realization:
Realization is relationship between a blue print class (Interface in Java) and implementation class.  It is represented as a dotted line followed by a triangular arrow. For example:--
                                                         
6. Dependency:
Dependency relationship between two entities is defined when one entity is dependent on another. The entity which depends on another is called the dependent entity and the other entity is called as independent entity. When there are any changes in independent entity, then it may affect the dependent entity, but the vice versa is not applicable.
It is represented as:-