Skip navigation
ANNOUNCEMENT: is currently Read only due to planned upgrade until 29-Sep-2020 9:30 AM Pacific Time. Any changes made during Read only mode will be lost and will need to be re-entered when the application is back read/write. 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 theresources directory. Oops,h:commandButton hasn't been fixed to havelibrary and name attributes. No problem:

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

Of course, it doesn't work. The value ofresource['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:commandButtondidn'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.

  • A JSR is formed
  • The expert group goes to work
  • An early draft and a reference implementation are posted to the public
  • The spec is incomprehensible to those who haven't participated in the discussions
  • With much effort, the early reference implementation can be coaxed into running some nifty examples
  • A few blogs appear
  • It becomes apparent that large parts of the promised deliverables are not yet specced or implemented
  • In a few short months, a very large amount of new technology is added to the public review draft
  • The spec is still largely incomprehensible
  • The reference implementation is getting almost usable
  • There are still important pieces missing that look pretty dicey to spec and implement
  • The expert group, in a burst of heroic action, provides most of the missing pieces and issues a proposed final draft.
  • The spec is still filled with gobbledygook, but it has become familiar gobbledygook
  • The reference implementation has become pretty stable
  • Bloggers, authors, tire kickers, and early adopters can finally make sense of the thing
  • The final draft is rubber-stamped
  • Lots of little “fit and finish” issues become apparent
  • None of them can get addressed because the spec is final
  • All behavior must now be preserved in the interest of backwards compatibility

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

  • “Public review” should not be mere lip service. Give at least 6 months between issuing the proposed final draft and approval. Have a formal process for collecting input and responding to it.
  • There should be a process for cruft detection and removal in every update. Deprecate in version x + 1, remove in version x + 2.

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.