Matt RaibleMatt Raible is a Java Champion and Developer Advocate at Okta. developer.okta.com

The JHipster Mini-Book The JHipster Mini-Book is a guide to getting started with hip technologies today: Angular, Bootstrap, and Spring Boot. All of these frameworks are wrapped up in an easy-to-use project called JHipster.

This book shows you how to build an app with JHipster, and guides you through the plethora of tools, techniques and options you can use. Furthermore, it explains the UI and API building blocks so you understand the underpinnings of your great application.

For book updates, follow @jhipster-book on Twitter.

10+ YEARS


Over 10 years ago, I wrote my first blog post. Since then, I've authored books, had kids, traveled the world, found Trish and blogged about it all.

All Java web frameworks should support hot deploy of a single class

In Anyone else using Groovy?, Tim Fennell (inventor of Stripes) raves at how much he likes Groovy now that it supports Java 5 features. He writes that Groovy might offer a solution to make development with Stripes faster:

The other thing I've been wondering about is that if there were enough demand for it we could try adding "improved" groovy support. E.g. throw your groovy actions under WEB-INF and we'll use groovy's built in stuff to do auto-reloading etc.

Gregg Bolinger responds with an excellent idea:

It would be really cool if Stripes could automatically discover and load changes to action beans (including new ones) without the entire app restarting, regardless of what the action bean is written in. But I realize that is a pretty tall order. :)

I agree that it might be a tall order, but I don't think it's impossible. In fact, I think all Java-based web frameworks should support hot deploy of a single class. We shouldn't have to buy JavaRebel to do this. It should be mandatory.

When an application reaches a certain size, the startup time can get pretty lengthy. This is lost development time. Furthermore, if any part of the development cycle takes longer than 15 seconds, there's a good chance developers will do something else (check their e-mail, move onto another task, etc.). Multi-tasking may be a good skill to have, but it's a horrible way to be productive.

Of the frameworks I'm familiar with, only Tapestry 5 and Seam support reloading single classes without restarting the whole application. Why can't the other frameworks "borrow" Tapestry 5's code? Maybe someone should just buy ZeroTurnaround and give away JavaRebel for free.

If I had one wish for 2008, it would be for all Java web frameworks to support this feature. Pretty Please?

Posted in Java at Jan 24 2008, 03:11:18 PM MST 21 Comments
Comments:

+1 to it.

Yesterday started Tap5 development, it's _awesome_. It's like back to PHP again :) working so damn fast.

But there is a serious drawback from live reloading - I can't work with any other framework (e.g. Tap4), the container restart is killing my productivity :( the only way is to rebell?

Posted by Renat Zubairov on January 24, 2008 at 04:54 PM MST #

I agree that java/j2ee has typically had a inefficient reload cycle. In 1997 nettdynamics, a java framework had hot reload!

Ways I combat the problem.

  1. write tests - UI should be easy if a service layer is well tested, and the ui doesn't have much code
  2. use zero turnaround (it works, and cheap)
  3. Don't do war copies to deploy , but instead use sysdeo tomcat eclilpse plug, or the jetty plugin- both allow running exploded war out of workspace. This can be difficult with maven, but possible if you use the maven ant tasks to copy pom dependencies intoo web-inf\lib (but i think maven in itself is not an efficient dev tool but...)
  4. wicket support reloading these days I think, but I haven't tried it yet
  5. I am not sure I think it is up to the web frameworks to implement this feature. I think zero turnaround has the best idea

Posted by James Law on January 24, 2008 at 05:12 PM MST #

As a person who spent a lot of time working on getting the class reloading to work, here's my 2 cents:

  • Web frameworks just can't provide it. The way is done in Tapestry 5 (and in RIFE, and we did it in Aranea)
  • works only for certain components in certain cases. And it won't work for Struts, JSF, etc. It never works for business/data access layer and will fail randomly for web. That's just life.
  • Class reloading should have be in the JVM! There is no other way to say that -- such functionality should have been essential in the JVM and whole Java development should have been built around it. This gaping whole is the reason we started ZeroTurnaround in the first place.
  • I'd be only too happy if someone bought out ZeroTurnaround and gave JavaRebel away for free. However that's unlikely to happen before the business mentality shifts away from production to development. Until then we have to make a living and we made JavaRebel very affordable (think 2000$ costing developer tools that IBM sells).

BTW just as a side point next week we are releasing the JavaRebel 1.1M1 with full support for annotation reloading and start working on frameworks like Stripes reloading their metadata without application redeploy. If anyone is interested in contributing, join our community.

Posted by Jevgeni Kabanov on January 24, 2008 at 05:41 PM MST #

I've been using the JBoss Seam incremental hot deploy feature since it's release about 6 months ago. I love it. I've done quite a bit of PHP and find that it isn't too much slower to deploy. For XHTML the deploy cycle is the same as PHP. For non-EJB components it takes only as long as the container takes to pick up the classes.

Posted by Damian Harvey on January 24, 2008 at 10:43 PM MST #

We've written a thing to run Jetty from our IDEs - see http://nicklothian.com/blog/2008/01/24/run-your-web-code-from-your-ide/ for details. It works pretty well - in debug mode you get hotswapping, too

Posted by Nick Lothian on January 25, 2008 at 12:25 AM MST #

It's true that there's some leaky metaphors with live reloading; Tapestry requires that the components be in specific packages to allow for live reloading (note: I consider this a plus even if live reloading wasn't available), and you get some class cast exceptions if you reference classes *inside* those packages from *outside* those packages.

However, as nice as 100% full reloading across all logical and physical layers would be, you get tons of bang for your buck with what's available in T5. My catch phrase is "I've never changed an EJB because I didn't like the color." As you move away from the database (changes are somewhat glacial) and towards the user ("can I use a different font here?") you need a tighter feedback loop for your modifications.

When a data transfer object (or Hibernate entity) changes, yes a full restart is required, taking (with Jetty) all of maybe three seconds. But with view logic changes, generally a give-and-take between the template and the component class, there's no waiting at all.

Yes, it's impossible to go back once you have this.

Posted by Howard M. Lewis Ship on January 25, 2008 at 12:53 AM MST #

yes a full restart is required, taking (with Jetty) all of maybe three seconds.

If a full restart takes 3 seconds what do you need live reloading for? The last project I worked on, full restart took 2.5 minutes! And Jetty does not make much of a difference, it's a great light container, but most of the reloading time goes to the applications.

Posted by Jevgeni Kabanov on January 25, 2008 at 02:12 AM MST #

Indeed, full restart of the application container (Jetty) is nothing comparing to the restart of the application,e.g. reinitialization of Hibernate (schema synchronization, mapping files reading) and initialization of the web framework (parsing of the templates). Also not to forget you need to bring your web application to the state where it was before (in case session do not survive container restart).

Posted by Renat Zubairov on January 25, 2008 at 04:02 AM MST #

"I think all Java-based web frameworks should support hot deploy of a single class."

I personnaly thing that all web container shoul support hot deploy of a single class. It's web container responsability, not web framework ?

Posted by Jean-Christophe Lagache on January 25, 2008 at 04:34 AM MST #

JavaRebel is really a great tool, I'm really glad that we bought it!

The annotation reloading in M1 sounds good, but wouldn't it be necessary to also update the internal metadata cache for each framework? Sounds like a tedious task to do, given the amount of java frameworks around (my vote goes for Stripes :-).

Are there any plans or JSR's for JDK7 for better support of class reloading at the vm level? I heard something about better support for dynamic languages, maybe Java could use some of this as well. Any info anybody?

Posted by digital.alterego on January 25, 2008 at 05:30 AM MST #

The annotation reloading in M1 sounds good, but wouldn't it be necessary to also update the internal metadata cache for each framework?

Yep. We are releasing the SDK as Open Source and hope for some contribution from community. Anyway, it is not always as hard as it seems. I did Guice in two days, and I never seen the codebase before.

Are there any plans or JSR's for JDK7 for better support of class reloading at the vm level? I heard something about better support for dynamic languages, maybe Java could use some of this as well. Any info anybody?

It is likely that Java 7 will get INVOKEDYNAMIC opcode, but this doesn't solve class reloading. Seeing that Java module system is slated to be included in Java 7 it's unlikely that any other classloading modifications will be included.

Posted by Jevgeni Kabanov on January 25, 2008 at 07:06 AM MST #

To re-iterate/re-enforce: the point of class reloading is to avoid container redeployment, since that will lose all session state and context.

Yes, Hibernate adds to the startup time, but just another couple of seconds (that's nice to avoid, with live reloading). Tapestry's class transformer and template parser and related technology are all very fast: in a very non-scientific test, I can see that the very first request into my integration test suite has to transform, parse and load 65 pages and a smattering of components, this all happens in 4451ms, about the time it takes to compile and load a JSP (order of magnitude, anyway). And having your start page hit 64 other pages is very rare, a typical application start page will have page links to only a smattering of other pages.

Posted by Howard M. Lewis Ship on January 25, 2008 at 09:23 AM MST #

This whole thread makes me appreciate the fact that I've been able to work with Rails the last ~6 months. I realize though that staying marketable means being willing and able to hop back into java if/when necessary. If and when the time comes, I hope it's not like moving from South Korea to North Korea.

Posted by Bryan Noll on January 25, 2008 at 11:10 AM MST #

@HLS: In some applications the hibernate startup time can be much longer. Our app takes about 15 seconds to do a full redeploy and the vast majority of that time, 12-13 seconds, comes from the hibernate startup. Maybe we have a more complex schema/more entities than is common, I don't know.

Also, Tomcat (not sure about other containers) have ways of persisting sessions across redeploys. We use it and it's worked well for us. So we do have to wait the 15 seconds for a redeploy, which sucks, but our sessions and context are still valid.

Posted by Tim Fennell on January 25, 2008 at 01:39 PM MST #

So let me get this straight: we're worrying here about developer productivity (via bouncing the app server) and the answer to this is hot deploy....while simultaneously and constantly talking about which web framework is the best?

How much developer productivity is lost di**ing around with adopting the framework of the moment? How many times do you need to relearn the same old stuff, albeit with a different framework?

How often do we need to hear the same old garbage arguments about Struts vs. JSF vs. Wicket vs. Tapestry vs. SpringMVC vs. RoR and how a "real developer" should be able to "pick it up in a few days"?

Posted by Tony on January 26, 2008 at 04:48 PM MST #

hear hear :)

Posted by Anonymous on January 27, 2008 at 03:50 AM MST #

Yeah Tony, all these frameworks. All these languages. With their own frameworks. Man, I just want my 9-5 job and apply whatever I learned years ago. Wouldn't everyone?

Posted by Eelco Hillenius on January 29, 2008 at 12:10 AM MST #

JavaRebel now and ultimately native JVM support is the way to go. It is sad that many frameworks - Tapestry, Rife, Wicket - all implemented their own incomplete solutions for class reloading. These frameworks should focus on what their good at, and let someone else - JavaRebel - do what they are specialized in. The more specialization, the better the end-result and the less duplication of effort.

Posted by Eelco Hillenius on January 29, 2008 at 12:14 AM MST #

I've found that you can enable true hotswap deployment in Jetty by hooking up a remote debugger to your Jetty server from Eclipse. Instructions here:

http://www.clickonchris.com/2010/05/configuring-jetty-maven-and-eclipse-together-with-hot-deploy/

Posted by Christopher Johnson on May 28, 2010 at 08:10 AM MDT #

Turns out there are patches against JDK7 to make JRebel-level reloading native to the JVM: http://wikis.sun.com/display/mlvm/HotSwap Unfortunately its doubtful that something so incredibly useful would actually make it into the JDK7 release.

Posted by Stephen Haberman on August 18, 2010 at 09:24 AM MDT #

Play! Framework (both 1.2.4 and 2.0 version) is damn good for hot reloading and more. As Play! Framework is now part of the TypeSafe stack, each modification is tested at compile time (even templates) and immediatly displayed in browser with, if needed, a exact description of the error.

Posted by Zofren on March 15, 2012 at 09:45 AM MDT #

Post a Comment:
  • HTML Syntax: Allowed