I missed the JavaOne Comparing Web Frameworks talk and was appalled at some out-of-date information in it ... though reviewing his slides, it looks like he talked about Tapestry 5 but showed out-of-date Tapestry 4 examples. With Tapestry 5.3 ready very soon now (and less than a year after 5.2) it seemed like a good time to share some cool things about Tapestry:
- Tapestry Release Compatibility
- Tapestry 5.3 will be available soon; and for the majority of users, the upgrade is simply a matter of changing the version number in their pom.xml or build.gradle. Release compatibility was certainly a major headache from Tapestry 3 to Tapestry 4; and there is admittedly no direct upgrade path from Tapestry 4 to Tapestry 5 ... but Tapestry 5 was created from the ground up to prevent the kind of pain experienced in prior Tapestry releases. To wit:
- Services and dependency injection allows a fine-grained, not monolithic, approach to evolving the framework
- Metaprogramming of components allows new behaviors to be gradually introduced, bypassing the fragile base class problem
- Tapestry 5 has always carefully separated internal interfaces (which is not guaranteed to be stable between releases) from stable public interfaces. Literally, in packages named
.internal.so there's no guesswork about what's public and what's internal
- Tapestry Makes It A Snap To Work With Hibernate and JPA
- Tapestry has built-in modules for supporting both Hibernate and JPA. You get lots of stuff for free, including automatically configuring entities (just put them in the right package), easy transaction management, and smart encoding/decoding of entities ... Tapestry knows how to convert back and forth between entity instances and primary keys when building URLs.
- Tapestry Works Great With Spring
- Tapestry integrates very cleanly with Spring. You can inject Tapestry services into Spring beans, you inject Spring beans into Tapestry services and components.
- Tapestry Plays Well With Others
- Tapestry doesn't care if you have other servlets running in the same web application. You can fine-tune how it builds URLs, or even put Tapestry in a box so it doesn't collide with other servlets or filters. You can also easily share information with other applications.
- Tapestry Likes HTML5
- Starting in Tapestry 5.3,
<!DOCTYPE html>works perfectly in Tapestry.
- Tapestry Hot Deploys
- Tapestry (since 2006) has had live class reloading; change a template or a Java file and Tapestry reloads it instantly. And since its integrated into the framework, Tapestry can be very efficient about loading and reloading resources. Since 5.2, Tapestry has also live reloaded (most) service implementations. So code away! Tapestry can keep up with you.
Tapestry 5.3 adds vastly improved reporting of server-side exceptions, along with an easy way of presenting alerts to users.
- Tapestry Is Polyglot
- Tapestry doesn't care if your classes are written in Java, Scala or Groovy ... if it's bytecode, that's all that counts.
- Tapestry Is Fast And Getting Faster
- Tapestry has been getting faster and leaner with each release. 5.2 introduced page singletons (where a single page instance can be safely shared across many threads, even though it contains mutable fields) and 5.3 boosts the performance in a bunch of ways large and small. Tapestry 5.2 scored right at the top of this performance comparison, and Tapestry 5.3 is around 30% faster.
- Tapestry Has The Best Feedback Of Any Framework, Period
- Tapestry's approach to feedback goes far, far, far beyond any other framework or toolkit; it goes beyond the comprehensive exception report page and extends to small concerns throughout the framework:
- Tracking what the framework is doing, and why, at all times
- Including extra checks for common errors and building real messages that identify what went wrong and how to fix it
- Built-in pages to allow simple application monitoring
- Tapestry Really Gets Localization
- Localization support isn't an add-on; it's built-in from the ground up. Tapestry allows templates and other assets to be localized automatically: just follow the naming convention and Tapestry uses the correct file. Tapestry has localized messages for 14 languages and counting.
- Tapestry Is Customizable
- Tapestry's architecture, based on lots of individual services and dependency injection, means that almost any service or other logic in Tapestry can be overridden. Don't like how Tapestry builds URLs? Replace it seamlessly. Dont' like how Tapestry reports exceptions? Replace it! Tapestry is designed specifically so that you can augment or replace any behavior in the framework.
- Tapestry is a Meta-Programming Monster
- And I mean that in a good way; Tapestry has powerful support built-in for meta-programming at the services layer and at the component layer. Tapestry lets you get in and modify method invocations and field access, without getting your hands dirty with the ugly bytecode details. All the cool things Tapestry does with naming conventions and annotations is wide open for application-specific things. Meta-programming provides a critical alternate avenue of code reuse.
- Tapestry IoC Works Great On Its Own
- Tapestry's IoC library works great on its own, separate from the web framework itself. That includes live class reloading, meta-programming capabilities ... even a simple job scheduler.
... that's enough for now. The point is that Tapestry has a lot going on ... to paraphrase Philip Greenspun:
Any sufficiently complicated servlet or JSP web application contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Tapestry.
... and half is being very generous!