25

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.

PJvG
  • 1,310
  • 3
  • 16
  • 33
  • 1
    You could look into using OSGI. It supports reloading bundles at runtime. – Viktor Seifert Jul 02 '13 at 07:47
  • 3
    Ive used Jrebel and amazed at how well it reloads classes in projects and its dependencies. Free Social license makes it easy to test out. JRebel has quite an extensive user base. – vcetinick Jul 02 '13 at 07:54
  • 2
    Thanks for your comments. I am already looking into OSGi and JRebel, I haven't decided yet which one would be best for me though. Also, I will add OSGi to the list above. – PJvG Jul 02 '13 at 18:22
  • 1
    @PJvG Can you share your findings? What did you choose and what were your findings? – Martin Kersten Oct 02 '15 at 14:04
  • @MartinKersten I decided to switch from Java to Python for the project I was working on two years ago before I was ready to choose a Java plugin for hot class reloading. I'm sorry but I don't have any findings to share. – PJvG Oct 05 '15 at 06:55
  • Ok. So python has hot class replacement already build in? – Martin Kersten Oct 05 '15 at 09:00
  • @Martin I never said or implied that, but it seems that Python [has indeed hot class/module reloading build in](https://docs.python.org/2/library/functions.html#reload) (if I understand it correctly). I looked it up for you. I however stepped away from using hot class reloading. It was no longer required for the project. So I don't know how well Python's reload works or if it is applicable to your situation. I don't think I can be of much help to you here. Good luck with whatever you're planning on doing. – PJvG Oct 05 '15 at 09:55
  • 2
    Sorry to confused you. I just thought the hot class reloading was a requirement of sort. Thanks for looking it up thou. I took a look and the mechanism has quite interesting caveats and corner cases. I for myself bite the bullet and implement a class reloading mechanism from scratch due most of the options are either closed source or from what I read dislike the implementation or is too complex. So thanks again for looking it up. – Martin Kersten Oct 05 '15 at 13:37

2 Answers2

36

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.

Anton Arhipov
  • 6,479
  • 1
  • 35
  • 43
  • 1
    Thanks for the elaborate answer! It is very helpful. Is there a reason though why you did not mention Apache Commons JCI FAM and AgentSmith in your answer? – PJvG Jul 16 '13 at 07:33
  • 1
    Since ZeroTurnaround is canceling its floating license model I'm looking for JRebel alternatives and found this great answer. In the meantime there's a new kid-on-the-block: https://github.com/spring-projects/spring-loaded . It does have it's limitations but what it does it does well. – Marcel Stör Dec 09 '14 at 20:53
2

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.

jmarranz
  • 6,459
  • 2
  • 21
  • 10