Monday, January 27, 2014

How to write a custom class loader

Under the Java™ 1 class loading system, it was a requirement that any custom class loader must subclass java.lang.ClassLoader and override the abstract loadClass() method that was in the ClassLoader. The loadClass() method had to meet several requirements so that it could work effectively with the JVM's class loading mechanism, such as:
  • Checking whether the class has previously been loaded
  • Checking whether the class had been loaded by the system class loader
  • Loading the class
  • Defining the class
  • Resolving the class
  • Returning the class to the caller
The Java 2 class loading system has simplified the process for creating custom class loaders. The ClassLoader class was given a new constructor that takes the parent class loader as a parameter. This parent class loader can be either the application class loader, or another user-defined class loader. This allows any user-defined class loader to be contained easily into the delegation model.
Under the delegation model, the loadClass() method is no longer abstract, and as such does not need to be overridden. The loadClass() method handles the delegation class loader mechanism and should not be overridden, although it is possible to do so, so that Java 1 style ClassLoaders can run on a Java 2 JVM.
Because the delegation code is handled in loadClass(), in addition to the other requirements that were made of Java 1 custom class loaders, custom class loaders should override only the new findClass() method, in which the code to access the new class repository should be placed. The findClass() method is responsible only for loading the class bytes and returning a defined class. The method defineClass() can be used to convert class bytes into a Java class:
   class NetworkClassLoader extends ClassLoader {
         String host;
         int port;

         public Class findClass(String name) {
             byte[] b = loadClassData(name);
             return defineClass(name, b, 0, b.length);
         }
         private byte[] loadClassData(String name) {
             // load the class data from the connection
         }
    }

No comments:

Post a Comment