Skip to main content

Baby Steps with JSF 2

Posted by cayhorstmann on December 18, 2008 at 10:08 PM PST

There are
several blogs that tell you how to do fancy things with the upcoming JSF 2
(such as these by Ryan Lubke and href="http://weblogs.java.net/blog/driscoll/">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 href="http://weblogs.java.net/blog/cayhorstmann/archive/2006/09/the_power_and_p.html">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 href="http://c2.com/xp/YouArentGonnaNeedIt.html">YAGNI. Many people (such
as href="http://cagataycivici.wordpress.com/2008/11/13/xml-less-jsf-navigations/">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?

  • The IDEs don't yet know how to do completion of tags or EL elements in
    your .xhtml files
  • The IDEs don't yet know how to parse those facelet error messages and
    trace them back to your .xhtml files
Related Topics >>

Comments

By the way Cay, When the leaves finally JSF 2.0?

Ryan, I think with the f:event support we have spec'd and implemented (just waiting on a review before I commit it), we should be able to do page actions. Here's the issue covering the proposed change: https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=514 Does that look like it will do what you want to do? WRT URL rewriting, this is the first I've heard of that feature, so, while I may have missed something, I don't think that one is even on the table for a 2.0 release. If it's really important to you, please file an ehancement request on the public tracker. It won't make 2.0 (we're feature frozen), we can certainly look at it for a future rev of the spec.

Cay, yes. That's the remark to which I was referring. We have at least two impls ready to use (I helped with one), but I haven't heard yet what the status is on that change. Still digging.

Hi Cay, Very good the post, and it is interesting, and over time I'm sure that the JSF 2.0 will bring further benefits to Java programmers, and congratulations for his many books are good. I thought it was very smooth this change of faces-config for Annotations.

Regarding navigation, I really hope JSF 2.0 expert group hasn't dropped Page Actions: http://docs.jboss.com/seam/2.0.3.CR1/reference/en-US/html/events.html#d0... I also hope they haven't dropped URL rewriting: http://docs.jboss.com/seam/2.1.1.CR2/reference/en-US/html/events.html#d0... These are so important.

jdlee: You mean this remark, right? "Naturally, I think if we do this we can dispense with the navigation-rules alltogether and say that if there is no navigation-rule for the page you're on, then just infer the to-view-id by taking the outcome, tacking .xhtml onto it, and going there." I have no opinion on all the other stuff in this ticket, but having the option of no navigation rules is a HUGE advantage for beginners. I strongly encourage you to add that to the spec.

Hi Cay, There are a bunch of components in wicket-stuff, including wrappers for various javascript libraries like yui, dojo, jquery, etc. It's not unexpected that there would be more third-party involvement in JSF components though. First of all it's a JCP standard, but it's also because of the difficulty in writing your own, so people look for ready-made solutions. In Wicket it's so easy to do them that one looks to customize first instead of looking for yet another dependency with its own peculiarities (unless it's a complex component, then it might pay to look for a ready-made and debugged version). Ismael

Cay, is this what you had in mind (look at Ed's comment from 10/18): https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=419

These all sound like exciting developments. Hopefully writing custom components for facelets is easier than doing them for jsp. I totally agree with you about the navigation rules. They resulted in files that were really terrible to maintain. Also, I hope facelets has support for decent server-side include functionality. Unfortunately, all my JSF development occurred in 2004 and 2005, which mostly predated facelets. We had to cobble together a bunch of JSF templates with struts-tiles. It wasn't much fun.

Unless it's fallen off the table and I've missed it, simplified navigation config is to be added to the spec. IIRC, what we've discussed is action string = view id, so return "foo" sends the user to foo.xhtml. If that's not found, JSF looks up the nav rule from faces-config.xml. That topic hasn't come up recently (we've been hammering at Ajax, state saving, etc) of late, so I'm not sure where it stands. I'll check, though.

JSF 2.0 makes it simpler to write composite components: http://weblogs.java.net/blog/driscoll/archive/2008/11/writing_a_simpl.html. (For perspective, check out this response from the Tapestry creator: http://java.dzone.com/articles/simple-jsf-20-component-vs-tap). But I have no desire to write custom components. I leave that to others who can figure out the AJAX magic that is expected these days, such as my fearless co-author David Geary. There are lots of people who do write custom components, even though it is impossibly hard. In contrast, Wicket has a rather short list of components ((http://wicketstuff.org/wicket13/compref/). Is there a third-party market?

My first encounter with JSF was in a project where I was to write a component. Hell is better than writing a custom component in JSF. I hate JSF and continue to do so unless they make writing a custom component an easy task. Till then... Wicket to the rescue.

Ryan, page actions have made it in the form of: What we are still trying to work out is whether navigation rules can be fired after execution, as they are in Seam. Likely it will happen programmatically in some way, either via a hint or explicitly by the developer.

Implicit navigation is implemented in JSF 2.0. That basically means that if no navigation case matches, the outcome is treated as the to-view-id. Seam implements this logic as well. However, in Seam this always results in a redirect, whereas in JSF 2.0 you have to put a redirect hint in the form of a fake URL parameter on the outcome as follows: /confirmation.xhtml?redirect=true JSF 2.0 is really shaping up to address the major concerns people had about JSF 1.2!