In this post I want to discuss how runtime class reloading can be done in java using user defined class loaders. The following is a simple example that demonstrates how classes can be reloaded at runtime in Java. This is done using a different user defined class loader than that originally loaded the class. The following two java classes should be on the classpath of the java command.
package com; import java.io.*; import java.net.*; public class TestReload { private TestClass reload() { URL[] urls = null; try { // Convert the file object to a URL File dir = new File("C:\\programs\\projects\\"); URL url = dir.toURL(); // file:/c:/almanac1.4/examples/ System.out.println(url); Runtime.getRuntime().exec("javac C:\\programs\\projects\\com\\*.java"); urls = new URL[]{url}; } catch (Exception e) { e.printStackTrace(); } try { ClassLoader cl = new URLClassLoader(urls); Class cls = cl.loadClass("com.TestClassImpl"); return (TestClass) cls.newInstance(); } catch (Exception e) { e.printStackTrace(); } return null; } public static void main(String[] argsv) { System.out.println("sys out"); TestReload testReload = new TestReload(); while (true) { System.out.println(testReload.reload().getMessage()); try { Thread.sleep(5000); } catch (Exception e) { e.printStackTrace(); } } } } // Test class the implementation of this class will be out side of class path package com; public interface TestClass { public String getMessage(); }
Now place the TestClass and TestClassImpl in a path other than the java class path and compile them. Now run the original TestReload and change the message, you will see the changes picked up at run-time :). Bear in mind that I chose not have the class to be reloaded specifically in class path to avoid confusion. This is perfectly acceptable and two different class loaders can load same class.
package com; public class TestClassImpl implements TestClass { public String getMessage() { return "Change me"; } }
Grails development is breeze with runtime class reloading for controllers, domain and service classes etc at run time. JavaRebel is a promising tool that enables this functionality to java users and is a great productivity gain. This tool uses class instrumentation and java agents to achieve run-time class loading that is more efficient and faster.
Resources:
http://mindprod.com/jgloss/reloading.html
http://www.exampledepot.com/egs/java.lang/ReloadClass.html


Leave a Reply