Posts tagged Web2.0
The Power of Facelets (Part 1 – Motivation)
Dec 15th
Ever since Java Server Faces (JSF) were released, we utilized them successfully for many web application projects. While being conceptually really nice and well thought through, one problem with JSF has always been the mismatch with JSP (Java Server Pages).
The issue is how to integrate JSP’s dynamic content into JSF’s component-based model. JSPs are singularly focused on generating dynamic output, whereas JSF requires JSP to coordinate building a component model. The disjunct occurs because that task is beyond the original intention of JSP.
Even though most JSF developers simply learn to navigate such problems, it made the usage of JSF in large projects a huge pain and always resulted in ugly code that was difficult to read and maintain. Far from what you want to achieve with a new technology.
The Problem with JSPs
…Well – maybe not JSP per se. JSPs are great for their intended use: Mixing both static and dynamic content made available by other parts of the application – servlets, plain java code, databases, etc.
But keep in mind that – historically – JSPs are nothing more than “fancy servlets” with some added semantic sugar. Their sole purpose of existence is to generate a response to a request; a JSP page is processed in one pass from top to bottom, with JSP action elements processed – here it comes – in the order in which they appear in the page.
JSF are component based and have a much more complex life cycle. They are created, asked to process their input (if any), and then asked to render themselves (I am simplifying here). For JSF to work well, these three things must happen separately in a well-defined order, but when JSF is used with JSP, they don’t. Instead, the component creation and rendering happens in parallel, causing all kinds of problems.
The fact that both JSP and JSF components add content to the response is another cause for a lot hard to track down issues. Unless you understand the difference between how these two technologies write to the response, you’re in for a lot of surprises – such as content appearing out of order or not at all.
There are severe limitations on how JSF and non-JSF tag libraries can be mixed in a JSP page. On top of that, developing a JSF application requires understanding the event-driven component model.
When learning JSF, a JSP developer now has to not only understand those (likely unfamiliar) concepts, but also learn the pitfalls of how to use the two technologies together and – more importantly – how not to. It’s a lot to learn and often unintuitive.
Lets have a look at a very simple example that illustrates the issue with parallel component creation and rendering. Say you want to create a label for a checkbox – bread and butter which we developers don’t even want to think about, right? Intuitively you would write something like this:
There is no intuitive reason this shouldn’t work, but if run this example, you’ll notice that no <label> element is rendered the first time you request the page, but if you request the page a second time, a <label> element is rendered.
This strange behavior has to do with the combination of JSF and JSP. When JSF receives the first request for the page, the component tree for the view represented by the page doesn’t yet exist. JSF creates a tree with just a UIViewRoot at the top and forwards the request to the JSP page to add the real components.
The JSP container now processes the page and invokes the JSF action tag handlers (here it comes again:) in the order they are encountered. A JSF tag handler looks for the JSF component it represents in the component tree. If it can’t find the component, it creates it and adds it to the component tree. It then asks the component to render itself. This means that on the first request, the components are created and rendered in parallel. On subsequent requests, the component tree exists, so no new components are created; the tag handlers just ask the existing components to render themselves.
On the first request, the >h:outputLabel< action creates its component and asks it to render itself. To do so, it needs to find the component identified by the for attribute, but this component doesn’t exist because the action element that creates it appears after the <h:outputLabel> element and hasn’t been invoked yet. Hence, the component created by <h:outputLabel> action can’t render its <label> element. On the second request, all components exist, so the component represented by the <h:outputLabel> finds the component the label belongs to and happily renders the label element.
Of course in this case there are easy workarounds, but hey: Why should I “work around’ something as simple as adding a label to a checkbox? Furthermore – as you start going beyond “Hello World” pages, you encounter more and more examples like the one above, and many of them aren’t as easy to understand. Matters get worse once you start using AJAX, A4JSF and similar technologies.
In a recent project, the code for the view pages were – out of necessity – plastered with <f:verbatim>pages – creating pages with unbalanced tags (hey – we had no choice) and making it almost impossible to work with.
The solution was – of course – to dump JSP altogether and move to Facelets – more about this in the next article.