Tapestry is hands-down the worst framework I've ever used. It destroys your ability to reason about your code, because what you write looks like java but no longer follows java semantics (Want to initialize your page objects? You can't, you're expected to null-check your fields and reinitialize them every time you want to access them. Want to pass a parameter into a page you're linking to? Put an annotated field in your page that's typed to the other page, and call a magically-named method on it. I wish I was making this up). And it forces you to spread your flow logic between your pages and your templates; standard practice for repeater components is to have the logic for displaying the repeated component read the data it needs from a field on the outer component object, which is populated by the loop in the template. To get any sense of where data is coming from you have to flick back and forth between two files (actually usually more like six, because when you have multiple components on a page they're not isolated from each other in any way).
If you want a good web framework for Java, try Wicket. Components are real objects written in standard java, and proper separation between logic and presentation is enforced (because wicket markup files can't contain any logic).
My first ever programming job was a Tapestry 3 project. I had just finished computer school and had a strong understanding of Java but no field experience. We were using Tapestry and Cayenne (an ORM) and this whole, molasses-slow catastophe in the making, was my first introduction to the life of a professional coder. I still have strong paranoia and anxiety about any magical behaviour. But then the project went from v3 to v4 and everything broke. Zero backwards compatibility. Well - a bit dramatic. Nothing could be _trusted_ to work properly.
Tapestry is a reimagined WebObjects framework, and the company I worked for originally specialised in these systems, so it was natural for them to pick Tapestry. I also did a lot of translating/transplanting code from a WebObjects system to a Tapestry 4 system and everything the parent says was true for me. Work on a single component is spread across a minimum of three files, sometimes four, and there is a lot of magic which makes debugging (something you'll have to do a lot) a nightmare. I suspect Tap5 is incompatible and a wholly different beast to Tap4, but to this day I never want to work on a Java based web framework. Give me a pile of rotten php spaghetti any day of the week.
That said, I'm loving Clojure and might investigate Noir at some point in the future.
>I suspect Tap5 is incompatible and a wholly different beast to Tap4, but to this day I never want to work on a Java based web framework. Give me a pile of rotten php spaghetti any day of the week.
I might be getting a bit too evangelical here, but Wicket will change that. It actually uses the Java type system the way it's meant to be used (it's the only library I've ever seen that uses final classes and final methods effectively), and as a result its backwards-compatibility record is superb. It's so good that when writing wicket I don't even miss python.
Thanks for your comments. I am looking for a Java framework to learn. And Tapestry seems like a good candidate. I have just written a hello-world application in Tapestry. And I have no experience in developing using tapestry. My understanding from tapestry 5.2 docs is
1. Tapestry retains the state of the pages and components. (you need to annotate your state variables though). So, I am surprised that you need to reinitialize the field every time.
2. Tapestry provides parameter blocks to pass parameters to a component. It looks similar to a function call. What am I missing here?
Yeah, you can annotate fields to make them work, I'd forgotten that.
If you're writing good OO code then you write objects whose state gets set on creation. In wicket, if I want to redirect the user to another page (say after a form submission) passing in a parameter I can do setResponsePage(new MyOtherPageClass(parameter)). In tapestry that looks like randomAnnotatedField.magicMethod(parameter); return MyOtherPage.class . IIRC.
There's no type safety; if you misspell a tapestry magic method name it will just silently not be called. You can't step through your components in a debugger because your fields won't show up properly. It's particularly bad if you're just learning, because it seems to actively discourage good OO design, and because tapestry classes have subtly and not-so-subtly different semantics from real Java.
Yes, I understand the problems with "magic". One good thing about magic is that it reduces verbosity though. I have been programming in Rails for a few months now. I still prefer Python explicitness over Ruby magic.
If you want a good web framework for Java, try Wicket. Components are real objects written in standard java, and proper separation between logic and presentation is enforced (because wicket markup files can't contain any logic).