35

This question goes out to those who have used Tapestry as a web framework and then either gave it up or switched to something else, or even ported their application from Tapestry to something else.

The question is why? What led you to make this change?

EDIT: Also, what framework (if any) did you change to?

75 accepted

Why?

  1. Because Howard Lewis Ship is a liar. Calling version 3 and version 4, or version 4 and version 5 the same project name isn't merely disingenuous. It's an out-right lie. They are the same in name only. The Tapestry codebase is such a moving target that every major revision requires you to completely rewrite your application. Not just "tweak" your code. Completely rewrite it. Even point releases broke compatibility (4 -> 4.1). Upgrade paths were promised, then later reneged. "But this time it'll be different!" "Don't worry, upgrading from 5 to 6 should be extremely easy!" Fool me once, shame on you. Fool me twice...?

  2. Because Howard Lewis Ship doesn't care about building a community around the framework. See point #1. Thousands of Tap 3 developers were essentially given the middle finger when version 4 came out. All that time getting up-to-speed with Tapestry's notoriously steep learning curve, all for nothing. Same for those who drank the Kool-Aid and decided to rewrite their apps for version 4. Decided to try and convince their managers... "Say, you know all that money you just got through spending to build this Super-Duper app? Well, would you mind terribly approving another huge expenditure so we can rewrite it from scratch just to have the same functionality but remain current? He promises he won't do it again!"

  3. Because the exception messages are, without a doubt, the least helpful exceptions ever thrown. Ahh... RequestCycle, line 414, how I loathe thee.

  4. Obviously the steep learning curve.

  5. You'll find yourself constantly fighting with the framework. Just do a search for "The Tapestry Way" on tap-users and see what I mean. For instance, components can't be added dynamically. So imagine if you wanted to allow people to add tags to an image. You give them an input field and an "ADD MORE" button, and when they click that, another input field appears. Pretty tame stuff, right? Except that was impossible with previous versions (might still be, I don't know and I don't care). No, Tapestry used to have this asinine Rewind Cycle where it would compare all the values of the page state with a generated list (in a hidden input field) and if you had more fields than it was expecting... Exception. Granted, there were work-arounds. So. Many. Workarounds.

  6. Object instantiation was the pits. Every single domain member of the object path had to be instantiated beforehand or you'd get an exception. Here's an example:

    
    public void pageBeginRender(PageEvent event) {
      if (getClient() == null) {
        setClient(new Client());
      }
      if (getClient().getBusinessContact() == null) {
        getClient().setBusinessContact(new BusinessContact());
      }
      if (getClient().getBusinessContact().getAddress() == null) {
        getClient().getBusinessContact().setAddress(new Address());
      }
      ... ETC, ETC, ETC...
    }
    

  7. The whole supposed "benefit" of Tapestry was separating the layout from the controller, so theoretically you could have designers working on the styling while your developers worked on hooking all the components up. In practice this is next-to-impossible. With earlier versions of Tapestry, every single component had three files: a java class, a component template (yay! XML!) and the HTML. Every page, every widget, everything. Of course, you could always inline components in your HTML and make things really fun for new members of your development team.

  8. Ego. This is the same guy who gave us Hivemind (hivemind.apache.org), an inversion of control layer so much more powerful than Spring that they had to discontinue it. No great loss, as Hivemind was the most abysmally documented IOC ever devised.

  9. In the end, I (like many others) realized that Tapestry was simply a revenue stream for Howard Ship's consulting business. Which explains why the API keeps changing. Bigger, better, onwards and upwards!

These days we primarily use Stripes, because it does what we want it to, can be easily adapted to fit the corner cases, has a crap-load of built-in nice-to-haves, and... oh yeah, weighs in at only 480kb instead of Tap5's 20 Megs of libraries. With that much code you'd expect it to write the apps for you.

13

Disclaimer: I'm a Tapestry committer.

About some points given by Civil Disobidient:

1 and 2: The Tapestry past major version incompatibilities are really annoying, but Howard and the other committers are committed to not do it again. Tapestry 5 was built from the ground up to be forward-compatible. 3, 4, 5, 6, 7, 8: All the points are valid for to Tapestry 4, but not for Tapestry 5.

We invite everyone to take a look at Tapetry 5 now. Sebastian Hennebrueder wrote a very deep blog post evaluating Tapestry 5 as part of a Java web framework series.

9

I stopped using Tapestry in a corporate environment because I found it difficult to justify the risk of using a project with a single main contributor. However, if I (1) were to consider it for my own company, or (2) worked with an executive who was willing to take on the risk, perhaps by subsidizing the development of Tapestry, I would do it in a heartbeat. It is simply the best web development framework and IoC container I am aware of.

8

Here's content (a little out of date) created by someone who moved from Tapestry to Wicket:

http://cwiki.apache.org/WICKET/for-tapestry-users.html

But here's a blog post written by someone (who used to be a Tapestry committer no less), who switched to Apache Wicket and even wrote a book on Wicket:

http://agileskills2.org/blog/2007/09/my_thoughts_on_the_differences.html

Some "why I switched" testimony from someone who used Tapestry (and even wrote a couple of supporting frameworks) can be found here: http://www.mail-archive.com/users@wicket.apache.org/msg27146.html

Here's a comment from someone I knew to be a vocal supporter of Tapestry when I asked him why he switched from Tapestry (not sure, but I think he was leaning towards GWT):

Tapestry was great and served its purpose well ? no regrets ? it was the best framework for that generation ? but it can?t provide the desktop like RIA levels I was looking for moving forward.

FWIW, here's an IBM developerworks article that compared Tapestry 4 and Wicket:

http://www.ibm.com/developerworks/library/os-tapestrywicket/index.html

Update: Performance of Wicket and Tapestry 5 compared

8

I'm going the other way, I'm moving to T5.

I've recently moved from WebObjects to Tapestry 5. I've been using Web application frameworks since before there was java. I feel your pain for those who complain about backwards compatibility, I can see where you're coming from between T3 and T4, but I doubt there was much choice between T4 and T5. Frankly, at work we're still using WO 5.3 because it never seemed quite worth it to upgrade to 5.4, and WebObjects 5.3 -> 5.4 is supposed to be easy.

T5 is a radical re-thinking of how web application frameworks should be architected. As a consequence, the framework got radically simpler. I think that's a good thing.

I don't think you can blame Howard too much for the T5 change.

All of the Web application frameworks in java land are going to go through some upheaval as JPA/JSF/Bean Validation/GlassFish/JBoss go through their evolutions. It's ultimately going to be a good thing, but all of these frameworks have been riding rough seas lately. Perhaps he was going to change the name, but he was pretty up front about T5 being a radical redesign.

As for the Wicket fans, don't make me laugh. Wicket guarantees ugly websites by making it impossible to work with an artist.

Anyways, I chose T5 after surveying ALL of the existing web frameworks out there, because ultimately T5 was the simplest and most straightforward. Anything that would make it harder to work with an artist to make the site beautiful was immediately a showstopper, so that ultimately left 2: T5 and Facelets. T5 won because JSF just looked too cumbersome.

7

I used to use Tapestry and changed to use GWT.

Top 5 Reasons for changing:

1. Tapestry can be overly complicated and the learning curve is pretty steep for new developers who are starting out \ joining the team. Esp. on larger projects.

2. I found that I could develop "richer" applications using GWT seeing that my strength is Java not Javascript. In order for me to implement similar functionality using Tapestry I would have to hand write Javascript which would later become a maintenance nightmare.

3. Browser compatibility, I would spend large amounts of time trying to get my hand written Javascirpt to work on all the different browsers (like I said Javascript is not my strength :-) The GWT Compiler hides me from this which results in me spending more time writing features.

4. Back button blues, GWT's History listener is handles the browsers back button in comparison to Tapestry.

5. GWT has a smaller footprint because only the data is being sent across the wire apposed to refreshing the entire page.

The list goes on but all in all, I am very happy to have made the change and have not looked back since.

7

I've been using tapestry 4 since inception, and many of the rant reasons above have at one point or another given me pain.

The dojo/AJAX support is fairly lame and hardly works without a hack or 2.

The general documentation is sparse for some topics, while good for others.

A framework needs a good FORUM and not just a MAILING LIST. this is missing. (email is so 1970).

The learning curve was steep which may be why I'm hesitant to change my framework.

I've written quite a few more tapestry 4 apps since T5 became the development focus using T5 for new projects is still as daunting as ever.

each time i've considered using T5 i've given up after a couple of hours of not being able to write a from scratch simple app, and that doesn't say much for the beginners documentation.

EDIT

I am now using tapestry 5.2 and it is a vast improvement. If T3 and T4 were the stepping stones to this point I think the lack of backwards compatibility between them was a necissary evil. I think compatibility from T5 onwards will be much better (has been from 5->5.1->5.2). Ajax support is much better, dojo is gone in favour of prototypejs.

6

No way to create dynamically typed components, like WebObject's WOSwitchComponent. This was feasible (though quite complicated) in T4, but T5 is statically typed, so this powerful feature was lost, making it impossible to use any sort of runtime rules-based framework for rendering the view. In our case, this breaks the clean separation we have between view and controller in our WebObjects-based app.

5

Lots of reasons but the main one was breaking compatibility between v3 and v4. Just when we solved all those issues v5 came out and broke backwards compatibility again! Just couldn't go through that again.

Moved to Struts2. Less elegant but it works.

5

I used T3 on a real-world project, and it was OK; but mostly because I only knew of Struts 1 at the time so just about any other framework would seem better.

I didn't use T4 because I then discovered better alternatives, Stripes and Wicket being at the top of the list.

I really, really tried to forget about how much I hate HLS's attitude (I can't stand people who constantly pat themselves on the back) and gave T5 a good, honest look. I really actually wanted to like it because it would be another weapon in my arsenal. It sounded promising; however the awkward and unintuitive way of accomplishing common tasks coupled with the lack of consistent documentation resulted in a frustrating experience. Even a screencast by HLS himself shows the implementation of a simple counter and it doesn't even work as expected; you need to add some annotation to put the counter in the session. Are you kidding me?

Why do we need to deal with passivation and activation of pages? A clever framework would hide these details from you. Exposing the internals of the framework has always been a problem with Tapestry; this starts way back with Tapestry in Action, where the author constantly discusses how the framework is implemented instead of how you can use it to accomplish common web development tasks.

At the end of the day T5 is a huge disappointment because HLS talks about it like it's the greatest thing since sliced bread, but it really is not. Wake up Howard - you're a brilliant developer and how you implemented Tapestry may be very impressive on a technical level, but it's no good for the end user/developer if it doesn't address his/her needs. The fact that you started over from scratch so many times proves that you're in it for your own needs only.

4

For those who defend Tapestry with the suggestion that T5 absolves all of the issues with earlier versions, I would suggest T5 shows all of the flaws inherent with Mr Ship's previous efforts and adds a few more.

Too much stuff happens 'automagically' which is great when you want it to, and impossible to debug or fix otherwise.

Ship can't decide whether he wants code to express behaviour by convention or annotation, so supports both, documents neither very well and leaves teams to intermingle the two unless code style is ruled with a rod of iron.

The much vaulted claim to separate code and presentation is a deceit. Over simplistic conditionals in the view mean that any little change in UI behaviour has to be backed by a simultaneous code change. Components fragment any moderate sized web application into a plethora of interdependent widgets, each backed by three or more separate files which must be kept in sync. As all of the discovery is provided by package hierarchy, the codebase resists any attempt at management beyond the most simplistic strategies and all but the smallest project descends into a morass of hundreds of tiny files, impossible to navigate and miserable to debug. Without the benefit of explicit configuration to show which set of components contribute to a page or user action, you are left to trace through the dependencies until you happen to chance on the particular combination of components that have blighted your application.

By choosing his own conventions, Ship discards the great mass of useful development tools, particularly any providing vital validation of syntax and dependency.

Undoubtedly there are some very nice ideas there. Unfortunately, it's all or nothing with Tapestry. You can't chose the parts that work well and use other standard strategies where the framework is flaky. As he's thrown so many ideas into T5, there are bound to be some parts that don't fit the bill, and you just have to live with them.

Beyond that, further development on Tapestry runs at a snails pace (Ship seems to be devoting more time to yet another new framework, Cascade), and there are far too few contributors to the code base to keep it current or fix the omissions.

The bottom line is that development of any moderately sized web application is a pain. It requires a thorough understanding of the problem and all of the usual code management techniques to maintain a robust codebase. Frameworks spring up constantly, offering the possibility that much of this can happen automagically. In the simple 'Hello world' and student demo applications, everything appears to be wonderful. Scale up to anything larger, with a team working to deliver a maintainable web application, and the time saved is soon lost to dealing with an inflexible framework that introduces dependencies, unexpected 'features' and subtle assumptions about how your application should behave.

3

I've never used Tapestry myself, but as one of Wicket's committer probably the thing I heard most from people switching from Tapestry to Wicket (besides Tapestry breaking backwards compatibility without a good upgrade path every major release) is that Tapestry doesn't support the kind of dynamic behavior that Wicket supports. Or if it does, it's more tedious.

Personally, I like some of the ideas in Tapestry but also always thought it's developer(s) made the classic premature optimization mistake. It's funny that the premature optimization leads people to think that Tapestry will perform better (so that's good for marketing), though that doesn't always hold up in practice (as various benchmarks I've seen and executed myself have shown).

If you like Tapestry's declarative programming model better than Wicket's (or GWT's for that matter), I'd urge you to check out SiteBricks, which to me is Tapestry done the right way.

2

I haven't stopped using Tapestry yet, but I'm looking for ways out.

I wrote a blog post on the ups and downs of using Tapestry 5, long and short of it is that while the basics of the IOC are fine, the mvc is a nightmare (convention over configuration + ad hoc conventions = unmanageable mess), and the whole framework is simply immature, poorly documented and poorly supported.

I hadn't used Tapestry before 5, so the backward compatibility thing is not something I had to go through, though I can imagine how frustrating it would be.

2

Tapestry5 is great - although the Play framework looks also promising - especially the modules mechanism. An important factor is being able to use other peoples code - in order not to reinvent the wheel. Tapestry is only good if you do everything youself - most 3rd party libs won't work with the latest release and every time you end up getting other peoples code to work. Looking at other peoples code take time and you might want to do everything youself. If you have many developers and can afford to code everything yourself, go for Tapestry.

If you dont have much time or money, go for the Playframework or non-Java technologies such as PHP / YiiFramework, CakePHP or RubyonRails. I personally hate RubyonRails as I don't want to start at lesson one and learn a new language.

0

May be get back to James Gosling and ask- why he gave Duke's choice award to tapestry. Was it just beautiful looking code that he saw, or did he try to find out- whether its correct mathematical way of solving problem.

Go for RIFE. I tried to write a PSSServlet(1 day code , and thought for perhaps 15 days) - http://sourceforge.net/projects/pssservlet , and this happened to be just like RIFE. RoR founder supports RIFE and tells- that is the way for java to go.

think - what is correct way of handling javascript, should Swing ActionEvent map to seperate POJOs or is it just sufficient to pass HttpServletRequest around etc..

0

I thought i was thick for having such a hard time with Tapestry. turns out its really a shit framework. damn.