Archive for August, 2009

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

I have recently switched from bash to zsh. zsh has nice command completion and it also suggests command if you mistype. Mac OS-X comes with zsh installed, to switch to zsh go to system preferences -> accounts, right click on the account select advanced options and select zsh for login shell. Also along the way I picked up a new command, its the bang command I would like to share, bare in mind this is not unique to zsh and is also available in bash. Have fun programming :).

 !! - To run last executed command
 !$ - Last argument of previous command
 !* - All arguments
 !!:1 - First argument

References
http://www.zsh.org/
http://vafer.org/blog/20070103101542