According to Java2 class loading system, a custom class loader should subclass java.lang.ClassLoader and overrride findClass() method which is responsible for loading the class bytes and returning a defined class.
Following code is a custom class loader which loads classes from jars, inside the directory called "jar".
public class JarClassLoader extends ClassLoader {
private String jarFile = "jar/test.jar"; //Path to the jar file
private Hashtable classes = new Hashtable(); //used to cache already defined classes
public JarClassLoader() {
super(JarClassLoader.class.getClassLoader()); //calls the parent class loader's constructor
}
public Class loadClass(String className) throws ClassNotFoundException {
return findClass(className);
}
public Class findClass(String className) {
byte classByte[];
Class result = null;
result = (Class) classes.get(className); //checks in cached classes
if (result != null) {
return result;
}
try {
return findSystemClass(className);
} catch (Exception e) {
}
try {
JarFile jar = new JarFile(jarFile);
JarEntry entry = jar.getJarEntry(className + ".class");
InputStream is = jar.getInputStream(entry);
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
int nextValue = is.read();
while (-1 != nextValue) {
byteStream.write(nextValue);
nextValue = is.read();
}
classByte = byteStream.toByteArray();
result = defineClass(className, classByte, 0, classByte.length, null);
classes.put(className, result);
return result;
} catch (Exception e) {
return null;
}
}
}
This code can be improved to
* Load classes from any jar inside the directory
* Dynamically pick up classes if the jar is updated (by keeping a modified time field)