Where JSF and Portlets went wrong.

JSF and Portlets promised to integrate the web, but in reality they just brought more confusion and lock-in. One of the main goals is to provide a lightweight alternative for web integration.

JSF promise was to be able to reuse web components among different frameworks that correspond to one standard. However the standard, as always, have left more things open than specified, and in reality we didn't even come near to actually reusing components between frameworks (try using ICEFaces components with ADFFaces). What's worse, JSF have imposed on us a highly complex and clumsy API, that one needs to follow to achieve even a little reusability and broke the familiar way of capturing logic in custom JSP tags.

While third-party options (like Facelets) do make programming with JSF easier, one still has to jump through hoops just to get simple reusable components. And since the components are not really Java objects, there is almost no good way to enforce a normal contract for their communication.

The trouble is that we already have a great tool for building and integrating disparate components—it is called the Java programming language. Object-oriented design have been proven to be a viable solution for already two decades, and it is just sad to see that the designers of JSF have ignored it to pursue type unsafe and hard to debug design that looks more than a bit like Struts, revisited.

Which brings us to our second offender—Portlets. Although Portlets were the first to achieve actual remote integration among different web applications, they also did that with a model that is limiting in every way possible. There is almost no communication between portlets, there is no way to embed portlets in other portlets, and some of the worst aspects of servlets (like static configuration and global contexts) have been carbon copied to the portlet spec. However instead we get modes, window states, persistent store and user profiles, which don't have much to do with the integration itself and should really have been provided on top of that and not all in one spec.

In my mind these specifications share the same trouble as the infamous EJBs:

  • They are designed by a committee
  • They are not standardizing something existing, but creating a new solution on paper
  • They are designed largely by and for tool makers, instead of developers

Now, selling tools is a great goal for those of us who make them. But tool-oriented specifications have insofar turned out to be less than successful. The EJB world is rapidly moving towards lightweight solutions like Spring and Hibernate, which instead of providing shiny tool support have a simple and clean design and just do their job well. The developers became so bitter from the tools, mappings and bytecode postprocessing, that Plain Old Java Objects became a buzzword that sells considerably better than MDA.

Now the situation is rapidly improving in the application server ecosystem, and with EJB 3.0 being a mix of Spring and Hibernate with a healthy dose of annotations, we are definitely looking to a brighter future (though the point of the rubber stamping perfectly good open source frameworks as a standard is still unclear to me).

However the situation in the web framework ecosystem is yet to achieve the same level of enlightenment. Currently we are looking at a large number of incompatible web frameworks that kill any hope of integration and reuse even before it appears. Many of these frameworks are really innovative (Wicket, Tapestry, RIFE come to mind and Seaside deserves an honorable mention), but there is no way to use their strength without also accepting their weaknesses.

It is our belief that different approaches are needed for different types of web applications. For example blog engines do well with a REST semantics, while complex enterprize applications do better with a component semantics and in some other cases one needs differently proportioned mix of the two or something altogether different. Aranea goal is to capture different types of these semantics in a simple and clean component model:

  • Services capture REST semantics
  • Widgets capture stateful component semantics

However to become actually useful you also need to connect the two, so we have Components that are a supertype of both and capture component lifecycle, communication and hierarchy. As a result we get a lightweight implementation of the Hierarchical Model-View-Controller pattern that allows to actually use both approaches at the same time.

What's more, since service and widgets capture the essence of their semantics they should allow to host similar constructions from different web frameworks providing an interoperability layer with a simple and clean API (widget interface has 4 meaningful methods not counting the 4 more lifecycle ones and does not need any configuration). It is indeed our intention that the minimalistic Aranea core would be usable to integrate together different web frameworks, allowing to seamlessly use them together in one application combining (to some extent) different approaches when needed.

Next to that goal it becomes relatively simple to just reuse components between applications a la JSF or combine several subapplications into one a la Portlets. Remote integration is trickier, but it shouldn't be too hard to host portlets or provide a WSRP adaptor.

Although we still have to talk in future tense about integrating the open source web frameworks (and possibly JSF), we have already achieved a lot of reusability and integration in terms inside and between applications, as well as with an internal legacy web framework. We hope that it will go just as smoothly with the other frameworks and we will be able to deliver on the JSF and Portlet promise.

0 comments: