On our current project, we are using a JBoss application server to host the services that the application needs to function. This application server takes about 1.5 minutes to start. This means that after a developer makes a change to the code, they must wait at least this long (in addition to the amount of time that it takes to get to the correct context in the application to test the change that they are going to make) to see whether the changes that they made achieved the desired result. It is important to get quick feedback when working in order to maintain flow and productivity, and this wait time clearly violates that principle. In order to enable developers to be more productive, we decided to try using JRebel, a tool created by ZeroTurnaround that allows developers to see the effect of their code changes immediately.
JRebel works by monitoring the directory that contains the class files that are produced as part of a build. In Maven, this is the target/classes/ directory of your Java project. If there is a change to any of the class files in this directory, then JRebel will update the classes in the container’s JVM to reflect those changes. In order for JRebel to detect changes in the build output directory it must know where this directory is located. You tell JRebel which directory to monitor for class file changes by creating a rebel.xml configuration file. This file can either be created by using an IDE plugin to generate this file for modules within your project (JRebel provides a plugin for Eclipse, IntelliJ, and NetBeans) or by using a Maven plugin to automatically generate this file as part of your Maven build. This file contains the full path to the target/classes/ directory, and must be included in the artifact that is deployed to JBoss (typically something like a JAR or WAR file).
In addition to supporting hot deployments of Java classes, JRebel also supports reloading static resources such as JavaScript, Velocity templates, and HTML. You must modify the rebel.xml file for the module containing these static resources for JRebel to work properly (see the JRebel documentation for information about how to do this). If you are simply deploying these static resources “as is” to the server, then the path in the rebel.xml file can simply point to the original source files. In this scenario, JRebel will detect and deploy changes to the file as soon as the file is saved. However, in many applications (including the one that we are developing on my current project), the JavaScript is minified and aggregated before being deployed to the server. For these applications, you will need to configure the rebel.xml file to point to the location of the minified/aggregated files instead of the source location (most likely under the target/ directory instead of the src/ directory for the module). In addition to this, you will then need to build the module in order to perform the minification/aggregation process again.
After you finish configuring JRebel to work with all of the modules for which you would like to hot deploy changes, you need to perform a full build and deploy of the application. You will then need to modify the startup procedure for the application server itself (in our case, JBoss) in order for JRebel to work. You must modify the script (standalone.sh for JBoss) such that it uses the JRebel Java agent when starting the JVM. This Java agent reads in the rebel.xml files that are included in the deployed artifacts and starts monitoring those directories for class file changes. As soon as any change has been made (which is determined by checking the timestamp of the monitored files) the Java agent will pick them up and hot deploy them and the developer will immediately be able to test the change.
Starting the server with the JRebel Java agent increases the startup time by about one minute, but this cost is more than compensated for by the fact that developers no longer need to restart their servers after making changes. If a developer works eight hours in a day and restarts their server 4-5 times per hour, JRebel will save them about 51.5 minutes per day. This improvement in efficiency alone is significant, but it does not account for the additional productivity that developers will gain by being able to get feedback on their changes quickly.
After we (the members of the architecture team for this project) got JRebel to work, we integrated it into a feature branch of the Vagrant-provisioned developer VM that developers use on this project and had several developers beta test it. The beta test is still in progress, but our initial feedback has been positive. We have had both front-end and back-end developers try using the tool, and both of these types of developers have been able to get it to work. Aside from some initial problems with the instructions that we provided to the developers (which we have since clarified), there have been no changes that a developer has wanted to hot deploy that JRebel could not handle. We plan on enhancing how JRebel is configured to reduce the number of steps that developers need to take (such as generating the rebel.xml file or hand editing it if they want to hot deploy changes made to static resources) in order to make the tool even easier to use.
I will publish a follow-up post once developers have had more time to use the tool and we have more information about how well it works and how much it improves developer productivity.