Hot Swapping Java Code on Runtime

If you are a Java enterprise application developer, you must know the pain of redeploying your code changes on your local server running inside your IDE (or externally) after making some smaller changes. You cannot always take the luxury to redeploy every change you make once in a while to see the output in your APIs, since redeployment requires your server to restart or reloading your whole enterprise application. And every redeployment takes around 4 to 9 mins on an average, depending on the size of your application and the infrastructure of your machine. It is even more devastating to see a web developer next to you writing and redeploying his/her changes just in few seconds to see the output in the browser instantly. And you can't do the same with your Java stack, eh!!

Well, on a serious note, consider that there are 10 developers working in your organization. Each developer is working 8 hours a day, their average annual wage is ₹500,000 and he/she does 4 redeployments per hour on an average, and the average time taken by the system is 5 mins per redeployment. Interestingly, each developer is wasting 2.67 hours a day just in redeployments, which is costing the organization around ₹16,70,400 annually for all 10 developers for doing nothing worthy of his/her time. 

Well, there are ways to save this time and invest it in other, more productive work. There is a tool available in the market called JRebel. It is a good commercial tool if one can afford. However, if you are an open-sourcist, there is a promising alternative to JRebel, which is DCEVM (Dynamic Code Evolution Virtual Machine) along with HotswapAgent. And we are going to see hotswapping of Java code on runtime using these two tools.

DCEVM is a modified Java HotSpot, which allows you to redefine the classes at runtime in your JVM. Hence, we need to patch this modified Java HotSpot version to our existing JVM on our system.

Install DCEVM

Download the latest release of DCEVM and patch your current JVM installed in your system. For reference, I am using Java 8. DCEVM also supports Java 7.

Once you download the JAR file, run the following command to start the installer:

java -jar DCEVM-light-8u112-installer.jar 

The installer will automatically detect your JVM directory. If not, then select your Java installation directory and click the "Install DCEVM as altjvm" and "Replace by DCEVM" buttons.

DCEVM Installer

And you're done! This will patch your JVM with DCEVM.

To validate the installation, run:

java -version 

It should output something like:

java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Dynamic Code Evolution 64-Bit Server VM (build 25.71-b01-dcevmlight-8, mixed mode)


Note that there is Dynamic Code Evolution 64-bit Server VM instead of Java HostSpot(TM) on the last line. This means you have successfully patched DCEVM in your JVM.

Next, we are going to download and configure HotswapAgent. HotswapAgent is responsible for reloading resources and framework configurations. In the other words, it supports the reloading of classeses/Spring bean definitions after changes occur to them. 

Download HotswapAgent

Download the latest release of HotswapAgent and put hotswap-agent*.jar in any location on your disk.

Run Configurations

Now that we have both tools in place, we need to configure the location of hotswap-agent*.jar as javaagent and DCEVM as altjvm in the VM arguments to the JVM in our Run Configurations. For reference, I am using STS (Spring Suit Tools) Eclipse. It supports any IDE/Server or command line.

You need to configure following line in VM arguments to the JVM in Run Configurations:

-XXaltjvm=dcevm -javaagent:/home/cybercode/tools/hotswap-agent-1.1.0-SNAPSHOT.jar=autoHotswap=true


Here, note that path of hotswap-agent*.jar on my system is /home/cybercode/tools/hotswap-agent-1.1.0-SNAPSHOT.jar. Replace the path where you have saved this JAR file. 

To open Run Configurations in Eclipse, go to Run > Run Configurations. If you are running your Java application with embedded Tomcat, you can configure the VM arguments here.

Tomcat Run Configurations

And if you are running your Java application as Spring Boot application, then you can select your Spring Boot app and pass the VM arguments in the same place.

Spring Boot App

That's it. All the setup is done. Now, it's time to run the application and test the configurations.

Run Your Application to Hot Swap Java Code

Now that we have done all the configurations, let's start the server and change some code and see the changes instantly.

For reference, I am running my application on an embedded Tomcat Server in my STS (Eclipse) IDE. Once you run the server, you can observe from the logs in the console to see that the HOTSWAP AGENT plugin is loaded in the Tomcat container.

Hotswap Agent log

Once the server starts. I am calling an API where in my code I have printed Calling my API... on the console.

Image title

Next, I have modified the print statement to Calling my API again after some changes!! and saved and built my code. There it goes. You can observe in the following snapshot that, instead of redeploying the whole application, the DCEVM hot swapped the affected classes in the JVM just within 1 to 3 seconds. And you can see the modified output on the console as following.

Classes hot swapped.

So, that's it. It has hotswapped my Java code just in 1 to 3 seconds. Overall, a very useful and promising tool.

TIP: Uncheck the 'Build Automatically' option in the Project Menu in Eclipse. After making changes in your code, to hotswap classes, press Ctrl+B to build the project. After the build event, it will automatically hotswap the classes. But if you keep the 'Build Automatically' option checked, it will hotswap on every save event.

An Alternative: Spring Loaded

As an alternative, I have also given Spring Loaded a try. It's an open source tool that does the same job. It worked fine with my smaller Spring Boot application, however, it could not hold up when faced with the larger enterprise application. If you also want to give it a try, you can download the latest release of the Spring Loaded JAR and place it in your favorite location. Then, pass the following VM arguments to the Run Configurations and follow the same steps as above.

-javaagent:/home/cybercode/tools/springloaded-1.2.6.BUILD-20160411.195630-9.jar -noverify


This would work the same way as DCEVM and HotswapAgent. However, I found DCEVM and HotswapAgent to be more convenient over Spring Loaded due to their stability. What do you think? Let me know in the comments below.

And if you find this post helpful, do share it with others. 

 

 

 

 

Top