JavaServer Faces vs Tapestry - A Head-to-Head Comparison

Discussions

News: JavaServer Faces vs Tapestry - A Head-to-Head Comparison

  1. In this article, Phil Zoio puts these frameworks head-to-head, comparing each on its merits. He rates the two on critical aspects of their design, development and runtime environments. The intention is to provide users with a basis for making informed choices about the advantages and disadvantages of each, and for deciding which to choose when embarking on a new project. His comparisons are based on JSF 1.1 and Tapestry 3.0.3 (with occasional references to the forthcoming Tapestry 4.0 where appropriate).

    Read JavaServer Faces vs Tapestry - A Head-to-Head Comparison

    Threaded Messages (42)

  2. or blend the 2[ Go to top ]

    if you realy don't want to do RiA:
    http://facelets.dev.java.net/source/browse/facelets/src/test/com/sun/facelets/greeting.xhtml?rev=1.1&view=markup

    .V
    http://roomity.com
  3. Great article! I heard that you were going to be writing it up and getting input from both groups-- finally a worthwhile and legitimate comparison.

    I know that portlets are gaining speed, and just to provide you with an example of how easy it is to get JSF to work with portlets, all one developer had to do was override one method in Facelet's ViewHandler.
  4. "Tapestry does not rely heavily on tools. A couple of tools are available for the Eclipse IDE, which can be quite helpful. No WYSIWYG drag and drop visual design tools exist for Tapestry in the same way as for JSF."

    .... apart from Studio Creator. ;^)

    http://developers.sun.com/prodtech/javatools/jscreator/ea/jsc2/index.html
  5. Love the Icon[ Go to top ]

    Shouldn't Facelets look happier?
  6. Love the Icon[ Go to top ]

    Shouldn't Facelets look happier?

    It's just the look of contempt with itself, because it doesn't have annotations built in yet ;-)
  7. Love the Icon[ Go to top ]

    No. No. It has to be very serious, because it's "Enterprise".
  8. I think this is a very fair and balanced article. I found one minor mistake (components that render in code subclass AbstractComponent; BaseComponent is for components with a template).

    I'd also like to thank Phil (who let me preview the article) for including Tapestry 4.0 in the text (even if the examples are for Tapestry 3.0.3). I'm very, very excited about Tapestry 4.0 (and beyond!).
  9. This is a great in-depth comparison between JSF and Tapestry. My main comment is about the premise that action-based frameworks are on the way out. I think what's missing is that component- and event-based frameworks are better suited for handling the page/view, while action-based frameworks are *still* better for navigation/controller logic. Centralization of the logic/state, page flow, exception handling, etc. all fit more nicely in a framework that's removed from components and events. Just as Struts users had to shoehorn page event handling into controller actions, pure JSF/Tapestry users will shoehorn the controller tier into an event-handling framework that's more suited to intra-page events. I think that ultimately the framework of choice will use component- and event-based pages paired with an action-based controller tier.
  10. I think what's missing is that component- and event-based frameworks are better suited for handling the page/view, while action-based frameworks are *still* better for navigation/controller logic. Centralization of the logic/state, page flow, exception handling, etc. all fit more nicely in a framework that's removed from components and events.

    I've had similar thoughts when taking a look at many of the AJAXian oriented applications. Rich DHTML web applications are comprised of components interacting with components that interact with components... and all of the client-side behavior is intricate Javascript.

    We need server-side frameworks that let the client-side do its own thing, while still handling. page flow, exception handling, etc.

    --John
  11. Great article, very thorough. Thanks!
    Rich Feit: My main comment is about the premise that action-based frameworks are on the way out.
    Yep, that is my concern too.
    Indeed, the action-based model on which Struts is based is no longer regarded by many as ideal for Java web application development. While Struts and many other Model View Controller (MVC) frameworks from the early 2000s are largely operation-centric and stateless, the frameworks emerging most strongly are component-based and event-driven.
    * Action-based model != MVC (as well as more generic Front Controller != MVC)
    * Struts applications do not have to be stateless. I believe that Struts core developers and most book authors made a huge mistake by recommending using request scope for action forms instead of session scope. Trying to save some server memory resulted in a very inconvenient ways of saving and restoring state, and compromized user experience.
    * Struts applications can be event-driven by using standard DispatchAction or more sofisticated versions of it, like DialogAction.
    * Struts can be used to create simple JSP components.
    * It is not the model, which is "no longer regarded by many as ideal for Java web application development". Struts simply stopped in its development, while others kept moving on. Currently Struts is nothing more than a controller + XML config file + taglibs. Struts taglibs are less important now, since one can use JSTL. Validator is part of Commons, Tiles is recently ripped out as well. Thus, it is not the programming model which got obsolete, it is Struts itself, which does not provide enough services to be called "framework" today.
    * Microsoft's ASP.NET 1.x use Page Controller pattern. Realising the shortcomings of this approach, Microsoft includes support for Front Controller pattern into ASP.NET 2.0. Front Controller is what Struts, WebWork and Spring MVC is about. The concept itself is more flexible, than a page paradigm, but results in more procedural way of processing request, which may not seem to be object-oriented or event-driven and thus, not fashionable.
    Navigation. In JSF, you need to use a combination of code and configuration to transfer control to a different page after posting a form. ... You can specify navigation as a redirect rather than forward. ... In my view, it's a shame JSF retained Struts's mechanism for navigation. Navigation should be regarded as part of the application logic, not configuration.
    I might agree, that navigation may be better off, if coded right in the Java code. On the other hand, it takes only one XML element to switch from forwarding to redirecting in the navigation case. In many (all?) JSF examples managed beans are configured with session scope, and the state by default is handled on the server (JSF is able to keep state in the request/response chain, like ASP.NET's _viewdata request parameter). Therefore, by adding <redirect> to navigation rule, you can easy implement Redirect-After-Post pattern.

    Also, consider that navigation is defined in the Java code, while managed beans are still defined in external config file. What would happen if bean's scope is changed to "request", while Java code uses redirection? The application will break. So, either both bean definition and navigation definition should be in the code, or both pieces of information should be external, as they are now.
    JSF event model was designed to be similar to the JavaBeans event model. The main JSF event handlers are the action methods and the action listeners, both introduced in the previous section. Note that it is possible and sometimes necessary to define both an action listener and an action method for a component instance. This is because action listeners cannot influence navigation, while action events have no access to information on the component generating the event. Some users may find this distinction a bit confusing or even contrived.
    I do find the distinction confusing.
    The downside of Tapestry's data-centric approach is that it introduces a few subtle issues into the way that form submission is handled. Tapestry has no equivalent of the Restore View phase. To recover values obtained from form submission, it re-renders the same form, populating component properties and applying data bindings in the process. However, if the model data used to re-render the form changes, the rewound form is no longer in sync with the submitted data, resulting in a StaleLinkException.
    I did not get this one. If Tapestry re-renders form, using current state of model data, then re-rendered form will simply reflect the model changes, will not it? If the view is model driven, then I don't see the reason to throw exception. I would appreciate a better explanation for StaleLinkException.
  12. Tapestry records the current state of the page in a hidden field on the page. When the page is being re-rendered, the state being rendered is compared to the one in the hidden field, if they dont match, the StaleLinkException is thrown. This is done to prevent problems with Back button, Refresh etc.
  13. Tapestry records the current state of the page in a hidden field on the page. When the page is being re-rendered, the state being rendered is compared to the one in the hidden field, if they dont match, the StaleLinkException is thrown. This is done to prevent problems with Back button, Refresh etc.

    Actually, it's about making sure the right properties of the right objects are updated. Generally, this only bites you when your Form includes a loop, such as a Foreach component, and is editting multiple domain objects within a single form (often in a master/detail relationship: think order and line item in a shopping cart).

    MindBridge has added the For and If components to Tapestry 4.0, which automatically encode state into the form (as hidden form fields) to take care of this kind of thing pretty much automatically. I was just updating my labs (the materials I use when teaching Tapestry to clients) to discuss the For component ... and what was an entire lab on ListEdit becomes a short section of another lab. Simpler is good.
  14. Tapestry records the current state of the page in a hidden field on the page. When the page is being re-rendered, the state being rendered is compared to the one in the hidden field, if they dont match, the StaleLinkException is thrown. This is done to prevent problems with Back button, Refresh etc.
    Recalling the article, redirecting from input phase to render phase in Tapestry is "clumsy" and apparently was not supposed to be used.Thus, a Tapestry application is supposed to return a page immediately in response to posting a form. So the "state hidden field" is just a token in Struts parlance. You probably wanted to say "when the form is implicitly resubmitted and page is being re-rendered" instead of just "when the page is being re-rendered". Seems to me like one more reason to use Wicket, which cleanly separates input phase and render phase.
  15. Tapestry records the current state of the page in a hidden field on the page. When the page is being re-rendered, the state being rendered is compared to the one in the hidden field, if they dont match, the StaleLinkException is thrown. This is done to prevent problems with Back button, Refresh etc.
    Recalling the article, redirecting from input phase to render phase in Tapestry is "clumsy" and apparently was not supposed to be used.Thus, a Tapestry application is supposed to return a page immediately in response to posting a form. So the "state hidden field" is just a token in Struts parlance. You probably wanted to say "when the form is implicitly resubmitted and page is being re-rendered" instead of just "when the page is being re-rendered". Seems to me like one more reason to use Wicket, which cleanly separates input phase and render phase.

    I'm afraid you don't understand how Tapestry works internally. During a form submission, Tapestry uses the rendering engine to re-visit each component within a form, in the order in which they components were originally rendered. This allows the same basic mechanism to handle truly hideous cases, such as deeply nested loops and conditionals. MB's For and If components take the bite out of this (by doing all the managing of hidden form state for you, rather than leaving you largely on your own as in earlier versions of Tapestry).

    Tapestry's core design value is to have the page structure (that is, the page, its components, all the templates, all the parameters, etc.) be completely static, and to be highly dynamic while rendering). This is key to Tapestrys efficiency principle, since it allows for aggresive caching of data within pages, and aggressive pooling of pages between different request and different users ... without requiring that pages be stored into the HttpSession.

    JSF and Wicket have to serialize and/or store the component tree for each page and each user; JSF appears to do this using a serialized object stored in a hidden form field. Wicket stores it in the HttpSession.

    Tapestry's approach minimizes the amount of user data that needs to be stored in the HttpSession; using client-persisent page properties (new in 4.0) its even possible to avoid the HttpSession entirely. In fact, you have fine grained control over which properties are persisted and where (and even, for how long).
  16. Recalling the article, redirecting from input phase to render phase in Tapestry is "clumsy" and apparently was not supposed to be used.Thus, a Tapestry application is supposed to return a page immediately in response to posting a form. So the "state hidden field" is just a token in Struts parlance. You probably wanted to say "when the form is implicitly resubmitted and page is being re-rendered" instead of just "when the page is being re-rendered". Seems to me like one more reason to use Wicket, which cleanly separates input phase and render phase.
    I'm afraid you don't understand how Tapestry works internally. During a form submission, Tapestry uses the rendering engine to re-visit each component within a form, in the order in which they components were originally rendered. This allows the same basic mechanism to handle truly hideous cases, such as deeply nested loops and conditionals. MB's For and If components take the bite out of this (by doing all the managing of hidden form state for you, rather than leaving you largely on your own as in earlier versions of Tapestry).

    Tapestry's core design value is to have the page structure (that is, the page, its components, all the templates, all the parameters, etc.) be completely static, and to be highly dynamic while rendering). This is key to Tapestrys efficiency principle, since it allows for aggresive caching of data within pages, and aggressive pooling of pages between different request and different users ... without requiring that pages be stored into the HttpSession.

    JSF and Wicket have to serialize and/or store the component tree for each page and each user; JSF appears to do this using a serialized object stored in a hidden form field. Wicket stores it in the HttpSession.
    I am afraid that several topics got mixed up in the discussion, like:
    * client behavior and page navigation (posting a form, receiving rendered page in response, redirect or not)
    * server behavior (different methods to render components and to read input data from client into components)
    * state management (server side: session, another memory object, serialization to disk; client side: state hidden field)

    It seems to me that you are trying to explain how Tapestry renders components and how it reads input from client back into components. While this information is educational, it does not disagree with my note that "a Tapestry application is supposed to return a page immediately in response to posting a form". My statement is merely an assumption since I have not used Tapestry (yet?), so if I am wrong, please correct me. Also, being build with Tapestry, TSS uses redirection after a comment is submitted, so I might be wrong in my conclusion.

    Considering efficiency, you suggest that Tapestry is better that JSF or Wicket, because data and pages (isn't it the same thing, unless by pages you mean HTML) can be cached and pooled. Unless these pages are serialized to disk, they are pooled in memory. Unless the pool or cache is establieshed only on one machine in a cluster, the pages has to be spread through all servers. How is this better compared to clustered HttpSession?
    Tapestry's approach minimizes the amount of user data that needs to be stored in the HttpSession; using client-persisent page properties (new in 4.0) its even possible to avoid the HttpSession entirely. In fact, you have fine grained control over which properties are persisted and where (and even, for how long).
    Are you talking about ASP.NET's "_viewstate" equivalent for Tapestry? Well, I believe that "_viewstate" is one of the most ridiculous things that Microsoft ever created. I hoped that javaland would not pick up this disease.
  17. Considering efficiency, you suggest that Tapestry is better that JSF or Wicket, because data and pages (isn't it the same thing, unless by pages you mean HTML) can be cached and pooled. Unless these pages are serialized to disk, they are pooled in memory. Unless the pool or cache is establieshed only on one machine in a cluster, the pages has to be spread through all servers. How is this better compared to clustered HttpSession?

    Pooled Tapestry pages do not need to be spread through all servers because they contain no state. Each server has its own pool independent of the others. It's not that pooled pages are better than clustered sessions, they are irrelevant to clustered sessions.


    Regarding efficiency, Tapestry is indeed better than JSF or Wicket because Tapestry's approach to state management leads to much lower per-session memory requirements. You can realistically expect Tapestry sessions to be about 1/10 the size of Wicket sessions. While I don't know enough about JSF to throw out a hard number, like Wicket, JSF stores entire component trees in the session, so I would expect the memory requirements to be similar (correct me if I'm wrong).


    In response to statements made by Wicket developers attempting to belittle the importance of session size and claiming that other bottlenecks will be encountered before the order of magnitude difference in memory consumption is noticeable, allow me to run through a few scenarios:


    1.) A single-server application has a lot of concurrent users, isn't very CPU-intensive and is running on a server with 2GB of RAM. A 10x memory savings might come in handy, especially when batch processes are running or if you want to cache lots of persistent objects or query results.


    2.) Your app runs in a web farm with a central database server for shared sessions (a nice, simple architecture that scales well up to the point of database saturation). Since the database server is the bottleneck (and you can't improve the situation very much with typical master/slave database replication due to the update-heavy nature of session data), 10x less data throughput is going to make a big (although not at all linear) difference in how many front-end servers you can add.

    3.) Your app gets DDOS'd. The bots aren't nice enough to send back session ids so each request creates a new session. Now your session count has no relationship to concurrent users and very little to request throughput. Session size, however, has a direct relationship to uptime. To make this scenario more relevant, consider that regular traffic spikes and surges are no different than temporary DOS attacks as far as the server is concerned: you end up with lots of extra sessions sitting around that don't correlate nicely to concurrent users or throughput.


    4.) Some bizarre requirement from the geniuses in marketing translates into keeping sessions alive for a week. While there always other approaches, if your sessions are small enough and load is relatively low, it might be perfectly acceptable to just crank up the timeout and deal with 50 or 60 thousand sessions (even if it's only until you restructure and implement a better solution). This happens, and it's nice to have the headroom if you need it.

    5.) You are clustering sessions in memory. Each server you add increases the per-server session memory requirements due to replication. In fact, session memory is the only resource that doesn't scale linearly (assuming you're in a data center where you can just buy more external bandwidth on demand and that you're running 1000Mb ethernet inside the cluster).


    The point I'm trying to make is that session size can certainly be a scalability bottleneck and is almost always at least an important factor in determining the scalability of a system.
    Are you talking about ASP.NET's "_viewstate" equivalent for Tapestry? Well, I believe that "_viewstate" is one of the most ridiculous things that Microsoft ever created. I hoped that javaland would not pick up this disease.

    No, he's talking about client-side state. Microsoft hardly invented the idea. You may have legitimate gripes, but maintaining state on the client is a proven and simple (if the framework supports it) method to get extremely high scalability. Client-side state also allows users to conduct multiple simultaneous sessions, which can be quite useful (full client-side state of course isn't required for this, it's just a natural side effect). Once again, session size is critical as the two primary issues (setting aside opinions about application behavior) with client-side state are security (use an HMAC to solve this) and bandwidth. Even broadband users have low upstream bandwidth so a 20KB increase in request size might not be acceptable whereas a 2KB increase isn't likely to be noticed.
  18. Once again, session size is critical as the two primary issues (setting aside opinions about application behavior) with client-side state are security (use an HMAC to solve this) and bandwidth.
    This is one of these discussions that never ends with agreement. You consider performance and number of concurrent sessions to be more important than usability. I prefer to have more usable, forgiving and "nice" webapp. I am a human, I can click Refresh or Back anytime I want, or I can go somewhere else and then return back, and I don't want to lose my information, I don't want to see scary and ugly dialogs and I don't want to see the same page five times on my way back only because I've made five attempts to submit it.

    I guess, one of the fundamental differences between Tapestry and Wicket is that Wicket is built around two-phase request processing, separating submit and render phases. It uses more session memory, but the applications are pleasant to develop and to use. Apparently, Tapestry uses simpler (from client perspective) request/response lifecycle, which it has to compensate with tokens.

    I am extremely happy that Wicket allows to build an application that behaves exactly as I like. I can save on creating my own framework ;)
  19. This is one of these discussions that never ends with agreement. You consider performance and number of concurrent sessions to be more important than usability.

    I get your point, but usability is determined by my users. Tapestry has been invisible to my users so far and they have not requested any behavior that is impossible or even difficult to accomplish with Tapestry. There hasn't been any perceived lack of usability with Tapestry.


    It's not that I *prefer* scalability, the issue is that some (certainly not all) of my applications *require* high scalability to remain available and acceptably performant given the expected load and allotted hardware.

    So, from my point of view, Wicket's superior usability is strictly theoretical (meaning that I both haven't had a need and that I'm not convinced it exists) while Tapestry's superior efficiency is real, valuable and not really debatable. I imagine that from your point of view, the opposite is true. I wouldn't disagree in the slightest. Those are both entirely legitimate opinions that depend on the needs and priorities of your application and your past experience.

    I prefer to have more usable, forgiving and "nice" webapp. I am a human, I can click Refresh or Back anytime I want, or I can go somewhere else and then return back, and I don't want to lose my information, I don't want to see scary and ugly dialogs and I don't want to see the same page five times on my way back only because I've made five attempts to submit it.

    I can personally assure you that many humans are quite happily using applications written with Tapestry and experiencing no ill side-effects. Tapestry's persistence model is very flexible and intuitive, so one can quite easily go somewhere else and then return back without losing any information whatsoever (probably like Wicket, this requires no code to achieve in Tapestry) or seeing any scary or ugly dialogs. I just now tested a Wicket form to be sure of this, and guess what happened after I submitted it five times and then started hitting the back button? I revisited the form five times. This behavior is a function of HTTP, cache headers and your browser - not a framework. The difference in the frameworks would come in when you submit old versions of the form. Wicket had an advantage over Tapestry 3.0 in this area but it's down to another theoretical and debatable advantage given Tapestry 4.0's handling of stale forms.
    I guess, one of the fundamental differences between Tapestry and Wicket is that Wicket is built around two-phase request processing, separating submit and render phases. It uses more session memory, but the applications are pleasant to develop and to use. Apparently, Tapestry uses simpler (from client perspective) request/response lifecycle, which it has to compensate with tokens.

    Well, request processing between the two frameworks is different but it's actually Wicket's model that would better be described as "simple". Tapestry uses various engine services that each handle the request/response cycle in ways that are optimized for different behaviors (as mentioned in the article). You can also create your own engine services if desired, so request/response cycle handling in Tapestry is extremely flexible. And I guess I didn't make this clear earlier: Tapestry does not use "tokens." With 4.0 it is now possible - although entirely optional - to store state on the client side but this is a new feature intended to further minimize server-side state, which, as I noted in my last post, is often a good and useful option to have.

    I think you really need to suspend your criticisms (which are nearly all based on incorrect assumptions) until you write an application or two in Tapestry. I have no such criticisms of Wicket, (and I know so little about JSF that I just don't have an opinion) I only know that Tapestry is highly productive, built for efficiency, and is mature and stable enough that I'm comfortable staking my clients' businesses on it. Wicket looks great and I'll spend more time with it in the future, but - for now - it fails on those last couple of points.
  20. I can personally assure you that many humans are quite happily using applications written with Tapestry and experiencing no ill side-effects.
    From my side, I can assure you that many humans are quite happily drive cars with manual transmission and think this is the way cars to be driven.
    I just now tested a Wicket form to be sure of this, and guess what happened after I submitted it five times and then started hitting the back button? I revisited the form five times. This behavior is a function of HTTP, cache headers and your browser - not a framework.
    This behavior is a function of HTTP, browser and a framework. Separating input and output by using "do-and-redirect" and "get-and-show" actions (in Ruby-On-Rails parlance) allows to achieve such behavior with most browsers (do you use Opera? then you are out of luck), while using solid "submit input data, respond with result page" process does not allow this, because this is how current HTTP spec is defined. It is possible with Struts as well.
    And I guess I didn't make this clear earlier: Tapestry does not use "tokens." With 4.0 it is now possible - although entirely optional - to store state on the client side but this is a new feature intended to further minimize server-side state, which, as I noted in my last post, is often a good and useful option to have.
    Right, please forgive me for calling "viewstate" a "token".
    Tapestry's persistence model is very flexible and intuitive, so one can quite easily go somewhere else and then return back without losing any information whatsoever
    Is this possible with client-stored state?
    I think you really need to suspend your criticisms (which are nearly all based on incorrect assumptions) until you write an application or two in Tapestry.
    Based on the article, I made an assumption that two-phase request processing aka Redirect-after-Post is not a standard thing for Tapestry, and this assumption was not contestedr. I am not saying that this is inadequate in any way. I am just saying that I personally prefer to use redirection, therefore I am looking into Wicket, which provides behavior needed to me out of the box.
  21. This is really an unfair synopsis of our position on Wicket's sesion use. Although I agree that session size is not nearly as important for most projects as people think, we do not have a heads-in-the-sand attitude about scalability. While it is true that Wicket is session heavy /by default/ (and therefore extremely easy to work with in terms of model state, which is virtually transparent), the idea driving overall architecture is that you will be able to scale it to be more and more session light as need be, by putting in more effort where the session size "hot spots" are. You can use detachable models, for example, to make your session more lightweight as a first step. Then if that simple step is not enough, you can create PageState classes that represent "dehydrated" versions of pages that can be replicated in a clustered environment. Finally there are plans to add client-side state to get to the very same kind of zero-state applications you're talking about. But the advantage of Wicket's architecture, unlike Tapestry, is that you will be able to get sessions that are as lightweight as you need them to be - BUT NO MORE. You don't have to code your 10 user intranet application or your small to midsized public web application to the needs of Amazon.com.
  22. This is really an unfair synopsis of our position on Wicket's sesion use. Although I agree that session size is not nearly as important for most projects as people think, we do not have a heads-in-the-sand attitude about scalability. While it is true that Wicket is session heavy /by default/ (and therefore extremely easy to work with in terms of model state, which is virtually transparent), the idea driving overall architecture is that you will be able to scale it to be more and more session light as need be, by putting in more effort where the session size "hot spots" are.

    I totally agree, you made some excellent points. Even in the struts days (i feel odd saying that), people were asking craig about scalability and what decisions developers need to make. One one hand you can create a lot of difficulty for yourself with managing view state on your own, or you can be more productive and use JSF, Tapestry, or Wicket and scale by throwing more hardware at the problem. Memory is cheap-- programmers' time isn't.
  23. Memory is cheap-- programmers' time isn't.

    Please stop it. As mentioned several times, both in the article and here, Tapestry 4 does not require you to think about rewinding, etc, as the issues are handled automatically for you. Most programmers will not even know what that means.

    So you get the best of both worlds with T4: small sessions (or NO sessions) and simple code that is already far simpler than most alternatives out there (and that includes a hell of a lot of the JSF flavours).

    This whole discussion seems to me to be one big red herring. JSF has some advantages, but this is most definitely not one of them. This is not only about memory, it is about bandwidth and CPU as well. This is a big weakness, especially in commercial development.
  24. Please stop it. As mentioned several times, both in the article and here, Tapestry 4 does not require you to think about rewinding, etc, as the issues are handled automatically for you.

    Did you even read my last post? I was talking about going from stateless struts-type frameworks to the more feature-rich frameworks you see today. There is more overhead-- aslo notice I made no comparative statement between the frameworks being discussed.
  25. Sorry, bad choice for a message to reply to. It's just that it seems to me that the discussion is taking the wrong turn. My message was a reaction to the topic as a whole, not your message in particular. Apologies.
  26. I was talking about going from stateless struts-type frameworks to the more feature-rich frameworks you see today.
    I wonder if stateless struts-type frameworks include Struts itself, because Struts applications do not have to be stateless, as I already have shown. Struts can even be used to create simple and relatively isolated web components.
  27. I just realized it wasn't quite clear what I was responding to because I responded to the wrong message. It was:

    "Regarding efficiency, Tapestry is indeed better than JSF or Wicket because Tapestry's approach to state management leads to much lower per-session memory requirements. You can realistically expect Tapestry sessions to be about 1/10 the size of Wicket sessions. While I don't know enough about JSF to throw out a hard number, like Wicket, JSF stores entire component trees in the session, so I would expect the memory requirements to be similar (correct me if I'm wrong).

    In response to statements made by Wicket developers attempting to belittle the importance of session size and claiming that other bottlenecks will be encountered before the order of magnitude difference in memory consumption is noticeable, ..."

    My points are:

    1) I agree that Wicket sessions /by default/ are heavier than Tapestry sessions, although I have no idea where the number 1/10th came from and I am not aware of any performance comparison between the two frameworks of this nature

    2) The current approach that Wicket takes does not limit our ability to provide session weight tuning in the future. In fact, the PageState mechanism in Wicket 1.0 provides considerable ability to do that today and very elegantly

    3) We have architectural ideas that will permit us in the near future (as soon as anyone really pushes Wicket into a scalable environment, I imagine) to achieve low state and zero-state

    4) Wicket is a much younger framework and it will take adoption by companies and individuals with scalable use cases to drive the above features

    5) Although there have been statements made about the importance of session size for most projects, we do understand what scalability is and why it is desirable and we have workable plans for the framework that can take this on with what is IMO a much neater and more OO approach to the problem of scaling

  28. 2) The current approach that Wicket takes does not limit our ability to provide session weight tuning in the future. In fact, the PageState mechanism in Wicket 1.0 provides considerable ability to do that today and very elegantly

    3) We have architectural ideas that will permit us in the near future (as soon as anyone really pushes Wicket into a scalable environment, I imagine) to achieve low state and zero-state

    4) Wicket is a much younger framework and it will take adoption by companies and individuals with scalable use cases to drive the above features

    5) Although there have been statements made about the importance of session size for most projects, we do understand what scalability is and why it is desirable and we have workable plans for the framework that can take this on with what is IMO a much neater and more OO approach to the problem of scaling

    Sounds like you recognize that session efficiency is important and some significant changes are coming to Wicket in the future. OTOH, Tapestry has extremely efficient session management *right now*.
  29. But the advantage of Wicket's architecture, unlike Tapestry, is that you will be able to get sessions that are as lightweight as you need them to be - BUT NO MORE.
    "NO MORE?" It sounds like you're implying that there is some kind of disadvantage to lightweight sessions.
    You don't have to code your 10 user intranet application or your small to midsized public web application to the needs of Amazon.com.
    This is an oversimplification. A 10-user app and Amazon are somewhat rare and extreme examples. Isn't scalability important for a mid-sized public app running on a single server? Or what about multiple low-traffic apps? Certainly anything running on the internet is exposed to potentially volatile and unexpected loads, so more headroom is always a good thing.
  30. "NO MORE?" It sounds like you're implying that there is some kind of disadvantage to lightweight sessions.

    Yes there is. State is not handled transparently. I don't know about Tapestry 4, but with Tapestry 3 this was /the/ reason for me /not/ to use Tapestry and go for Wicket instead. Furthermore, because the state has to be kept and re-applied somewhere, Tapestry has to manage the pages and components lifecycle.
    You don't have to code your 10 user intranet application or your small to midsized public web application to the needs of Amazon.com.
    This is an oversimplification. A 10-user app and Amazon are somewhat rare and extreme examples. Isn't scalability important for a mid-sized public app running on a single server? Or what about multiple low-traffic apps? Certainly anything running on the internet is exposed to potentially volatile and unexpected loads, so more headroom is always a good thing.

    No it isn't an oversimplification. I work for a company that spits out medium-large scale webapplication all of the time. Session size isn't a problem. Usually bandwith, database scalability and actual memory leaks (we've had them in the ORM layer, JSP taglib handling, JDBC drivers) are bottlenecks long before session session even becomes a minor concern. It /is/ a good thing to have predictable session size (which is far more important than how large that size is), so that you can tweak for it. It is a good idea anyway to take all 'enterprise' concerns seriously. You can count on Wicket addressing that even further in the comming year. But... I'm also one of the people that get very tired of the heavy approach that stands for J2EE/ Java. There are many ways to address scalability, and optimizing session size is just one of them. In the end it usually /is/ just optimization, and yes, I agree with other people that developer productivity is a serious concern for Java. And you can see from RoR that this doesn't have to be addressed with tools and layering framework on framework.
  31. SF appears to do this using a serialized object stored in a hidden form field. Wicket stores it in the HttpSession.Tapestry's approach minimizes the amount of user data that needs to be stored in the HttpSession; using client-persisent page properties (new in 4.0) its even possible to avoid the HttpSession entirely. In fact, you have fine grained control over which properties are persisted and where (and even, for how long).

    To be correct, JSF has built in functionality to either serailize it into hidden fields (client) or store it in the session (server). That's not to say that I couldn't replace it with my own StateManager implementation. JSF though, the view trees could be different between each user, so it wouldn't do much good to pool them. Keep in mind, that the whole page isn't stored with JSF, just form controls w/ a couple components. On average, probably only 50% or 15% of the page content actually would need to be persisted-- somewhere.
  32. Recently put in Tapestry 3.0.3 as the new Standard within our organization - mainly because productivity seemed 2-3 times faster than JSF. Tapestry does make it very easy to create and abstract out components.

    However, Tapestry does have some issues that reduced our productivity alteast in the short run. Trying to debug a rewind cycle bug consumes a lot of time - and still not sure where we can place initialization and update logic without accidently tripping on the rewind cycle.

    I've ended up recommending folks to place all their init & update logic in pageBeginRender() using big/chained if (xyz == null) then initXyz() or if (changeXyz) then changeXyz() type logic. This works for both Pages and Components for th e most part.

    Also the having different components for Form vs. Non forms causes issues. They could be abstracted out better.
  33. Also the having different components for Form vs. Non forms causes issues. They could be abstracted out better.

    I believe the issue is resolved in Tapestry 4. The If and For components combine the Form/non-Form variants. The correct approach is automatically used depending on whether you are in a form or not.

    In other words, the stale session exception is pretty much a thing of the past.

    The Tapestry 3 version of those components is available in the Base library on T-Deli (http://www.t-deli.com). In case this is needed, the site also provides access to the Workbench application that demonstrates the main Tapestry features. See:

    http://www.t-deli.com/workbench/app
  34. Excellent article.

    But regarding the learning curve with Tapestry 4, I don't think documentation is lacking and it's necessary to learn Hivemind for beginners. They can certainly get started and become productive (see http://agileskills2.org/EWDT/chapters1-4.pdf) including using application state objects without understanding the concepts in Hivemind such as services, thread models, service factories, schemas, configurations.
  35. Althought a very useful article, it completly ignores framework performance criterion.

    Did anyone test the framework overvead (memory and CPU) for JSF, Tapestry, and maybe compare to other framework, like Struts?

    Catalin
  36. Althought a very useful article, it completly ignores framework performance criterion.Did anyone test the framework overvead (memory and CPU) for JSF, Tapestry, and maybe compare to other framework, like Struts?Catalin

    Felipe (JSP EG) had a presentation at JavaOne on MVC bottlenecks. He compared JSP, Struts, and JSF 1.1. The JSF solution had 4% less throughput over the Struts solution (I might be off on that number).

    The take-away from that presentation was that the bottlenecks weren't the MVC frameworks, but polling data from the db and such. I just remember them saying that they were expecting to have a substantial difference in performance between the frameworks when everything was pretty consistent.

    If you ask me though, all of the tests were on top of JSP and it would have been cool to see what kind of numbers Velocity or Facelets would put up. Tapestry wasn't compared, but again, I would've been interested to see those numbers too.

    -- Jacob
  37. Nice, thorough article - Kudos[ Go to top ]

    I just had a quick read of this article and am very impressed with the thoroughness.

    Articles like these can only help foster for more enlightended discussion about these new Web frameworks as opposed to the often ill-informed FUD that tends to prevail when these new technologies are discussed in public.

    Nice Job!

    -Chris

    p.s. I was also flattered to see that you cited my JSF managed beans IoC container article at:
    http://www.oracle.com/technology/tech/java/newsletter/articles/jsf_pojo/index.html
  38. Different output media[ Go to top ]

    What if I need to output some data tables, agreement forms etc. in a non-html format (pdf for instance), quite common requirement? Can someone compare JSF and Tapestry on these areas also - I mean in support for different output media or am I missing the topic here?
    Had a situation with Tapestry 3.0 where I needed to simply output raw log files to browser, without any html and correct http headers explicitly set. Could not figure out any elegant solution.
  39. What happens if HLS is lost?[ Go to top ]

    It seems to me that Tapestry is heavily dependent on HLS as an individual. If HLS were to have a disabling accident tomorrow (or win a $500 million lottery and decide to stop coding), would Tapestry be able to keep up?

    I think JSF is much less dependant on a single person.

    This is probably another factor to consider.
  40. What happens if HLS is lost?[ Go to top ]

    Hmmm...
    In that case I do think Tapestry could keep up, or should I say stay ahead. I'm confident that the Tapestry as a community project would survive. (http://jakarta.apache.org/tapestry/dev.html)
  41. What happens if HLS is lost?[ Go to top ]

    It seems to me that Tapestry is heavily dependent on HLS as an individual. If HLS were to have a disabling accident tomorrow (or win a $500 million lottery and decide to stop coding), would Tapestry be able to keep up?I think JSF is much less dependant on a single person.This is probably another factor to consider.

    Winnin the lotter would not stop me from coding, it would just let me decide what to code even more so than now (but not much more so!).
  42. the links for downloading the example codes are broken.
    where can I get them?
  43. Where are the example applications?[ Go to top ]

    I've pointed this out but it doesn't seem to have been fixed yet. In the meantime, you can download them from a copy of the article here:

    http://www.realsolve.co.uk/site/tech/jsf-vs-tapestry.php