RSS Feed for This PostCurrent Article

Compile and Reload Java Class Dynamically using Apache Commons JCI

In one of my recent assignments, I need to have the flexibility to modify my Java class, compile and then reload it dynamically. I played around with a few tools and finally decided to use Apache Commons JCI.

JCI is used projects like JBoss Drools, Cocoon, and other commercial products.

As quoted from the website, JCI is a java compiler interface. It can be used to either compile java (or any other language that can be compiled to java classes like e.g. groovy or javascript) to java. It is well integrated with a FAM (FilesystemAlterationMonitor) that can be used with the JCI compiling/reloading classloader. All the currently supported compilers (even javac before java6) feature in-memory compilation.

The current implementation supports compilation via the following compilers:

  1. eclipse
  2. janino
  3. groovy
  4. javac
  5. rhino

Compilation

JavaCompiler compiler = 
 new JavaCompilerFactory().createCompiler("eclipse");
CompilationResult result = 
  compiler.compile(sources, new FileResourceReader(sourceDir), 
      new FileResourceStore(targetDir));
System.out.println( result.getErrors().length + " errors");
System.out.println( result.getWarnings().length + " warnings");

Filesystem monitoring and Class Reloading

A subproject of JCI provides a FilesystemAlterationMonitor that can be used to get notified when files change on the local filesystem. If you attach a ReloadingListener or a CompilingListener it can even trigger the reload of a class in the ReloadingClassLoader.

ReloadingClassLoader classloader = 
  new ReloadingClassLoader(this.getClass().getClassLoader());
ReloadingListener listener = new ReloadingListener();

listener.addReloadNotificationListener(classloader);

FilesystemAlterationMonitor fam = new FilesystemAlterationMonitor();
fam.addListener(directory, listener);
fam.start();

You can also implement a simple FilesystemAlterationListener yourself and just use it to get notified about configuration files changes.


Trackback URL


RSS Feed for This Post4 Comment(s)

  1. Daniel | Nov 2, 2007 | Reply

    Hi, is this class reloading based on JVM HotSwap or classes can be reloaded completely (not only method bodies)?

  2. admin | Nov 2, 2007 | Reply

    If you read the doc and source code of the ReloadingClassLoader, which says

    ReloadingClassLoader uses a delegation mechansim to allow classes to be reloaded. That means that loadClass calls may return different results if the class was change in the underlying ResoruceStore.

    Which means that the modified compiled class are reloaded completely everytime it is changed.

  3. Pavani Challa | Sep 21, 2009 | Reply

    Hi, I am facing two problems here.

    1. My class is not reloaded even after it is modified.

    2. FAM doesn’t work when the directory has sub-directories.

    Please help me out.

  4. dao | Jan 26, 2010 | Reply

    hello,

    is it possible to add a classloader listener un pure java 1.5?

    I have a java application in debug mode, I reload classes while the application is running (using eclipse) and I want to do something when I detect the class is reloading.

1 Trackback(s)

  1. From links for 2007-10-29 « betaalfa.com | Oct 28, 2007

Sorry, comments for this entry are closed at this time.