Monday, August 14, 2006

Changing Your Java Classpath at Runtime

Someone recently asked me how they could modify their Java classpath at runtime.

It is not possible to do this, simply by changing your java.class.path property because this property is only read when the JRE is first instantiated. After that, it is not re-read. Therefore, any changes you make to the property don't really do anything to the existing virtual machine!

BUT there is still a way to accomplish this:
  • Get hold of the SystemClassLoader
  • Call its addURL() method. Since this method is protected, you have to use reflection to sneakily change its accessibility in order to invoke it. I love hacks!
try {
File fileToAdd = new File("HelloWorld.class");
URL u = fileToAdd.toURL();
ClassLoader sysLoader = ClassLoader.getSystemClassLoader();
if (sysLoader instanceof URLClassLoader) {
sysLoader = (URLClassLoader) sysLoader;
Class sysLoaderClass = URLClassLoader.class;

// use reflection to invoke the private addURL method
Method method = sysLoaderClass.getDeclaredMethod("addURL", new Class[] { URL.class });
method.setAccessible(true);
method.invoke(sysLoader, new Object[] { u });
}
}
catch (Exception e) {
e.printStackTrace();
}


WARNING:
Using reflection to invoke private or protected methods is not good programming practice. Especially for hacking into system classes such as the Runtime ClassLoader!

1 comment:

  1. I understand that your "Warning" is just to make you nice to code politicians, but in fact the BAD practice is opposite, when available methods and functionality are just blocked just because of some stupid idiot thinks that we all are as stupid as he is. :-) Well done, Fahd, with this one! It is very very useful for day-to-day java coding. And it gives also to java programmer a very special and very important control instrument that will make him independent from some design idiots.

    With great respect, Estereos

    ReplyDelete