Picture of two pills

Java Class Reloading Pain : A Fresh Open Source JRebel Alternative

This post introduces a very simple pure Open Source approach knocking down JVM- and application restarts during development. It may not address every scenario requiring class updates, but it reduced the total amount of restarts significantly for me. Your mileage may vary. My workstation is a Linux system and a part of the approach outlined uses a stacked filesystem. I don’t know whether a stacked filesystem that will do is available on every other OS Juava supports. It may not be required for you at all. Even if, I am fairly sure it is possible to come up with an alternative which does not leverage OS support.

Java Class Reloading : A long History of Pain

Developers’ desire to reload class changes is as old as Java. Official bug entry “4910812 : Enhance Hot Code Replacement” dates back to 2003. The most annoying thing for me is the fact that restarts distract a lot. I tend to switch context, do something else and forget about the restarted application. In fact, reloading pain was a major driver for me to almost convert towards dynamic languages. Sure, the problem is not easy to solve, but there still is demand – not everybody has given up hope yet.

Pain perceived depends on various factors. It may not really matter in situations where restarts are fast, such as in the case of desktop applications. But it can matter a lot when you are working on server side components which need a heavyweight environment bootstrapped to run. One of my heavyweights is a webapp called alfresco repository, and one workaround is trying to avoid the Java language and use a dynamic language instead. I am still doing this and will keep doing it when I feel it makes sense.

Approaches Solutions addressing the bug issue generally separate in to categories, JVM – und agent based ones. The ones I looked at over time did not work for me for one reason or another. JRebel, the canonical choice was ruled out because it is not Open Souce and I don’t like that it wants the IDE to be aware of it. DCEVM and most other efforts seem either dead or immature.

Revisiting Class Reloading

Actually, I was fairly happy with the help offered by dynamic languages. I was watching Graeme Rochers Groovy / Grails Exchange 2012 Keynote where he mentioned that spring-loaded, the agent based reloading solution introduced with Grails 2 is available separately on github. I consider SpringSource and the Grails community trustworthy, so I decided to try adding the missing pieces for my “other than grails day to day” work.

Frankly, the spring-loaded agent source looks ugly, but I guess that is due to current JVM limitations imposed at an agent based solution in general. I doubt JRebel sources look better in this respect. At the end of the day, I don’t really care about how ugly the source looks as long as is works for me and there is no need to understand it.

All the spring-loaded agent requires to work are a few Java command line arguments, e.g. -javaagent:/opt/spring-loaded/springloaded-1.1.1-dev.jar -noverify. Depending on your use case, this may already be most you need besides immediate recompilation of classes whenever they change. Eclipse has “build automatically” set by default and hence does the latter out of the box. I hope IntelliJ has a similiar feature (I am about to switch).

For my current alfresco repository case I needed a way to get the project classes directory “merged” with the one of the webapp. The missing ingredient was a stacking filesystem – I picked FUSE based UnionFS. Layering the directories works like this:

unionfs-fuse /opt/alfresco/tomcat/webapps/alfresco/WEB-INF/classes-default=RO:/home/deas/projects/project-a/target/classes=RO:/home/deas/work/projects/project-b/target/classes=RO /opt/alfresco/tomcat/webapps/alfresco/WEB-INF/classes

This union-mount makes changes of class files in target/classes directories of projects appear immediately in the webapp where they are detected by spring-loaded. Neither spring-loaded nor the IDE need to be aware of what is actually happing.

I have just started using this and I am exploring further possibilities. But it already helps me – a lot. It may help you as well.

Honestly, I wonder why SpringSource is not making serious noise about spring-loaded. I am quite excited already. Thank you guys.

Yes, it is not easy but Oracle should still ship cure with the JVM. This may change a little with Java 8. Bug 4910812 received a fresh comment in December. But even if JVM-level efforts resume, it may still take some more time until hotswap catches up in terms of functionality.

References

Andreas Steffan
Pragmatic ? Scientist and DevOps Mind @ Contentreich. Believes in Open Source, the Open Web and Linux. Freelancing in DevOps-, Cloud-, Kubernetes, JVM- and Contentland and speaks Clojure, Kotlin, Groovy, Go, Python, JavaScript, Java, Alfresco and WordPress. Built infrastructure before it was cool. ❤️ Emacs.

5 thoughts on “Java Class Reloading Pain : A Fresh Open Source JRebel Alternative”

  1. Spring Tool Suite supports agent-based reloading out of the box and works like a charm. Thanks to your post I found out about it and wish I would have know about it before.

  2. To be honest, I think we should keep in mind that getting hot-reloading mechanics into systems which were not designed for this kind of workflow can only end up in a compromise. Most trouble here stems from the way these systems handle state. Not sure about PHP, but Erlang is an example of a system which is designed for code changes at runtime from the ground up. I would guess that SpringSource is fully aware of the fundamental problems, and hence only addresses some special use cases in contrast to JRebel which seems to address every code change on could imagine.

    Personally, I am not very happy with the compromise. Today this drives my more and more into Clojure.

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

    https://github.com/jmarranz/relproxy/

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert