Baby Steps with JSF2

There are several blogs that tell you how to do fancy things with the upcoming JSF 2 (such as these by Ryan Lubke and Jim Driscoll). In this blog, I look at the other side of the coin—how the simplest things are working out. After all, if Ruby on Rails has taught us anything, it is that a technology that makes the simple things simple has a great shot at getting developer mindshare.

In Ruby on Rails, it is trivial to make a canned CRUD application, but I don't care about that. The kind of applications that I am interested in don't naturally evolve from a bunch of CRUD screens. Instead, I looked at the shopworn login example from Chapter 1 of Core JavaServer Faces. That example has a couple of screens, a managed bean, and a navigation case.

Good News #1. No more <managed-bean> in faces-config.xml

Nobody likes the busywork of maintaining an XML file in addition to the Java code. Just as you can use annotations in JPA to avoid XML drudgery, JSF 2 lets you annotate your managed beans, like this:

@ManagedBean(name = "user")
@SessionScoped
public class UserBean {
   ...
}

Good News #2. Facelets is a standard page description language

I never liked JSP, and I didn't like that JSF was built on top of it. JSP gives you the stack trace from hell. Now, you can author your pages in XHTML goodness, like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html">
  <h:head>
    <title>Welcome</title>
  </h:head>
  <h:body>
    <h:form>
      <h1>Please enter your name and password.</h1>
      ...
      <p>
        <h:commandButton value="Login" action="login"/>
      </p>
    </h:form>
  </h:body>
</html>

A validating XML editor will flag silly typos, and more importantly, when something goes wrong at runtime, you get a comprehensible error message with a file name and line number:

As an aside, some people like facelets because presumably it gives you a way of sharing your JSF files with a visual designer. You could write that button as

<input type="submit" jsfc="h:commandButton" .../>

and the document would look ok in a web page or a visual designer. But that doesn't scale to higher level components such as a h:dataTable. Those components are the raison d'ĂȘtre for JSF. As much as I like the easy stuff to be easy, I just don't have any JSF apps that are made up solely of buttons and input fields. The reason you want facelets is that it can give you decent error reporting, and it doesn't carry the JSP baggage.

While I am ranting...ever so often, someone tells me that it is a flaw in our JSF book that it doesn't relive the history from servlets and JSP to JSF (not to mention the Cambrian explosion). I never understood that. That's like saying: “To really understand Java, you first must master C++”. End of rant...

Not-so-good News #3. <navigation-rule> is still among the undead

If you have a simple app that consists of no more than 99 pages, you know where your actions need to go, and the <navigation-rule> element in faces-config.xml is just a big pile of YAGNI. Many people (such as Cagatay Civici and my grad student Tom Austin) figured out how to implement a navigation handler that just navigates to the !@#$ page that you knew all along was required.

I really hope that the expert group sees the light and adds this to JSF 2.0. All I am asking for is a simple switch in web.xml or an annotation. Can you dream? No more faces-config hassle for simple apps!

Good News #4. Hot deployment just works

I tried this in Netbeans and Eclipse, with Glassfish v3 andTomcat. It all worked great. Make a change in a .xhtml or .java file, save it, and refresh your browser. The change is right there. It's amazing. Well, it's just like it should have been all along. Not having to restart the app server all the time is huge. (Truth be told...I am not sure it always works flawlessly. There were times where I felt I had to restart the server. Glassfish v3 restarted awfully fast, and I preferred it over Tomcat.)

What doesn't yet work?