Seam usage in production

There ‘s an interesting thread on the Seam forum about Seam in “profesional use”. Performance and steep learning curve are often mentioned as drawbacks.

Seam heavily relies on proxy based components created by javassist. And javassist is known to be unperformant compared to cglib. This library might have been chosen due to politic reason at JBoss. Seam Managed Persistence Context (SMPC) is also seen as a culprit but i guess that like many other frameworks you have to understand what’s underneath the carpet, lazy loading in some use cases can really hit performance.

Scalability is not mentioned but i guess that since Seam is stateful it also can be an issue for large websites.

For the learning curve, it might be true if you don’t come from the JavaEE world or have never developed JSF applications. Seam still requires good knowledge of JSF 1.X and how it corrects it in many ways. The request lifecycle is also complex albeit powerful.Also other “lightweight” JSF based frameworks are quoted like makefaces.

Seam for me is both a IOC container specialized for web development and a web integration framework of Java EE (Ejb,Web beans), JBoss stack (jBPM, Drools, Richfaces, JSFUnit) and commonly used libraries (quartz,jfreechart, itext, javamail,etc.) It also addresses many commonly asked features (conversations, mail sending, page caching,etc.) I am not sure for the future of Seam. Seam 3 might be a complete rewrite due to support of JSF 2 and JSR-299 aka Java Contexts and Dependency Injection, but it is a comprehensive and efficient web framework with a decent IDE (JBoss tools).

Some common JSF pitfalls

Well at least here’ s a non exhaustive list of common jsf pitfalls, i felt into (some are variants of others) :

  • Using a converter in a SelectOneMenu or SelectManyList components, be careful of type being applied. See Using an array instead of typed collection for the component input values ( still not sure why, have investigated too much on it, so i won’t extend on it)!
  • Declare a resource bundle in the page ( most of the time bundles are declared in a template page) with the loadbundle element instead of declaring it the faces-config.xml file . If done so, requiredMessage or converterMessage attibutes that can be applied to many UIInput components won’t work (i.e the message won’t be found).
  • With a commandLink inside dataTables with a bean of request scope actions are not executed. At least it happened to me with JSF RI 1.2_07 and is due to the fact that the id of the dataTable component is changed between the component tree creation (restore view phase) and the render response phase ( Update 09/21/2008 : See more explanations on this in the comment section by Dan Allen himself, author of “Seam in Action” ). When submitted on a post back request, the actions event are not queues (passed as hidden fields). It’s well detailled here As a workaround, i used the tomahawk savestate component for the elements of the datatable. This component stores the state of objects passed as value expression in the component tree (having a scope that spans between the inital request restore view and post back render response phase) . Seam has a page scope for that.
  • Validation errors when using a converter in selectOne* components and not overriding the equals() method for the type of object in the list. More explanation here :
  • Saving state on client side with hidden fields and having conversion or validation issues with a backing bean of request scope: state is lost. For instance, you have an inputHidden component in your form and for a reason or another a form’s field has conversion or validation issues. The backing bean of request scope is not updated for the postback request. The bean used to display the response is new and the inputHidden‘s field value is reset. Once again this shows a lack of page context for state that needs to be kept between the initial request and the postback request.
  • Programmatic submission of a web form in javascript through form’s submit method won’t work because the actionlistener is registred on a commandButton and when the form is submitted, the submit button parameter is not passed in the request. The button’s action event is not put in the event queue. A workaround is to programmatically click on the form’s command button.