JSF2 Annotations Ignored

I couldn’t figure out why when I tried to retro-fit an old JSF project for JSF2 annotations the annotations weren’t being processed and the managed beans weren’t being instantiated.

Duh. The JSF2 annotation processor defers to faces-config.xml. My faces-config still said JSF 1.2 in the faces-config element and related xmlns attributes.

On a related note, annotations are only processed by default in the WAR WEB-INF/classes directory. If including JARs in WEB-INF/lib, each jar containing managed beans need a META-INF/faces-config.xml. Doesn’t have to have anything in it, but if it isn’t there, annotations won’t process.

RichFaces “columns” tag doesn’t display columns

The RichFaces manual show this example on using the “columns” tag:

<rich:dataTable value="#{capitalsBean.capitals}" var="cap">
<rich:columns value="#{capitalsBean.labels}" var="col" index="index">

<h:outputText value="#{cap[index]}" />

</rich:columns>

</rich:dataTable>

There is no corresponding sample Java code.

That’s very unfortunate, since in the absence of any better documentation, the natural thing to expect is that “capitalBeans.labels” would be a DataModel object, just as it is for the table itself. And it isn’t.

The model for columns is a simple ordered collection, such as a List.

JSF Submit-on-Enter forms

It’s not (so far as I know) officially required anywhere, but it’s a generally accepted principle that a form on a web page containing one text field and one submit button should submit itself when you type in text and press the ENTER key. A classic example of this is Google .

In actuality, it isn’t quite that simple. For totally unknown reasons, Microsoft Internet Explorer requires at least two text fields and this apparently goes all the way up to and including IE8 (at least when you upgrade from IE6). Fortunately, the “spare” text field can be invisible and ignored by the application.

JSF is more complicated, and AJAX-aware JSF such as RichFaces compounds the issue even more. Here’s a solution that seems to work for me:

  <h:panelGroup>
     <h:inputText style="visibility:hidden;display:none;"
        disabled="disabled" required="false" />
     <a4j:commandButton id="ask"
        type="submit" styleClass="button1"
        action="#{forgotPassword.doAskQuestion}"
        reRender="pnl1,fpMsg" value="Submit" />
 </h:panelGroup>

I am indebted to Lincoln Baxter for this particular hidden field definition (it’s quite touchy). He’s the person behind the JSF PrettyFaces product (ocpsoft.com).

Note that this is only a kludge, and may not always work. Additionally, it causes the RichFaces a4j:commandButton oncomplete action to misbehave under both IE and Firefox (though in different ways), as of RichFaces 3.4.

JSF/Facelets/RichFaces – and Maven

SF itself is fairly straightforward. Getting it functional in an appserver is another matter. Originally, I used MyFaces and Tomahawk. More recently, I’ve replaced MyFaces with the Sun JSF Reference Implementation (RI). Tomahawk, although a MyFaces library works just fine with the RI.

The JSF-impl jar is part of the server for JEE-compliant servers, such as recent versions of JBoss. For Tomcat, it has to be explicitly linked into the WAR (?). At any rate, it has to be put into the application’s classpath, and everyone seems to be putting it into the WAR and not the server lib directory. Since there are possible threading implications, I’m doing likewise.

Tomcat5 also needs the EL-ri JAR placed in its classpath. Tomcat6 includes the required classes as part of the base distribution.

For the whole set of dependencies, see the Maven POM for my sandbox project: here

Detached objects and JSF

JSF and JPA have proven to be more problematic than expected. The upside of the JSF framework is that the datamodel objects can be presented more or less right up to the page view layer without recourse to Data Transer Objects (DTOs). The downside, is that what’s presented isn’t always clear, leading to the dreaded OptimisticLockingException.

Officially, you get an Optimistic Locking Exception when your in-memory model is out of sync with the database (the database is more up-to-date than the model). In actuality, all that really needs to happen is for the ORM manager to think the model is out of sync with the database.

This perception seems to be distressingly easy cause. I’d blame it on a bug in OpenJPA, but I had similar issues with the detach/attach model of JDO. I’ve not seem any good writeups on how to prevent the problem, but I’ve come up with a means of handling it (right or wrong).

In Struts, the issue was more obvious. It may be the same mechanism in JSF, just more obscure.

Here’s what happens:

1. You fetch in a record, display it, get the user’s input back.

2. You merge the update with the database. OB so far.

By default, JSF will redisplay the same form. If you then do more changes and attempt to merge them, you get an OptimisticLockingException.

In theory, this shouldn’t be happening, but in the current and development releases of OpenJPA (up to 1.2.0), I can do only one merge.

As it turns out, the simple solution is to do the update, then fetch a brand-new copy of the object if further edits are required/anticipated. That makes it almost a return to the old-time concept of EJB where a handle could be used to re-activate a copy of the EJB. Only instead of a handle, use the object’s primary key. This should be low-overhead assuming the object’s still in cache, but it is irritating.

As to what’s actually causing the problem, it seems that the “dirty” flags for the object don’t get cleared when the merge is done and the EntityManager merge() method returns the object. So on the next merge, the database is updated, but the original pre-merge criteria were applied.