Compile and Reload Java Class Dynamically using Apache Commons JCI
By admin on Oct 21, 2007 in Java, open source
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:
- eclipse
- janino
- groovy
- javac
- 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.
Daniel | Nov 2, 2007 | Reply
Hi, is this class reloading based on JVM HotSwap or classes can be reloaded completely (not only method bodies)?
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.
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.
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.