Showing posts with label classloader. Show all posts
Showing posts with label classloader. Show all posts

Sunday, June 12, 2011

Find from which jar a class was loaded

In order to find at runtime where from file system a class was loaded, following command would be useful:
System.out.println(<myjavaclassname>
               .class.getProtectionDomain()
                  .getCodeSource().getLocation());

Output will be something like this:
file:/C:/TestWorkSpace/lib/MyLibrary.jar

It can be helpful while debugging some class loading problems.

Wednesday, May 25, 2011

Common Class Loading Issues (java)

  • ClassNotFoundException
    • Thrown when an application tries to explicitly load a class using class name string and class (.class file) is not found in the classpath.
      Eg. Thrown when an application tries to load a class through its string name using:
      • The forName method in Class.
      • The findSystemClass method in ClassLoader.
      • The loadClass method in ClassLoader.

      By throwing a ClassNotFoundException, the class loader informs us that the bytecode required to define the class is not present in the locations where the class loader is looking for it. There may be classes in a system that cannot be seen by a class loader. This is because a class loader only sees classes that are loaded by itself or loaded by class loaders to which it has a reference. In the class loading delegation model, the classes that are visible to a class loader are those that are loaded by itself or loaded by its parent – in other words, a class loader cannot look down.
    • Can be easily checked by enabling verbose:class JVM argument

  • NoClassDefFoundError
    • Thrown if the ClassLoader instance tries to implicitly load in the definition of a class and no definition of the class could be found.
      The searched for class definition existed when the currently executing class was compiled but the definition can no longer be found. Essentially this means that a NoClassDefFoundError is thrown as a result of a unsuccessful implicit class load.
  • ClassCastException
    • Thrown as a result of incompatible types being found in a type comparison. It indicates that the code has attempted to cast an object to a subclass of which it is not an instance. (remember ClassLoader Namespace)
    • Two classes of the same fully qualified name are not equal to each other if they are loaded by different ClassLoaders. They cannot be cast to each other and such operations would result in a ClassCastException
  • UnsatisfiedLinkError
    It occurs during the resolving stage of the linking phase when a program tries to load an absent or misplaced native library.
  • ClassCircularityError
    It is thrown if a class if a class or interface could not be loaded because it would be its own superclass or superinterface.
  • ClassFormatError
    • This exception is thrown during the verification stage of the linking phase of class loading. The binary data can be malformed if the bytecodes have been changed --if the major or minor number has been changed, for instance. This could occur if the bytecodes had been deliberately hacked, for example, or if an error had occurred when transferring the class file over a network.
    • The only way to fix this problem is to obtain a corrected copy of the bytecodes, possibly by recompiling.


Principles of ClassLoader Operation

Delegation Principal
  • According to this principle, if a particular class is not loaded already, the classloaders delegate the requests to load that class to their parent classloaders.
    Suppose your class MyApp is being loaded:

    public class MyApp{
       Vector vec = new Vector
    }
    
    Since the System-Classpath classloader loaded the MyApp class, it first asks its parent, the extension classloader to load the class. The extension classloader asks the Bootstrap classloader to load java.util.Vector. Since java.util.Vector is a J2SE class, the bootstrap classloader loads it and returns.

Visibility Principal
  • According to this principle, Classes loaded by parent classloaders are visible to child classloaders but not vice versa
  • For classes loaded by ClassLoader X, classes A, B and X are visible, but not class Y. Sibling classloaders cannot see each other’s classes.

Uniqueness Principal
  • According to this principle, when a classloader loads a class, the child classloaders in the hierarchy will never reload the class. This follows from the delegation principle since a classloader always delegates class loading to its parents. The child classloader will load it (or try to load it) only if the parent hierarchy fails to load the class. Thus the uniqueness of the class is maintained. An interesting scenario emerges when both parent and child classloaders load the same

Static class loading vs Dynamic class loading

There are two ways in which classes can be loaded -- explicitly or dynamic or implicitly or static-- with subtle variations between the two.
Static Class Loading
Classes are statically loaded with Java’s 'new' operator.
class MyClass 
{     
    public static void main(String args[]) 
   { 
        Car c = new Car(); 
   }
}


A NoClassDefFoundException is thrown if a class is referenced with Java’s 'new' operator (i.e. static loading) but the runtime system cannot find the referenced class.

Dynamic class loading
Dynamic loading is a technique for programmatically invoking the functions of a class loader at run time.
we can load classes dynamically by...
Class.forName (String className); //static method which returns a Class

The above static method returns the class object associated with the class name. The string className can be supplied dynamically at run time. Unlike the static loading, the dynamic loading will decide whether to load the class Car or the class Jeep at runtime based on a properties file and/or other runtime conditions. Once the class is dynamically loaded the following method returns an instance of the loaded class. It’s just like creating a class object with no arguments.
  class.newInstance (); //A non-static method, which creates an instance of 
                        //a class (i.e. creates an object).
  Jeep myJeep = null ;//myClassName should be read from a properties file or 
                     //Constants interface.
                     //stay away from hard coding values in your program. 
  String myClassName = "au.com.Jeep" ;
  Class vehicleClass = Class.forName(myClassName) ;
  myJeep = (Jeep) vehicleClass.newInstance();
  myJeep.setFuelCapacity(50);

Summary
Explicit class loading occurs when a class is loaded using one of the following method calls:
  • cl.loadClass() (where cl is an instance of java.lang.ClassLoader)
  • Class.forName() (the starting class loader is the defining class loader of the current class)
When one of these methods is invoked, the class whose name is specified as an argument is loaded by the class loader. If the class is already loaded, then a reference is simply returned; otherwise, the loader goes through the delegation model to load the class.

Implicit class loading occurs when a class is loaded as result of a reference, instantiation, or inheritance (not via an explicit method call). In each of these cases, the loading is initiated under the covers and the JVM resolves the necessary references and loads the class. As with explicit class loading, if the class is already loaded, then a reference is simply returned; otherwise, the loader goes through the delegation model to load the class.

What is class loading ? (in java)

Classloading is a mechanism to load a Class inside the JVM. It allows classes to be dynamically loaded as opposed to static loading(done through imports). It is done with the help of class-loader which must be a subclass of java.lang.Classloader. See more here on - What is class loader?

Friday, April 29, 2011

Usage of class loaders

Java ClassLoader is a powerful tool that can be used in a various of ways to extend the possibilities of Java applications.
One of the most well-known usages of custom class loaders are Java Applets, where a class loader is used to dynamically download code from the webpage. Customized ClassLoaders are also the base element of Java Application Servers and Web Containers. ClassLoaders are one of things that make the Java platform so extensible and flexible.

Many J2EE application servers have a hot deployment capability, where we can reload an application with a new version of class definition, without bringing the server VM down. Such application servers make use of custom class loaders. Even if we don t use an application server, we can create and use custom class loaders to fine-control class loading mechanisms in our Java applications. So have fun with custom loaders. 

Getting the class loader of a class

Bootstrap class loader is pretty special, in that it is implemented in native code. All other class loaders are written in Java (apart from some native methods) and extend the java.lang.ClassLoader class. We could get the class loader which was used to load any particular class with class.getClassLoader() method:

public class ShowClassLoaders {

    public static void main(String[] args) {
        System.out.println("class loader for Integer: "
            + Integer.class.getClassLoader());
        System.out.println("class loader for BlowfishCipher: "
            + com.sun.crypto.provider
            .BlowfishCipher.class.getClassLoader());
        System.out.println("class loader for this class: "
            + ShowClassLoaders.class.getClassLoader());
    }
}

When we run this program, we will see the following output:
class loader for Integer: null
class loader for BlowfishCipher: sun.misc.Launcher$ExtClassLoader@9cab16
class loader for this class: sun.misc.Launcher$AppClassLoader@d9f9c3

java.lang.Integer was loaded using the bootstrap class loader. In most implementations getClassLoader() method returns null for the bootstrap class loader. com.sun.crypto.provider.BlowfishCipher class is stored inside the <JAVA_HOME>/lib/ext/sunjce_provider.jar so it was loaded with the extensions class loader. Classes implemented by us, like the class with the main method, was loaded by system class loader.

What is classloader?

The Class loader concept, one of the cornerstones of the Java virtual machine, describes the behavior of converting a named class into the bits responsible for implementing that class.
Source code to Machine code
In contrary to such languages like C++ or Fortran where source code is compiled directly to machine’s native code, Java’s source code is compiled to platform-independent Java bytecode. Normally Java Virtual Machine loads this bytecode for every required class from .class files from the local file system. Java gives us however a possibility to greatly influence the way bytecode is load – customized class loaders.

The loading of Java classes is performed by class loaders (CL), they are responsible for loading classes into the JVM. Simple applications can use the Java platform’s built-in class loading facility to load their classes, more complex applications tend to define their own custom class loaders. Because of this, the Java run time does not need to know anything about files and file systems when running Java programs.

Some points to note about class loaders
  • All class loaders are of the type java.lang.ClassLoader.
  • There are 2 types of classloaders mainly - Bootstrap loader or Primordial classloader and "other" class loaders which include extension class loaders and system class loaders
  • Root loader is bootstrap class loader which has native implementation and cannot be instantiated by Java code.
  • Other than the bootstrap class loader all class loaders have a parent class loader.
  • Chaining” of class loaders means, that every class loader has a parent class loader, and in most cases it asks its parent to load a requested class before trying to resolve it on its own. If the parent can not find the class, the class loader itself tries to load the class.

Writing custom class loader in java

Why write a ClassLoader?

If the JVM has a ClassLoader, then why would you want to write another one? Good question. The default ClassLoader only knows how to load class files from the local filesystem. This is fine for regular situations, when you have your Java program fully compiled and waiting on your computer. But one of the most innovative things about the Java language is that it makes it easy for the JVM to get classes from places other than the local hard drive or network. For example, browsers use a custom ClassLoader to load executable content from a Web site. There are many other ways to get class files. Besides simply loading files from the local disk or from a network, you can use a custom ClassLoader to:

  • Automatically verify a digital signature before executing untrusted code
  • Transparently decrypt code with a user-supplied password
  • Create dynamically built classes customized to the user's specific needs

Anything you can think of to write that can generate Java bytecode can be integrated into your application.

A Custom Class Loader:

We have to extend the java.lang.ClassLoader class and implement some of its crucial methods, like loadClass(String name). This method is run every time somebody requests a class inside the code, and receives as a parameter the full name of the class to load.

In our implementation we will print out this name, so to know when our method was called, and then load the class with our class loader if the class is in “com.vaani” package.(See loadClass method in code below).
 If the class is not in “com.vaani”, we will use the super.loadClass() method, which will pass the request to the parent class loader. (Please note that in this article we omit the “package” and “import” statements to make the code shorter, but every class should be inside the “com.vaani” package).

public class CustomClassLoader extends ClassLoader {

    /**
     * Parent ClassLoader passed to this constructor
     * will be used if this ClassLoader can not resolve a
     * particular class.
     */
    public CustomClassLoader(ClassLoader parent) {
        super(parent);
    }

    /**
     * Loads a given class from .class file just like
     * the default ClassLoader. This method could be
     * changed to load the class over network from some
     * other server or from the database.
     *
     * @param name Fully qualified class name
     */
    private Class<?> getClass(String name)
        throws ClassNotFoundException {
        // We are getting a name that looks like
        // com.vaani.ClassToLoad
        // and we have to convert it into the .class file name like 
        // com/vaani/ClassToLoad.class
        String file = name.replace('.', File.separatorChar)
            + ".class";
        byte[] b = null;
        try {
            // This loads the byte code data from the file
            b = loadClassData(file);
            // defineClass is inherited from the ClassLoader class
            // and converts the byte array into a Class
            Class<?> c = defineClass(name, b, 0, b.length);
            resolveClass(c);
            return c;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * Every request for a class passes through this method.
     * If the requested class is in "com.vaani" package,
     * it will load it using the
     * CustomClassLoader.getClass() method.
     * If not, it will use the super.loadClass() method
     * which in turn will pass the request to the parent.
     *
     * @param name
     *            Full class name
     */
    @Override
    public Class<?> loadClass(String name)
        throws ClassNotFoundException {
        System.out.println("loading class '" + name + "'");
        if (name.startsWith("com.vaani")) {
            return getClass(name);
        }
        return super.loadClass(name);
    }

    /**
     * Loads a given file (presumably .class) into a byte array.
     * The file should be accessible as a resource, for example
     * it could be located on the classpath.
     *
     * @param name File name to load
     * @return Byte array read from the file
     * @throws IOException Is thrown when there
     *               was some problem reading the file
     */
    private byte[] loadClassData(String name) throws IOException {
        // Opening the file
        InputStream stream = getClass().getClassLoader()
            .getResourceAsStream(name);
        int size = stream.available();
        byte buff[] = new byte[size];
        DataInputStream in = new DataInputStream(stream);
        // Reading the binary data
        in.readFully(buff);
        in.close();
        return buff;
    }
}

Classloader types

Bootstrap class loader

There is only one Primordial Class Loader, which is an essential part of each Java VM. It cannot be overridden. The Primordial Class Loader is involved in bootstrapping the Java environment. Since most VMs are written in C, it follows that the Primordial Class Loader is typically written in C. This special class loader loads trusted classes, usually from the local disk.


ClassLoaders other than Bootstrap by jdk
There are three distinct types of Class Loader objects defined by the JDK itself:
  • Applet Class Loaders, 
  • RMI Class Loaders, and 
  • Secure Class Loaders.
From the standpoint of a Java user or a system administrator, Applet Class Loaders are the most important variety. Java developers who are interested in rolling their own Class Loaders will likely subclass or otherwise use the RMI Class Loader and Secure Class Loader classes.

Applet Class Loaders are responsible for loading classes into a browser and are defined by the vendor of each Java-enabled browser. Vendors generally implement similar Applet Class Loaders, but they do not have to. Sometimes seemingly subtle differences can have important security ramifications. For example, Netscape now tracks a class not by its name, but by a pointer to actual code, making attacks that leverage Class Loading complications harder to carry out.

Applet Class Loaders help to prevent external code from spoofing important pieces of the Java API. They do this by attempting to load a class using the Primordial Class Loader before fetching a class across the network. If the class is not found by the Primordial Class Loader, the Applet Class Loader typically loads it via HTTP using methods of the URL class. Code is fetched from the CODEBASE specified in the <APPLET> tag. If a fetch across the Web fails, a ClassNotFound exception is thrown.
It should be clear why external code must be prevented from spoofing the trusted classes of the Java API. Consider that the essential parts of the Java security model (including the Applet Class Loader class itself) are simply Java classes. If an untrusted class from afar were able to set up shop as a replacement for a trusted class, the entire security model would be toast!

The RMI Class Loader and Secure Class Loader classes were introduced with JDK 1.1 and Java 2, respectively. RMI Class Loaders are very similar to Applet Class Loaders in that they load classes from a remote machine. They also give the Primordial Class Loader a chance to load a class before fetching it across the Net. The main difference is that RMI Class Loaders can only load classes from the URL specified by Java's rmi.server.codebase property. Similar in nature to RMI Class Loaders, Secure Class Loaders allow classes to be loaded only from those directories specified in Java's java.app.class.path property. Secure Class Loaders can only be used by classes found in the java.security package and are extensively used by the Java 2 access control mechanisms.

Namespaces in class loading

In general, a running Java environment can have many Class Loaders active, each defining its own namespace. Namespaces allow Java classes to see different views of the world depending on where they originate.
Eg. - classes from some url, OR classes from local environment, classes from particular firewall.

Simply put, a namespace is a set of unique names of classes loaded by a particular Class Loader and a binding of each name to a specific class object. Though some people say that namespaces are disjoint and do not overlap, this is not true in general. There is nothing to stop namespaces from overlapping.

Most VM implementations have used different class loaders to load code from different origins. This allowed these implementations to assign a single security policy to all code loaded by the same class loader, and to make security decisions based on which class loader loaded the class that is asking to perform a dangerous operation. With the addition of code signing in JDK 1.1, there are now two characteristics for categorization of code: origin (usually represented as a URL) and signer (the identity associated with the private key used to sign the file). Only the Class Loader that loaded a piece of code knows for sure where the code was loaded from.

According to the Java specification, every Class Loader must keep an inventory of all the classes it has previously loaded. When a class that has already been loaded is requested again, the class loader must return the already loaded class.

Every different class loader represents a different namespace. Static fields of classes inside one namespace are separate from static fields of classes from other namespaces. If we set a value of a specific static field in namespace A, objects from namespace B will not be able to read it, and vice versa.

Let’s see how it works. We will have a public static Integer field in some class, and we will be trying to access this field from classes loaded with different class loaders. Here is this field:

public class StaticHolder {
    public static Integer value = null;
}

Below is also the class used to access the field. It will read the value of the field and then change it to 4. Default value for any class field is null, so that’s what we expect to see as the start value. In a normal, single-classloader program, after changing the value of the static field, the change would be visible to other objects reading that field. We will see what happens with multiple classloaders.

public class StaticAccessor {
    /**
     * Accesses the static field from StaticHolder class.
     * It reads its value and after that sets it to 4.
     */
    @Override
    public void runMe() {
        System.out.println("--- Starting runMe. Static value: "
            + StaticHolder.value);
        StaticHolder.value = 4;
        System.out.println("--- Finishing runMe. Static value: "
            + StaticHolder.value);
    }
}

In our experimental main method we will create this time two CustomClassLoaders and load our StaticAccessor field with both of them. We will then create two instances of the StaticAccessor class, each of them from the different class loader, and run their runMe() methods.

 You can find the implementation of our CustomClassLoader in the previous article.

When we run the program, we will get the following output:
loading class 'javablogging.StaticAccessor'
...
--- Starting runMe. Static value: null
loading class 'java.lang.Integer'
--- Finishing runMe. Static value: 4
loading class 'javablogging.StaticAccessor'
...
--- Starting runMe. Static value: null
loading class 'java.lang.Integer'
--- Finishing runMe. Static value: 4
When you look at the “— Starting runMe” lines, you will notice that both of them show null! Although we changed the static field to 4 in the first run of runMe(), the value read in the second runMe() shows once again null.

In normal programs it may be hard to see a usage for such tricks. Separating namespaces in such a way may be however useful for example when doing unit tests, when you want to be sure that every test runs in a completely separate sandbox, or when implementing frameworks or application servers, where every deployed application should be isolated from others.

References
You can read more about class loaders and namespaces in Java for example in this article: http://www.artima.com/underthehood/classloadersP.html.



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

Summary
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.

Chitika