Every custom loader must directly or indirectly extend the java.lang.ClassLoader
class. The main extension points are the following methods:
findClass(String)
- overload this method if your classloader follows the standard delegation model for class loading.loadClass(String, boolean)
- overload this method to implement an alternative delegation model.findResource
and findResources
- overload these methods to customize resource loading.The defineClass
methods which are responsible for actually loading the class from a byte array are final
to prevent overloading. Any custom behavior needs to be performed prior to calling defineClass
.
Here is a simple that loads a specific class from a byte array:
public class ByteArrayClassLoader extends ClassLoader {
private String classname;
private byte[] classfile;
public ByteArrayClassLoader(String classname, byte[] classfile) {
this.classname = classname;
this.classfile = classfile.clone();
}
@Override
protected Class findClass(String classname) throws ClassNotFoundException {
if (classname.equals(this.classname)) {
return defineClass(classname, classfile, 0, classfile.length);
} else {
throw new ClassNotFoundException(classname);
}
}
}
Since we have only overridden the findClass
method, this custom class loader is going to behave as follows when loadClass
is called.
loadClass
method calls findLoadedClass
to see if a class with this name has already been loaded by this classloader. If that succeeds, the resulting Class
object is returned to the requestor.loadClass
method then delegates to the parent classloader by calling its loadClass
call. If the parent can deal with the request, it will return a Class
object which is then returned to the requestor.findClass
then calls our override findClass
method, passing the name of the class to be loaded.this.classname
, we call defineClass
to load the actual class from the this.classfile
byte array. The resulting Class
object is then returned.ClassNotFoundException
.