Thursday, May 24, 2012

Programming at the speed of thought II: JRebel

In my last blog post, I lamented the slow turnaround and overall heaviness of enterprise Java development. I also said that I would be checking out JRebel, a tool designed to let you make code changes and push them out to a running application without restarting the application. My verdict? I loved it, convinced my boss to buy it, and am an enthusiastic user. But it is not flawless, so adopters should keep expectations realistic.

We should keep in mind the scope of what JRebel is trying to accomplish. It's not just a matter of reloading updated classes. Enterprise Java has gotten very complex and bulky. Even if you don't use most of them, there are a zillion frameworks in the ecosystem to choose from. They use proxies, AOP, XML configuration files and annotations. What good is the ability to hotswap a class if what you changed is a DB named query that is living in an XML file somewhere? The prevalence of dependency injection frameworks and annotation-based object instantiation means it's not straightforward to even update a running object -- with all its dependencies -- in-place. JRebel tries to handle all that, along with multiple versions of Java, EJB, application servers and IDEs. It's a complex tool for a complex platform. Unfortunately, glitches come with the territory.

Some of JRebel's limitations comes from its sheer ambition. It needs to keep up with Java's vast and fast-moving ecosystem. For example, at the time of writing JRebel's Hibernate plugin still does not support Hibernate 4, though they say it's a priority. Everything else works, but I'm mainly missing its ability to deploy changed named queries in XML files that I mentioned earlier. Or conversely, their Spring WS plugin only supports Spring WS 2, so I disable it when I'm working with Spring WS 1.x.

Some of my colleagues have also seen glitches from the way we configure JRebel. If you have code in multiple modules, you are supposed to write a rebel.xml file that points to the classes in those modules. This adds to your running application's classpath. Because rebel.xml allows wildcard expressions, it is possible to drag in way more stuff than you realized. The result is that we have seen weird glitches in the running application because things are appearing in the classpath due to an over-promiscuous rebel.xml. This is probably a newbie mistake, but one that is easy to make and hard to diagnose, adding to the overall complexity.

So if JRebel can have glitches, may not support all your libraries, and does not reduce complexity, why do I love it so much? To put it simply, when I get it working right, Java development is a dream. Any interruption in the development process can interrupt your mental flow. Wait a few minutes to build, or even a minute to restart the server, and you get thrown off. Distracted. On the other hand, you work in a completely different mental mode when all those accidents vanish. The path from thought to code to reality is effortless. Change the code, refresh the browser, see your changes. Recently, I was making code changes to two different applications simultaneously running under JRebel and talking to each other. Again, it was effortless: change the code, refresh the browser, see my changes.

Another thing I like about JRebel is that the commercial company backing it, ZeroTurnaround, provides excellent support. They are very responsive when we have questions, and they fix bugs rapidly. JRebel itself is under active development and gains new features rapidly.

Ideally, an application platform should be designed from the ground up to be hot deployable. Grails is a joy to work not just because of its hot deploy capability, but also because everything just works. It comes ready to go "out of the box": build system, application server, database (even an SQL console) and command line interface. Just add your browser and enjoy. By contrast, JRebel has a tougher job because it retrofits a platform seemingly designed to thwart programmer productivity. But no other product comes close to what JRebel can do. Precisely because JRebel largely succeeds in what it claims to do, I wholeheartedly recommend it for those of us doing conventional Java enterprise development.

11 comments:

  1. Did you try the other projects? Or why do you say: "But no other product comes close to what JRebel can do" ?

    http://javeleon.org/index.php?page=features

    ReplyDelete
    Replies
    1. Yes, I looked at both Javaleon and DCEVM, and mentioned them in my previous blog entry. Their primary limitation is that they handle only class reloading. JRebel does so much more. See JRebel' list of features. They support a vast list of frameworks: Spring, Hibernate, J2EE, CDI, proxies, OSGi, JAXB. When so much of application behavior is driven by annotations, XML and other externalized resources, the mere ability to update classes does little for me. For example, if I create or update a Spring bean I need the application context to reinstantiate that bean, inject it with new or updated dependencies, apply AOP advice and inject THAT bean into its rightful location(s), all based on new or updated XML and/or annotation metadata. Nothing else can do that for me. Nothing else even tries.

      Delete
    2. Thanks for the insights! When you 'update' your project how long does it take? Would a framework like 'play' be similar to what can be done with JRebel? I just seek for some experiences without having it tried before.

      I'm using a very light framework with guice which reloads very fast and where I mainly develop on unit test level. So I need to understand if JRebel could still help me. BTW: Did you try the liverebel stuff or is this not mature enough?

      Delete
    3. How quickly an update takes depends on what needs to be reloaded. With Eclipse, any class I edit is compiled as soon as I save the file. JRebel refreshes that class as soon as it is executed. So in basic situations, an update is virtually instantaneous, under a second. But in some situations, JRebel will need to refresh a framework -- such as reloading a Spring application context -- and that could take a few seconds. In all cases, it is generally much faster than restarting the server.

      Play, like Grails, is designed to offer hot reload of modified code. If you can stay within these frameworks, you may not find JRebel necessary. But for those of us who do not have that option, or must do things that Play or Grails cannot hot-reload, JRebel might come in useful. JRebel is most useful for those of us who spend significant time doing integration testing/development -- where only a "real" server environment will do -- and using conventional enterprise Java libraries and frameworks.

      I have no experience with LiveRebel, so I cannot make informed comments on it.

      Delete
    4. The only speed issues I have with jRebel are when lots of classes get reloaded. For example, I use HBM files for my hibernate data objects and the hbm2java tool puts new timestamps on each data object. The modified timestamp comment causes eclipse to recompile all of them which causes jRebel to reload all of them and that can take over 15-30 seconds on a large project.

      However, I worked around this by modifying my ant hbm2java task to run a script that strips the timestamps from the data objects as part of the hbm2java ant task. Now all is good aside.

      Delete
  2. Thanks for an amazing post!

    ReplyDelete
  3. I totally agree with you.

    I started using JRebel just two months ago. And I was surprised to see how fast things can be loaded, it given me great motivation to be stick with Java again.

    Good article, keep up the good work !

    ReplyDelete
  4. Great post, Thanks for sharing information, appreciate your good work.

    ReplyDelete
  5. Hi.

    I'm thinking in use jRebel. Just one question, once finished my project I need to send to deploy in a server that doesn't know anything about jRebel. Will my project have problems in that sever?

    Thanks for the post.

    David

    ReplyDelete
    Replies
    1. Hi David. JRebel does not change the code you deploy: your war or ear file is the same with or without JRebel. So your project will work fine without JRebel.

      Delete