Saturday, April 22, 2006

JavaServer Faces - JSF - Powerful and Underestimated.

Project History and Experience.

Starting one year ago, I began researching UI frameworks for developing web appliations in Java. Keep in mind, I'm a Senior Software Engineer with 7+ years of experience, so I do bring some perspective to this research. My goal was to support a fairly complex user interface comprised of thousands of fields. These fields would include most of the standard user interface components such as text, select boxes, check boxes, buttons, tabs, various panels, and rich graphical mapping components. Each user will see distinct subsets of the full system, making the choice of UI framework particularly important.

In early 2005 there were at least a dozen Java web app frameworks, but I quickly narrowed the selection down to a few. There were highly praised but "non-standard" frameworks such as Tapestry, Spring and the now aging Struts. While each of these addressed page flow and validation, each seemed to focus on a JSP or HTML page as the core of the UI layer. If I recall correctly, Tapestry focused on plain HTML as the view layer with special tags embedded. Struts had the largest user base but, speaking from personal experience, can quickly become a cumbersome liability in a large project. Spring promised simplicity and elegance, with a focus on integration with hibernate.

None of these projects addressed the UI View layer in the classic Model View Controller (MVC) Architectural Style. Except JSF. JSF's core focus was a Component based View layer. If I were building a small application with, say 50-100 fields, standard JSP would do just fine with almost any framework or none at all. For a complex application with 1000s of fields, with rule driven inter-dependencies, the full MVC style was needed. JSF components could fire events. They could also be programatically composed, manipulated, and decorated.

I briefly entertained the idea of simply creating my own HTML RenderKit rather than take the potentially steep learning curve of JSF. I'm incredibly glad I stuck thru the JSF initial hurdles. While most of the JSF tutorials out there are for standard JSPs, what I wanted was JSF without the JSP. As the learning continued I thought JSF with JSP was fine, but thought I would need custom components. After months of effort, I have yet to find a need for a component that does not exist in either the core JSF API (per the Sun 1.1 Spec) or the Tomohawk MyFaces Implementation.

After 4 months into implementing this major project, I am ready to fully endorse JSF for anyone who will listen. The concept and style of JSF is incredibly powerful, providing a very rich present or future path for those who are willing to try it. My coworkers are openly impressed with the project and many did not think a web application was capable of this type of interaction. Just a few weeks away from production deployment, I've confidently load tested the application and it should far outperform our current legacy app.

Please forgive the intentionally vague lack of mention of my company or the project specifics. Let's just say that it's a pretty cool project, for a Fortune 100 company, and will be used by quite a few people.


Technical Details. Why you should think about JSF.

1. Composite Components.
Just like Swing, .NET Windows Forms, or most other client side UI Frameworks, JSF components are true components. Due to their object hierarchy, any JSF UIComponent can contain other UIComponents as children. This grants incredible flexibility. It means that you can generate and render from an arbitrarily complex domain Model to an Object Graph of the UI View.

2. Decorators.
Due again to the elegant component hierarchy of JSF, all components can easily be decorated. In this case, I built my own small hierarchy of Decorators that could decorate any UIComponent. There are several domain-specific Decorators I can't mention, but an obvious one that I can is for debugging. Simply pass the Decorator list to the root Model -> Object Graph, and each major section of functionality will be wrapped with a debugging panel showing important state information for the developer.

3. Component Attributes.
Gone are the days of coming up with a naming convention for HTML form parameters and parsing in those same parameters. With JSF Components, you can simply add as many Java Objects as you wish to named keys in the JSF Component. This is similar to "Object Tags" in some thick-client UI frameworks. In this way, when an event is fired for a Component, the Event handler can simply lookup the Object you attached directly to the Component earlier on. This also removes the potential (definite for my application) burden of using HTML form parameters to subsequently look-up objects from another data-store or Model.

4. Event Listeners.
If you use Eclipse, you know about it's code completion and automatic import suggestion. The first few times I implemented JSF Event Listeners, I almost selected the Java Swing ActionEvent import (suggestion) rather than the JSF ActionEvent import. I haven't bothered to compare the API specs of each class, but I can tell you that there is nothing lacking JSF ActionEvent API. You can completely free yourself from the HTTP cycle and simply concentrate on event sources and handlers.

For static applications without a dynamically generated component hierarchy, such as most of the JSF-with-JSP tutorials show, Event Listeners can be bound directly to the UIComponent itself. For my application, which currently has ~ 30 different Listeners/Commands, I realized it was not worth looking up the proper Listener for each control, when on average only less than 1 in 10 would be clicked on per render. Thus, all Command components are bound to a single Command Listener. This Listener, upon receiving an event, looks up the appropriate listener and invokes it with the event.

5. Extensibility
It's pretty easy to develop custom components for JSF. Due to the specific nature of the JSF specification, the MyFaces components can even be used with the Sun Reference Implementation (RI). For those obviously needed components missing from the RI, MyFaces easily separated their core RI components from their extended JSF components (Tomahawk). Other groups both commercial and non-profit/open source are regularly releasing sets of JSF components. As JSF adoption increases, there will be a stream of more and better components.


Conclusion.
Of the frameworks mentioned in the first section, only JSF has two completely separate implementations. Only JSF has the full endorsement of the Java Community Process (JCP). We can be quite sure that JSF will be around for a long time. After such a positive experience with JSF I am confident that others are too. I'm sure that in the near term, more blog entries like this one will show up and build the momentum, respect, and ultimately adoption of JSF. With the excellent extensibility in terms of 3rd party Components, JSF will be ever improving even without a specification update.

I'm not saying everyone should jump to JSF now, but if you are building a complex application in Java for the web, it's worth serious consideration.