Comparing Web Frameworks Presentation
Since Kris let the cat out of the bag, I might as well give you the link to my comparing web frameworks presentation (PDF, 280KB). I also created a page on the Equinox site for this presentation and related materials. In addition to the presentation, this page also has links to the various framework implementation demos. Here they are for your convenience:
Kris notes that I would still choose Struts. I think it should be noted that I would only choose it in combination with AppFuse (which generates ActionForms). Same goes for Spring and WebWork. I've added interceptors and convenience methods that simply make developing with these frameworks faster and easier. I would've chosen WebWork for my current project, but I'd like to see better client-side validation. Spring needs better tag libraries.
I think the choice of what framework to use is a very personal thing. I think the "best" framework for one person might be very different for someone else. For me, I typically do short-term projects with clients - get them up and running with an application, and then head off to the next project. It makes sense for me to create applications that use a popular framework like Struts that they can easily find developers to maintain it. However, the one thing I'm starting to find is that as long as I use AppFuse - there's good documentation on how to do things. So I've already written the "how to develop and extend this app" for future developers of a client's application. This will (hopefully) open the door for me to use any web framework that AppFuse supports.
I think WebWork rocks, but it's similar to JSF in that it doesn't come with everything your need. The good news is it's easy to write interceptors, but IMO there's a few that should be part of the framework. After working with Tapestry and JSF, I can see how component-based frameworks will be the wave of the future. I think as you develop more and more components, the code you write becomes less and less. It's funny that this is one of the goals of AppFuse - incorporate a bunch of tips and tricks for various frameworks to make development easier. By adding support for Tapestry and JSF, hopefully AppFuse will someday become a repository of useful components. Documentation is good - code is better.
I'd probably be more enthusiastic about Tapestry and JSF if I knew more about them. I still have a lot to learn. I've bought the books (Tapestry in Action and Core JSF), I just haven't had time to read them. I think after incorporating these frameworks in AppFuse (hopefully this year), I'll get a better feel for them and how they make development faster and more efficient. My major problem with JSF is that it's being written for the tools vendors and not for the developers. Make it easy for everyone, not just folks that want to use their hammer-like IDE to develop webapps. The major problem I have with the JSF Tools is 1) none of them are free and 2) most of them are tied to a proprietary app server.
Posted by Kris Thompson on November 04, 2004 at 06:18 PM MST #
Rafe (rc3.org) really likes Spring, for the fact "I found some instructions online and gave it a shot, and lo and behold, everything just worked. The first time."
Personally, I haven't had a chance to start using it; maybe on the next gig.
Cheers,
Bryan
Posted by Bryan on November 04, 2004 at 06:32 PM MST #
Posted by Ted on November 04, 2004 at 11:18 PM MST #
Posted by Eric Hauser on November 05, 2004 at 02:20 PM MST #
Posted by Keith on November 05, 2004 at 02:37 PM MST #
Posted by Jeff Carlson on November 05, 2004 at 06:01 PM MST #
Posted by 64.28.86.59 on November 05, 2004 at 09:48 PM MST #
Eric - WebWork needs some more work on its client-side validation. More most, this is a non-issue, but I've worked with some usability experts that believe it is important. If you do choose to use WW's client-side validation, you can't cancel it (w/o using location.href on a button) and it shows each validation error individually rather than collected in one alert box. I know it's minor - but I had to crack on it <em>someway</em> since I've been bashed by WW guys for being a Struts developer for so many years. ;-)
Keith - good point. I think if Spring MVC was released when Rod first invented it (before Struts I believe), it would be widely used today. Most of the frameworks, except for Spring and JSF, have enjoyed quite a bit of user feedback over the years. I'm actually starting a couple small projects next week - one using WebWork and one using Spring MVC.
Jeff - thanks - I've entered it as a bug.
Anonymous - yeah, I have a problem with that. The copy editor for Spring Live is always changing my i.e.'s to "for example" and "that is" - maybe I should get her to edit this presentation...
Posted by Matt Raible on November 05, 2004 at 10:01 PM MST #
Posted by Muhammad Mansoor on November 06, 2004 at 05:11 AM MST #
Posted by jsf on November 07, 2004 at 02:19 AM MST #
Posted by David Whitehurst on November 15, 2004 at 01:15 AM MST #
Posted by David Whitehurst on November 15, 2004 at 01:17 AM MST #
Now, select one of the Johns, my has ID==36. Delete him. Go back, try delete him once more: "Data Access Failure, Object of class [org.appfuse.model.User] with identifier [36]: not found". Go back using browser Back button, click either Save, Delete or Cancel. You will get the same error. Now go back using "<<Back" link provided on error page, and click any button again: the same error. You are stuck. Just for kicks, reload error page. You will see nasty "Do you want to resend POSTDATA?" window. Click OK and you will get the same error.
Do you want to check out another version of Struts CRUD application? See my Redirect-after-Post sample. Feel free to reload any page, go back or forward (if you use Firefox, do not use prerelease versions, they do not honor "no-store" response header). You can even open the same item in two windows, one for viewing, another for editing, and see how the viewed version is updated when you save edited version.
And by the way, the phrase "JSF does POST for everything" from your comparison is not truthful, I thought the same and I was wrong. I tried redirect directive in the navigation rule, works great, loads success page using GET.
Posted by Michael Jouravlev on January 20, 2005 at 10:55 PM MST #
Select user by ID, delete him, get user list, refresh the list, get "Do you want to resend POSTDATA?", click "yes", and get... an empty new user form! Reload user form, get the user data in the fields. WTF? Or, select user by ID, delete him, get user list, go back, delete the user again and get an empty new user form. Reload user form, get the user data in the fields. Yuck.
Tapestry version blows up on "delete/get list/go back and delete again" with "An exception has occurred. You may continue by restarting the session. org.apache.tapestry.ApplicationRuntimeException Unable to invoke method delete on org.appfuse.web.UserForm$Enhance_18@4764a1[userForm]: Object of class [org.appfuse.model.User] with identifier [41]: not found org.springframework.orm.ObjectRetrievalFailureException Object of class [org.appfuse.model.User] with identifier [41]: not found" and a stacktrace.
Go back from the error and save the user. Now you get a different error: "An exception has occurred. You may continue by restarting the session. org.apache.tapestry.ApplicationRuntimeException Unable to invoke method save on org.appfuse.web.UserForm$Enhance_18@4764a1[userForm]: SQL insert, update or delete failed (row not found); nested exception is net.sf.hibernate.HibernateException: SQL insert, update or delete failed (row not found) org.springframework.orm.hibernate.HibernateSystemException SQL insert, update or delete failed (row not found); nested exception is net.sf.hibernate.HibernateException: SQL insert, update or delete failed (row not found) net.sf.hibernate.HibernateException SQL insert, update or delete failed (row not found)" But Cancel works, what a relief.
Webwork version allowed me to add from the same form again and again, where is this POST interceptor which Jason was talking about? After I performed my "delete/get list/go back and delete again" move, Webwork just hung up on me, or so it seemed. After about a minute Firefox shown me a completely empty screen. When I tried one more time, Tomcat returned with exception: "type Exception report message description The server encountered an internal error () that prevented it from fulfilling this request. exception javax.servlet.ServletException: Servlet execution threw an exception org.displaytag.filter.ResponseOverrideFilter.doFilter(ResponseOverrideFilter.java:93) com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(PageFilter.java:118) com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:52) org.appfuse.web.MessageFilter.doFilter(MessageFilter.java:36) root cause java.lang.OutOfMemoryError note The full stack trace of the root cause is available in the Apache Tomcat/5.0.28 logs." But Cancel worked, whoa.
Posted by Michael Jouravlev on January 20, 2005 at 11:29 PM MST #
For the JSF version, I've added a <redirect/> as suggested and it works quite well - thanks! I agree that it's strange that subsequent POSTs cause different behavior.
The OOM issue happens periodically on this server because I'm running so many demos and the box seems to be *very* slow. I'm considering moving it back to my local server as I hardly had any issues when it was hosted here.
Posted by Matt Raible on January 23, 2005 at 05:40 PM MST #
Posted by Michael Jouravlev on February 17, 2005 at 02:44 AM MST #
If Equinox is not robust enough for you (because of your stated bugs) - it's an open source project, so patches are always welcome. ;-)
Posted by Matt Raible on February 22, 2005 at 08:44 PM MST #
As I add a new User exception below is being thrown.
javax.servlet.ServletException: SQL insert, update or delete failed (row not found); nested exception is net.sf.hibernate.HibernateException: SQL insert, update or delete failed (row not found)
Can you figure where did I go wrong?
Thanks,
Edison
Posted by Edison Ormichigos on March 22, 2005 at 07:29 AM MST #
Posted by Matt Raible on March 23, 2005 at 06:21 PM MST #
Im using the Spring version not the JSF. The only difference is that I use MSSQL 2000 instead of HSQLDB. As I run UserDAOTest testcase I got this following error.
Also, please edit my last post. Remove the username and password please. :)
Posted by Edison Ormichigos on March 28, 2005 at 09:55 AM MST #
Posted by Matt Raible on March 28, 2005 at 09:43 PM MST #
Posted by Nigel DeFreitas on April 23, 2005 at 05:07 AM MDT #