Blogs

Blogs

Java classes instant reloading using DCEVM + Hotswap Agent

I hate when I have to spend time deploying changes in my Java classes. I wanted to know if there was a way of deploying them very fast.

So I found out about Hotswap Agent and DCEVM and decided to give them a shot. So far, they meet my expectations. They get the job done fast... it seems instant! I would encourage anyone developing in Liferay to give it a try, and warn you that you might not want to live without it afterwards yes

Long story short, HotswapAgent and DCEVM are two Open Source projects that, when working together, allow reloading almost any Java class change instantly in the JVM when saving your code. Hotswap Agent is the library in charge of the class reloading, while DCEVM is a JRE patch needed for this to happen. I extraced the summary from here: http://www.hotswapagent.org/how-does-it-workYou can find more info about both technologies on the Internet, but here I will focus on showing how to make them work with Liferay.

So this is what I am currently using:

There is the catch of having to install a patch in the JRE, but since there are versions available for Java 7 and Java 8… I think it is worth it to use it for local development. These are the steps to install and run it:

1) First of all, download a copy of Java SDK 7u79, matching the current version of the Java 7 DCEVM available. I suggest this because I couldn’t make it work with a different Java SDK 7 version. I recommend you to download the SDK and make a copy of it in the same folder for you to apply the patch. That way you will keep an unpatched Java SDK handy:

 

2) Install the DCEVM JRE patch in the copy of the SDK and download the Hotswap Agent jar. The DCEVM installation UI is quite easy to follow. Select your java SDK target of the DCEVM patch, and click on “Install DCEVM as altjvm”. That’s it. Follow the Install section here if you need: http://www.hotswapagent.org/quick-start

 

3) Configure Tomcat Liferay server to run Hotswap Agent in the patched JRE and pass Tomcat the following Memory Arguments:

-Xmx1024m -XX:MaxPermSize=512m -XXaltjvm=dcevm -javaagent:F:\software\DCEVM\hotswap-agent.jar=disablePlugin=hibernate,disablePlugin=proxy,disablePlugin=tomcat

(specify the hotswap-agent.jar location properly to yours)

This Stack Overflow might help you on this step: http://stackoverflow.com/questions/32485303/how-to-configure-hot-swap-agent-with-liferay-server

The disablePlugin arguments can be needed to disable certain plugins of Hotswap Agent that could cause errors. I was getting NullPointerExceptions when saving Java classes at some point, and disabling those particular plugins makes it work: proxy, hibernate and Tomcat. Follow this thread to know the error I was getting if it helps: https://groups.google.com/forum/#!topic/hotswapagent/YNWV0D7qgSc

I have tested these tools for a week now, and I am very happy with how they work together: I can say that I don’t spend any time now deploying most of my Java changes. I hope you find this useful and enjoy Java fast deployments yes

NOTE 1:  it doesn’t instantly reload Java changes in JSP pages. If you change them, you will need to build and deploy again.

NOTE 2: any questions, feedback or input will be appreciated: if anyone runs into issues setting it up, i will try to help.

NOTE 3: Java classes of action hooks are benefited of this instant reloading. So if you deploy an action hook, do some changes in the Java class extending Action, and then save, the Java class is reloaded instantly.

Hi,

I follow your instruction step by step, with same exact step and version. On the log it is saying something about hotswap agent.

But I don't know to test it.

What i have tried is :
- Creating custom portlet (Hello world). Changing the java file, and save it, but the changes is not reflected when i refresh browser. can you share projects files that you use for testing?

basically i don't know whether it is not working, OR i don't know how to test it.
Hello Tiur.

Right, so I believe that when you start the Tomcat bundle using the patched JRE, the first lines that come up in the log are something like:
HOTSWAP AGENT: 9:25:49.414 INFO (org.hotswap.agent.HotswapAgent) - Loading Hotswap agent {0.3.0-SNAPSHOT} - unlimited runtime class redefinition.
HOTSWAP AGENT: 9:25:50.031 INFO (org.hotswap.agent.config.PluginRegistry) - Discovered plugins: [Hotswapper, WatchResources, AnonymousClassPatch, Spring, Jersey2, Jetty, ZK, Logback, JSF, Seam, ELResolver, OsgiEquinox, WebObjects, Weld].

Are you using Eclipse and Maven as well? If you give more details of your environment setup, I will try to get the same as yours and help you from there.

Also, if you just share the hello world portlet that you are using (like only the Java class), I could see if it works in my station and provide you feedback on testing.
I am using Liferay Developer Studio (Eclipse derivative i think).

Last night i add autoHotswap=true to the argument, now it is working for *.java file

the argument now become : -XXaltjvm=dcevm -javaagent:C:\env\tools\hotswap-agent.jar=autoHotswap=true,disablePlugin=hibernate,disablePlugin=proxy,disablePlugin=tomcat -Xmx1024m -XX:MaxPermSize=256m

And i also need to make configuration in server configuration on Liferay Developer studio to become : Publishing > select "Never Publish Automatically"

But the problem now, the *.jsp file is not reloaded.

I googled, and found reference that saying something about adding this in on file hotswap-agent.properties :
watchResources=${basedir}/src/main/resources dan extraWebappContext=${basedir}/src/main/webapp/html

but i haven't tried it.

Did your configuration could reload the *.jsp file?
Hello Tiur,

Greetings on making it work. No, I am not able to reload JSPs instantly yet but it would be great to have that. I will give those hotswap agent properties a shot.

By the way, I had the Publishing option as "Automatically publish when resources change" and it was still reloading the Java classes instantly. So I am not sure if "Never publish automatically" is strictly required.

Since you were able to make it work, I will add your findings to the article. I will also post updates if I am able to reload JSPs as well.

Regards.
Hi, I am trying to setup DCEVM on my machine, configuration is fine but it doesn't reload the java classes. I am using following resources:

DCEVM installer: DCEVM-light-8u92-installer.jar
java version: jdk1.8.0_73
IDE: Eclipse Spring tool suite 3.7.2.RELEASE
server : Tomcat 8.5.3

I am using external run.cmd to pass some more attributes to tomcat.
passing DCEVM altjvm property in run.cmd like below:
set "CATALINA_OPTS=%CATALINA_OPTS% -XXaltjvm=dcevm -javaagent:C:\BLKDeveloper\dcevm\hotswap-agent.jar=autoHotswap=true"

Server starts properly showing the hotswap agent registering the base packages. Remote debug also works fine, but whenever I try to make any change in the java class, changes are not reloaded, not even restarting the server. Just to mention during the build I create the jars bundled in war files.

can you help me out what could be the issue??

Thanks in advance.

For windows setup use this link  https://blogs.sap.com/2018/11/01/hotswap-with-hybris-a-free-open-source-alternative-to-jrebel/

Hi, I am trying to setup DCEVM with Hotswap agent on my machine for , configuration is fine but it doesn't reload the java classes .

 

I am using following resources:

Liferay Portal version 6.2.4 CE ga5/Liferay Portal version 6.2.4 CE ga2 (with these versions i tried) DCEVM installer: DCEVM-light-7u79-installer.jar java version: Java 7u79 IDE: Eclipse(neon) with liferay ide 3.2. server : Tomcat 7.0.42

ant: apache-ant-1.8.2