Compilation of already published Articles/Ideas/Problems-Solutions which I faced or came across over the period of time. Largely a place for me to document it as note-to-self. Nothing serious. :)
Monday, July 16, 2012
What is/isn’t JRebel?
A development-time tool that decreases turnaround by instantly reloading changes to your code, without having to restart the container or redeploy the application.
A JVM -javaagent plugin. The -javaagent is a command line option that has been available since Java 5 to allow custom instrumentation plugins to be registered. JRebel uses this option for installation.
A JAR file about 1 MB big. That’s pretty much says it all – there is no long installation process: just unzip, copy, add options to the command line and enjoy!
An IDE plugin. There is some configuration/integration you can do to improve your experience, but JRebel will work with a vanilla Java compiler and a text editor as well.
A framework. JRebel does not introduce any dependencies in your application. You can take it away at any moment and just continue developing the way you do usually.
An application server. JRebel works with all prominent application servers, but it definitely isn’t one.
A custom JVM. JRebel doesn’t require you to make any changes to the JVM and works on all prominent JVM implementations.
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.xmlconfiguration 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.
Aren't there free/open source alternatives that do that already?
In one word: no. However there are several partial solutions:
Hot deploy. This is basically when your application is redeployed on any change to the code. Most application servers will allow you to do that. The problem is that it only works for small or lightweight applications. Your typical enterprise application will redeploy for at least 30 seconds and this time is just wasted. With JRebel the reloading time is measured in milliseconds.
HotSwap. HotSwap is a technology available in Java since 1.4 that allows you to instantly redefine Java classes inside a debugger session. This is supported by all prominent IDEs (e.g. IntelliJ IDEA, Eclipse and NetBeans), so if you attach a debugger to your application and make some changes, they will be reflected immediately. Unfortunately this technology is very limited, as it only allows changes to method bodies and doesn’t allow new classes to be added. JRebel can be thought of as improved HotSwap, as it allows changes to class structure, including adding methods, fields, constructors and even annotations as well adding classes and changing configurations.
OSGi. OSGi is a runtime module container for Java. It allows you to split an application into modules with well-defined dependencies and manage them separately. One of the side-effects is that it allows you to update the modules (or, in OSGi-speak, bundles) one at a time. It is basically the same solution as Hot Deploy, but since the module size is smaller than the application size, the time wasted can be smaller. It will still likely be measured in tens of seconds, since all of the dependent modules should also be updated, but it can be significantly faster than vanilla WAR/EAR applications. JRebel reloading time is still orders of magnitude faster.
Throwaway class loaders. Several frameworks (including Tapestry 5, RIFE, Seam, Grails and so on) will instantly reload the changes to the code of the managed components (e.g. beans, pages, controllers, etc). This is possible by wrapping a throwaway class loader around the managed component and recreating its instance after every change. Unfortunately this solution works only for managed components and the rest of the code cannot be reloaded. It can also cause weird ClassCastExceptions and other similar problems due to class loader migration problems. JRebel works for any class in your system, preserves all the current object instances and does not exhibit any class loader-related problems.
What about configuration changes?
Reloading changes to Java classes is not always enough. Applications include configurations for Java code, annotations, XML files, property files and so on. JRebel uses configuration-specific plugins to reload those changes instantly, just as it does changes to classes. JRebel comes with plugins for Spring, Guice, Stripes, Tapestry 4 and others out of the box. To find out more check out check out our OSS projects’ overview.
Can JRebel be used in production?
JRebel is meant and licensed only as a development tool. If you’re interested in using the same engine for production updates, check out LiveRebel.