Agent Smith

ATTENTION
This is the old project page. Agent Smith has moved over to java.net. Change your bookmarks to
https://agentsmith.dev.java.net/.

Introduction
Java 5 has brought a new package, java.lang.instrument. With its classes and interfaces you can build an agent, a particular class that has access to the underlying implementation of the interface java.lang.instrument.Instrumentation, in which API you find

void redefineClasses(ClassDefinition[] definitions)

Here’s the idea: I want to create an agent that watches my .class files folder and that hot-reloads (or redefines) each .class file as soon as I modify it while I’m developing, without any reload, without the creation of custom classloaders and without the instantiation of new objects (if I’ve just modified a method, I want every already running instance to use the new method definition).

All this can be done with an agent. An agent is particularly useful because its presence is, in no way, known by the application. You won’t need to code some custom classloaders or awkward tricks to speed up the development process: you just plug in an agent and, when you are done, you plug it out, just as you do with assertions.

Agent Smith
With my powerful imagination, I’ve called it Agent Smith.

Smith is a combination of an agent implementation, a file monitor and an agent loader.

To use it, follow the instructions at the “How to compile and use” section.

Then begin to code: run your (web)app, change some classes while the app is running, optionally compile and deploy them (if your IDE is not doing that automatically) and see your modifications applied by executing the modified methods. Notice you haven’t reloaded the app. Multiply the time you are not wasting for the number of times you need to reload the app and you should gain some long weekends at the seaside the next month ;)

Agent Smith is currently at its very first release so it could be buggy. Anyway, I hope that you’ll like it and that you’ll feed me back with comments and improvements.

Requirements
The only requirement is that you use java 5 (or 6) to run your application. You can still compile it using java 1.4 but you need to run it with java 5+.

Source code
You can download it here.

License
Smith is covered by the LGPL license. If you have any issues about that license, mind that I don’t really think you’ll ever distribute your application with an agent. Using an agent is a development thing, not a production one and the license (even if it was a viral GPL) does not oblige you to change the license of your application just because you are using Smith. An agent, as said, is something your application does not know and your application does not depend on it.

DOCUMENTATION
How to compile and use
Smith comes in two versions. You can choose which version to use by editing the “build.properties” file and change “javac.version” field to “5” or “6“.

The hard version requires just java 5 and it is the recommended version. This version can only be used from the command line. Each time you need agent features, run the java virtual machine with the following parameter:

-javaagent:<PATH_TO_SMITH.JAR>=<PATH_TO_CLASS_FILES>
(mind to put a trailing slash)

By editing and compiling your class files, you’ll see them behave accordingly without the need of restarting the app. If you need agent features into a servlet container, edit its launch parameters and add the above parameter. It should then look like:

-javaagent:<PATH_TO_SMITH.JAR>=<WEBAPP_PATH>/WEB-INF/classes/

There is a small problem with Smith used in a servlet container. Because of the running file monitor thread, if you restart the container it will “hang”. The problem can be solved by creating a very small servlet with a destroy method such as

@Override
public void destroy() {
super.destroy();
Smith.stopAll();
}

As you understand, Smith jar must also be put in the classpath.

The soft version requires java 6, it’s easier to use but it is experimental. Java 6 attach api allows an agent to be loaded at runtime, after the jvm start up. You can therefore code a servlet that loads the agent. An example code is available here.
PAY ATTENTION: using this feature requires an almost OS dependent way to recover the jvm process from the running processes. Current Smith version has been tested with Linux and should work also with Windows and MacOSX. Please report of any issues you are encountering with these operating systems.

How to (quickly) test the agent
Read this blog entry.

Similar projects and links
A nice article at javalobby.
Hotswap, an ant target to replace class definitions on a running JVM