Tapestry Training -- From The Source

Let me help you get your team up to speed in Tapestry ... fast. Visit howardlewisship.com for details on training, mentoring and support!

Monday, May 01, 2006

Tapestry 5 Class Reloading

One of the big advantages of the scripting approaches to Web development (including JavaServer Pages at one extreme, and Ruby on Rails at the other) is the velocity of change: you can change a source file (a JSP, a Rails template, or even a Rails class) and see the change immediately.

Tapestry has traditionally been more aggressive at caching. Once a template or a XML file has been loaded into memory, it's stuck there. During development, you can use the -Dorg.apache.tapestry.disable-caching=true trick to turn caching off, but this not only slows down every request, but includes a memory leak that will eventually tank the application. It also does not reload classes the way it reloads templates and XML files.

In my quest to create a Java web development environment as compelling as Rails, one of the first things to tackle is this aspect of development: effective and efficient reloading of component classes.

The first pass at that code is now in the repository. Component classes are loaded in their own class loader (this is also necessary for the Tapestry AOP code that transforms classes as they are loaded into memory). When any transformed classes are changed externally, the class loader, as well as all instances derived from those classes, are discarded and a new class loader is created.

This will work quite well, far better than Tapestry 4's development mode. In production, you'll just throttle down how often Tapestry checks to see if underlying files have changed.

What's interesting is that I've been working, off and on, on this code base since mid-February. This compares to how long I spent on the initial prototype of Tapestry way back in January 2000, where I spent a couple of weeks of furious coding just to get to a simple "Hello World". In those couple of weeks, I "invested" Tapestry with many of the features that would grow with it, and support that growth, over the intervening years: the component hiearchy, the original and primitive form of templates, component parameter bindings, page loading, external XML page and component specifications, and other things long forgotten. To me, it was like winding up a spring ... all that upfront effort paid off with a basic design that was "right enough" to keep Tapestry innovative for many years.

The reason I'm starting with a new code base for Tapestry 5 is that it's time to wind up that spring again. The couple of design errors, only apparent after the fact, in Tapestry 4 are all but insurmountable without a fresh start (this primarily includes the requirement to extend base classes, but there are many more subtle things that need addressing). Further, the fact that I've spent a chunk of time getting the basic class loading and AOP support in place, the fact that anything web application is still weeks or months off, is actually a Good Thing. The spring is going to be wound nice and tight, full of energy for years to come.

21 comments:

Anonymous said...

Any chance for joining efforts?

http://jakarta.apache.org/commons/sandbox/jci/

And especially:

http://jakarta.apache.org/commons/sandbox/jci/apidocs/org/apache/commons/jci/ReloadingClassLoader.html

Anonymous said...

With this rewrite will backwards comptability remain a design goal, as before?

Unknown said...

Backwards compatibility is NOT a design goal. The fresh start, and the API approach (mostly, annotations) means that backwards compatibility for releases after Tapestry 5 will be much easier to maintain.

Dan said...

If backwards compatibility is not a design goal, then what about co-existing deployments (i.e. Tapestry 4 and 5 on Tomcat)?

We use Tapestry 4 extensively and like many organizations would want to reap the benefits of a new framework immediately without requiring a complete upgrade across the entire application base.

I would expect new users and new applications to adopt the new framework, but if backwards compatibility is not a goal then well-established systems may be slow in adopting Tapestry 5.

Tapestry 4 has been an exceptional addition to our application stack. Apart from the upgrades from 3.x (mostly self-induced design issues), the framework has been a blessing. The community is certainly as strong as ever and the frontrunner in web development (including Rails!). Keep up the good work!

Anonymous said...

Bravo, Howard, for:

(1) focusing on shortening the dev cycle, and for anything that helps simplify the big mess of Java app deployment; and

(2) having the chutzpah to abandon backwards compatibility.

Anonymous said...

Ahh, finally :) On the fly classloading alone would really be a big advantage for T5

Anonymous said...

So does this mean that Tapestry 5 won't be released until aroung 2008? I would think a ground-up rewrite could take a while...

Anonymous said...

Hmm... I'm evaluating Tapestry and JSF as possible frontends for a new ecommerce project. I appreciate it's still early days yet, but do you have any general advice about how to minimize the amount of recoding that would be necessary to upgrade the system when Tapestry 5 is released? Or is it just going to be a lot of work, no matter how the project is designed now?

Unknown said...

I wish I had a definitive answer on what the upgrade path will be from Tapestry 4 to Tapestry 5, as well as a schedule. It's very premature, as I blogged, things are very formative. I have every expectation that once the ball gets rolling, things will happen *very* fast. Much of the new design is to facilitate TDD for the framework (as well as applications built with the framework). 2007 seems more reasonable than 2008.

In the meantime, Tapestry 4 is still an excellent choice for building web applications. The goal is to make Tapestry (5) easier to learn and use, more powerful, more extensible, and faster. Tapestry 5 is already easy to learn, use, is powerful and is extensible ... just want Tapestry 5 to be much more so. I want Tapestry 5 to have the same level of advantage over Tapestry 4 that Tapestry 4 has over, say, Struts.

Unknown said...

I want to concentrate, for now, on the features and keeping it fast and clean. Perhaps there will be a compatibility mode of some kind, but the whole point is that Tapestry 5 will have a very different model from Tapestry 4.

Anonymous said...

Howard, does this solution solve the permgen problem? Our application is Tapestry and Hibernate based. After a handful of hot-deploys we always have to restart the application server because the permgen gets blown out.

Can the permgen space be reclaimed in Java 1.5 when you dump the classloader?

Unknown said...

About permgen: I honestly don't know at this point. It's something I'll have to look into once I have more of the framework in place. It seems likely. Tapestry 4 uses the same class loader and keeps adding classes to it. With a finite number of pages and components, that isn't a big problem, but in development mode (where each request creates a brand new batch of classes for each component on the page), you can run out of memory too quickly.

Tapestry 5 will only reload classes if it detects that some have changed, at which point, it discards the entire class loader and all instances instantiated via that class loader, and starts over from scratch.

Anonymous said...

Don't waver on backwards compatibility, make Tapestry 5 the best it can be.

Anonymous said...

I'm also for latest and greatest that Tapestry 5 can be. Don't sacrifice simplicity/power for sake of backward compatibility.

I took some time to convert all my web apps from Tapestry v3 to v4, and I'm glad. I don't care doing it again for v5.

Anonymous said...

Backwards compatibility is NOT a design goal.
This is why I'll move my app to JSF asap.

Dan said...

I'm very optimistic about the new features in Tapestry 4, and now 5, but there has to be consideration for compatability. This should be a goal. One of the biggest gripes against Tapestry has been the steep learning curve, lack of documentation, examples, etc. Wouldn't introducing a completely revamped framework just make matters worse in this regard?

Tapestry needs time to evolve, spread through the community, gain widespread adoption, and eventually surplant JSF. If a developer can't pick it up quickly and their manager can't be reassured about long-term compatability, they will go elsewhere for a solution.

I just don't want to see that happen.

Tapestry 4 hit the sweet spot for me, just like my first impression with Struts. I can't wait to see what comes with Tapesty 5, but I also don't want to see the community stretched thin.

Tapestry has an untapped potential to be the leading framework. As a proud developer and customer, I just want to see it get there.

Unknown said...

Dan,

You can see, even in these comments, that there are two opposing views on backwards compatibility. This is a serious issue for me, but staying compatible with Tapestry 4 simply isn't an option for me. Perhaps there will be an optional, limited compatibility layer. If the cost of upgrade is too high, Tapestry 4 will stay a viable option (hell, Brian is still improving Tapestry 3! The advantages of a larger, more active team).

In terms of learning curve, documentation and future compatibility: I'm adopting a document-as-you go approach, as well as a test-as-you go approach.

Further, the architecture of Tapestry 5 is expressly designed to insulate against future changes, meaning backwards compatibility can finally be meaningful in Tapestry ... starting at 5.

Dan said...

Howard,

As always, thank you for your sincere response. I think we all understand the challenge and will be better prepared to cross the bridge when it comes.

Point taken on starting pure backwards compatibility with Tapestry 5. I am very excited to see Tapestry evolve and hopefully Tapestry 5 will become the new standard in web developement.

I do have a question that is a bit off topic but nevertheless important:

Where would you recommend advertising a job opening for Tapestry skills (w/ Hibernate, Spring, etc.)? We are located in Ohio.

Unknown said...

So Howard, is Tapestry 5 going to be more REST-friendly?

Anonymous said...

Tapestry has a serious legacy building up that will PREVENT it from being adopted in commercial apps - lack of backward compatibility. We've built a mutual fund trading site that uses T3. We did not upgrade to T4 because the benefits couldn't be justified (major point: no new out of the box component that added tangible business value). And now it looks like T5 will be completely different again (this time hopefully it will simplify things).

Microsoft gets chided for delays and bloated code, but people underestimate the importance of backwards compatibility. You cannot justify spending 100s of thousands of dollars just to upgrade a framework to a business stakeholder who has already invested millions in an application.

Hopefully, I'm reading that T5 will have a long life. Otherwise we'll stay with T3.

Anonymous said...

allow me to contribute my two cents... I would say the page files and the "component" tags are good, so do the Annotations support in T4. However myself would prefer to write some of the components in the page files rather then using complete annotations in my java page files. Using the annotations in a substantial amount is fine in java page files, but using it completely in the in my java page file.. hmm it is quite messy .... don't you think so ?