What are the differences between the various Java plugins for hot class reloading and which one is the most intuitive?

StackOverflow https://stackoverflow.com/questions/17419900

Question

I am currently trying to implement hot class reloading in a Java application, however there are so many plugins to choose from and I cannot find a good comparison between the options. Also the websites of the plugins are not all very clear on what the exact features are and how to use them.

There is also the option of making a custom hot class reloading ClassLoader, but I feel like that is similar to "reinventing the wheel" if there are already so many plugins which can do the job.. do other people agree with this?

The Java plugins I found which I think can do the job:

So does anyone happen to know what the differences are between the plugins? And also which plugin is the most intuitive to use?

As a side note: What I actually want to do is reloading a .jar-file dependency of my java application. I have some java code which gets re-compiled automatically very often and then converted to a .jar-file. It's a dependency of my java application, and my application needs to use the newest version of this .jar-file every time.

Was it helpful?

Solution

Disclaimer: I'm involved with JRebel development and therefore my answer might look a bit biased, but I'll do my best to explain.

To answer this question I first want to draw your attention to the fact that one main difference among the names you have listed is: some of the solutions require you to change application design, others don't.

Modularization solutions, like OSGi or JBoss Modules provide benefits if you follow the right path and modularize your application. Otherwise, if you deploy one silo bundle, it basically means you're restarting/redeploying the whole application, thus diminishing any benefits gained from this approach.

Play Framework is actually a full-stack framework that has the hot-deployment capabilities. Those capabilities vary depending on which version of the framework you use. But again, same story as with modularity - the framework enforces a certain programming model.

Apache Commons JCI isn't really a solution for hot updating the code. AFAIK, it just compiles and loads the class via new classloader. This also involves changing the application code as in the cases mentioned above. I'm not really sure if it is good or bad. The downside is that you hardly can do any broad integration with the ecosystem in this way. This approach is rather feasible for a self-made framework that would make use of this feature. Myself, I'd rather use a scripting language like Groovy, JRuby or JavaScript to achieve the same. Something like this, for instance.

JRebel, Fakereplace and DCEVM - those guys do not care about the programming model. But the difference is quite big:

DCEVM patches the JVM and its goal is to provide a complete hotswap solution, which it does.

JRebel is a java agent (hooked with -javaagent VM argument), that instruments the application code and loads the new versions of the classes by versioning them. The main value of JRebel is that it provides flexible configuration along with a huge amount of framework specific integrations, so that you can do a lot more than just a hotswap of java classes. For instance, add and autowire new beans in Spring application context, add new EJBs on the fly, and new Struts actions, etc.

Fakereplace is also an instrumenting agent, like JRebel but it has a lot less support for Java code changes (I assume) and the number of supported frameworks isn't as impressive.

Feenix can do as much as the Java Instrumentation API allows it to do. Which basically means it doesn't really add value on top of standard HotSwap of the JVM. Same for AgentSmith

UPDATE: this answer motivated the author of Feenix to come up with a new version - Feenix 2.0 which resembles the way JRebel works with classes. But as the author says himself - Feenix is still vastly inferior to JRebel. There are also a couple of similar solutions, like HotswapAgent and Spring Loaded - those tools also provide similar functionality but limited in their own way.

Now a bit on your specific problem, how it could be solved with JRebel:

Every module of the application should have its own configuration file, rebel.xml. By module, we mean, either the EAR, WAR, or any of the JAR dependencies in WEB-INF/lib (like in your case) or server specific libraries. The configuration file with point to the directory where the compiled classes are and JRebel will load the classes directly from that location. This all means that you do not need to assemble the entire JAR once you make a change to a Java class. Instead, you make a change and compile the source (leverage the IDE, instead of a build script). The compiled class will be reloaded by JRebel once the class is invoked within the application code.

OTHER TIPS

There's a new kid on the block, RelProxy, it is open source, is not so advanced like JRebel but it can be used to freely change a subset of your code in runtime and reload it with almost no performance penalty and no need of context reloading (no session lost) in development and production if you want.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top