Skip navigation
ANNOUNCEMENT: community.oracle.com 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.

As a book author and glutton for punishment, I am often interested in bleeding-edge Java technologies, as they are cooked up through the Java community process. For example, when David Geary and myself wrote the first edition of our Core JavaServer Faces book, we needed to work with the early access versions of the spec and reference implementation (RI). At the time, source for the RI was only available to members of the expert group, and I had to use a decompiler to get an approximation of the source from the binary files. It was surprisingly effective, but not something that I care to repeat.

Fortunately, now the RI is developed with a public version control system on java.net, so that problem has gone away. But the spec is still very hard to read, and it would often help to have some background information on the thinking behind it. Unlike a true open source project, the expert group discussions are not public. The spec is only publicly updated at infrequent intervals and is often at variance with the RI.

http://weblogs.java.net/blog/cayhorstmann/archive/observer.jpg

When I complained bitterly to my fellow Java champions, someone suggested that I join any JSRs in which I am interested as anobserver. This andthisand this article tout the benefits of the observer status.

It turns out that, in order to be an observer, you first have to become a JCP member. That requires that your employer signs off on some pretty heavy legal paperwork. The JCP is naturally concerned that an employer doesn't later claim that some idea that made it into some JSR work product is their property. I didn't think there was any hope that anyone at my employer (San Jose State University) would understand the paperwork, or have the courage to sign it. But fortunately, I don't work for them during for the entire year, so I just signed it as a self-employed person while I was on break.

I then dutifully followed the process to sign on as an observer to a couple of JSRs (including JSR 314 for JSF 2.0), and the result was . . . nothing.

I emailed Ed Burns, the spec lead, and he responded:

CH> Hi Ed,
CH> I am an observer for JSR 314, but I am confused as to how I can observe.
CH> I naively assumed I would get some way of monitoring how the spec
CH> evolves, perhaps through read-only access of a mailing lists forum, and
CH> by being able to see proposal drafts. I logged onto the JCP page, and it
CH> has no contents. I was added to the observer alias, but have not
CH> received any email. Do I need to activate this in some way?

The observer list is very low traffic.  We use it for announcements on
the availability of new drafts.

We don't have a publically observable list for JSF 2.0.  We charged Kito
with maintaining a public JSF 2.0 group blog, but he hasn't updated it.
It's at <http://blogs.jsfcentral.com/jsf2group/>.  Please prod him to
update it.

http://weblogs.java.net/blog/cayhorstmann/archive/glasnost.jpg

Well, I am sorry, but that stinks. That's not openness. I think the JCP needs to move up to the next level of glasnost. I have sympathy for the poor spec leads who aren't given a lot of guidance. So the JCP should provide some guidance, such as:

  • Email and forum discussions are to be archived (unless there is some specific reason for confidentiality)
  • All versions of spec drafts are to be archived
  • Observers have access to these archives

To their credit, JSR 314 has a publicly accessible issue tracker. I don't think there is any evil intent to hide the discussions and drafts. They just didn't start out with a mechanism that made it easy. That's why I think the JCP should put every new JSR on notice to make all information public by default.

What's in it for you, the user of Java technology? Better technology, I think. Expert groups can have unhealthy dynamics, such as group think, design by committee, and a mad rush to adopt half-baked ideas just before deadlines. JSF in particular has some unhappy features, and absences of features. When the process is more open, interested people can watch what is about to happen, blog about the good and the bad, and raise awareness in the wider community. If you agree, please kvetch in the blog comments so that the JCP folks pay attention.

Update March 4, 2009: JSR 314 has just decided to make their email discussions and spec drafts public! Thanks to Ed Burns for doing the right thing!

JSF2 will provide a standard mechanism for adding AJAX capabilities to JSF applications. Jim Driscoll has this example, but it is a bit odd—the property getter is actually a mutator. Here is a more run-of-the-mill example. The code is at the Kenai site for the upcoming Core JSF 3rd edition in the ch01/login-ajax directory. I used Eclipse with the Glassfish v3 plugin and the most current JSF2 module in Glassfish (2.0.0 B8).

We want to process a login and show a welcome message upon success, all without a page flip.

http://weblogs.java.net/blog/cayhorstmann/archive/jsfajaxlogin.png

The bean class is straightforward. (For simplicity, the code don't actually check the login credentials.)

package com.corejsf;

import javax.faces.model.ManagedBean;
import javax.faces.model.SessionScoped;

@ManagedBean(name = "user")
@SessionScoped
public class UserBean {
   private String name = "";
   private String password;

   public String getName() { return name; }
   public void setName(String newValue) { name = newValue; }

   public String getPassword() { return password; }
   public void setPassword(String newValue) { password = newValue; }
   
   public String getGreeting() { return name.length() == 0 ? "" : "Welcome to JSF2 + AJAX, " + name + "!"; }
}

In the JSF page, we need to include the AJAX JavaScript library, with the following incantation:

  <h:outputScript name="jsf.js" library="javax.faces" target="head" />

(The library name has recently changed. In the Public Review spec, it was called ajax.js.)

To avoid nested IDs for the components that are updated asynchronously, use the prependId attribute in the form:

  <h:form prependId="false">

Give IDs to the inputText andoutputText components.

  <h:inputText value="#{user.name}" id="name"/>
  <h:inputSecret value="#{user.password}" id="password"/>
  <h:outputText value="#{user.greeting}" id="out"/>

Then define the login button as follows:

  <h:commandButton value="Login" type="button"
    onclick="jsf.ajax.request(this, event, {execute: 'name password', render: 'out'}); return false;"/>

(The function was calledjavax.faces.Ajax.ajaxRequest in the PR spec.)

Note that this is not a submit button. When the button is clicked, the onclick handler is executed, but the form data is not posted back. There is no page flip. Thejsf.ajax.request method makes an asynchronous request to the server and receives instructions on which components to update. (Details below.)

The values of the execute and renderkeys are space-separated ID lists. The components on theexecute list go through all parts of the JSF lifecycle except for “Render Response”. Those on therender list go through “Render Response”.

The input components must be on the execute list, so that the bean's setters are invoked. (This is where Jim's example was a bit confusing. His “Count” button isn't updating the model. It just forces the property getter to be invoked.)

Now let's spy on what goes on under the hood. Execute the View Source command of your browser. (If you use Eclipse, it defaults to using an internal browser without a View Source command. That is not good. Select Window → Web Browser → Default System Web Browser from the menu and run the app again.)

http://weblogs.java.net/blog/cayhorstmann/archive/jsfajaxsource.png 

Note the element

<script type="text/javascript" src="http://weblogs.java.net/blog/cayhorstmann/archive/ch01-login-ajax/faces/javax.faces.resource/jsf.js?ln=javax.faces">

This is the result of the outputScript tag. You can spy on the script by pointing your browser to

http://localhost:8080/ch01-login-ajax/faces/javax.faces.resource/jsf.js?ln=javax.faces

It contains a documentation of the request function that is more up-to-date than the Public Review spec:

http://weblogs.java.net/blog/cayhorstmann/archive/jsfajaxscript.png

In Eclipse or Netbeans, it is easy to run the app server in debug mode and set a breakpoint in the bean's getters and setters.

http://weblogs.java.net/blog/cayhorstmann/archive/jsfajaxdebug.png

That's how I found out what needs to go to theexecute list. (In Jim's example, he added a submit button to that list, but it does actually no good in this case.)

As David Geary and myself were experimenting with different settings, David questioned whether there was any AJAX going on at all. To settle the question, I figured out how to set up the TCP monitor in Eclipse. (In Netbeans, this is much easier, but David says most people he meets prefer Eclipse :-)) Search for TCP in the Window→Preferences dialog...

http://weblogs.java.net/blog/cayhorstmann/archive/eclipse-tcp.png

Then point your browser tohttp://localhost:10333/ch01-login-ajax (or whichever port you set up). You'll see the requests and responses.

http://weblogs.java.net/blog/cayhorstmann/archive/eclipse-tcp2.png

For example, here is the response when clicking the Login button.

<?xml version="1.0" encoding="utf-8"?>
<partial-response><changes><update id="out">
<![CDATA[<span id="out">Welcome to JSF2 + AJAX, Cay!</span>]]></update>
<update id="javax.faces.ViewState"><![CDATA[j_id5:j_id6]]>`````</update></changes></partial-response>

As you can see, the response contains instructions how to update the output field.

Note that the output field must be present in the page. I tried to avoid the greeting property by using therendered attribute:

  <h:outputText id="out" rendered="#{user.name != ''}"  
    value="Welcome to JavaServer Faces, #{user.name}!"/>

That did not work—the AJAX update was not able to add the component since it didn't exist on the client. (Use View Source to verify that...)

For a chuckle, try a user name of ]]>. With today's version (2.0.0 B8), it doesn't work. Of course, that's a bug—someone was insufficiently paranoid aboutCDATA.

What can one learn from all this?

  • View Source is your friend
  • The debugger is your friend
  • The TCP monitor is your friend

With JSF development, you need all the friends you can get :-)