How does JRebel work?
JRebel integrates with the JVM and application servers mainly on the class loader level. It does not create any new class loaders, instead, it extends the existing ones with the ability to manage reloaded classes.
When a class is loaded JRebel will try to find a corresponding .class file for it. It will search from the classpath (including an application classpath, like WEB-INF/classes) and from the places specified in the rebel.xml configuration file. If it find a .class file JRebel instruments the loaded class and associates it with the found .class file. The .class file timestamp is then monitored for changes in the loaded class and updates are propagated through the extended class loader, to your application.
JRebel can also monitor .class files in JARs if they are specified in rebel.xml.
Importantly, when loading updates to a class, JRebel preserves all of the existing instances of that class. This allows the application to just continue working, but also means that when adding a new instance field it will not be initialized in the existing instances, since the constructor will not be rerun.
Some common misconceptions:
- JRebel just wraps class loaders around classes.
In fact JRebel does not add a single new class loader to your application. The solution of reloading Java classes by wrapping them in throwaway classloaders is a well-known one, but unfortunately also very limited. The problem is that unless you also throw away all of the instances of the classes loaded by said class loaders, the code will not reload. However throwing away those instances is only possible if they are somehow managed by the framework, e.g. as it’s done in Tapestry 5.
- JRebel just uses Instrumentation API.
The Instrumentation API was introduced in Java 5 and included a limited ability to redefine Java classes on-the-fly. Unfortunately it is limited to only changing method bodies (as is HotSwap) and also suffers from several additional quirks, which makes it not too useful in a real environment. JRebel agent does use it to instrument the application server class loaders and other basic classes, but the API does not play part in the actual reloading process.