The Fit and Finish of JSF

When I come across an article such as this one, I am overcome with melancholy. I really want to love JSF. Its heart is in the right place. It wants to let me drag and drop components onto a form, wire them up with JavaBeans, and give me AJAX with essentially no work on my part. And it comes so close.

Now, admittedly, I am biased. I am a co-author of the best-selling JSF book, with David Geary, published by Sun Press. I am making lots of pennies on the Safari page views and a few dollars from the hardy souls who, bless their hearts, still buy the paper version. But frankly, there are easier ways of making a buck than writing a JSF book. I wouldn't do it if I didn't think JSF was (or, at least could be) the cat's pajamas.

We all know that JSF is far from perfect. Too much stuff in the HTTP session. Component authoring is way too hard. A leaky abstraction. The stack trace from hell.

But what really bugs me is the overall lack of “fit and finish.” Sometimes, JSF feels like one of those lower end American cars that make up much of the rental car fleet. Cheap, mismatched buttons. Gaudy metallic plastic that comes off when you stare at it too hard.

Here is a random example, one of many:

JSF 2.0 has a new feature for locating resources. It's pretty nice. You dump images, CSS files, scripts, and so on, into subdirectories of a resources directory. Then you can write

<h:graphicImage library="images" name="myimage.png"/>

Or, as my coauthor inexplicably prefers,

<h:graphicImage value="#{resource['images:myimage.png']}"/>

As it happens, I have a command button with an image. Wanting to be thoroughly modern, I move the image to the resources directory. Oops, h:commandButton hasn't been fixed to have library and name attributes. No problem:

<h:commandButton image="#{resource['images:myimage.png']}" .../>

Of course, it doesn't work. The value of resource['images:myimage.png'] is /context-root/faces/javax.faces.resource/myimage.png?ln=images, which starts with a slash! (Can you hear the evil laughter in the background?)

The JSF 1.0 expert group had to worry about big and important things such as the pluggability of the state manager, and nobody paid much attention when h:graphicImage added the context root to an image URI and h:commandButton didn't. The 1.2 expert group, focusing on lofty issues such as the ability to have multiple render kits in a single application, apparently had a few minutes to spare on a “solution”. Now h:commandButton prepends the context root if the image URI starts with a slash. So, I get /context-root/context-root/faces/javax.faces.resource/myimage.png?ln=images.

I know, it's no big thing, and I can work around it. It's just like that rattling piece of plastic in the rental car.

And I don't want to make fun of the JSF expert groups. They are very knowledgeable and have solved hard problems in constrained time frames.

My beef is with the process.

With this process, cruft is bound to accumulate. JSF is not the only culprit. Apparently, all is not well in the land of servlets. And that's a much simpler spec.

I think the process needs a couple of tweaks

Again, I don't want to bash JSF. There are lots of nifty things in JSF 2.0, and I see no really compelling alternative to it. (If there was, everyone would just flock to it instead of kvetching about JSF.) I just want more fit and finish in JSF 2.1 and 3.0.