Friday Jul 31, 2009

JSF 2.0 - What's New

Andy Schwartz, one of the JSF EG members, has written an excellent blog [1] on what's new in JSF 2.0.
Definitely worth a read!


Monday Jul 06, 2009

Mojarra 1.2_13 has been released.

Just a quick note to let folks know that 1.2_13 has been released.   Please see the announcement for details.

Wednesday May 27, 2009

JSF Configuration Resource Ordering

A common issue in JSF 1.1/1.2 was the inability to control the order in which faces-config.xml files were parsed when said files were included in a JAR file.  Why does ordering matter?  Consider the decoration of entities such as ViewHandler or Application.  If your application contains more than two ViewHandlers, you may wish to have the ViewHandler delegation chain configured in a certain order.
The same holds true for PhaseListeners.  A developer may wish to have PhaseListenerB execute before PhaseListenerA.

A stop-gap measure was implemented by Mojarra (MyFaces does the same I believe) where the ordering of META-INF/faces-config.xml documents was determined by the natural sort order of the JAR name that contained the file.  While this worked, it wasn't a perfect solution as you were then forced to rename the JAR files to achieve the desired result.

JSF 2.0 solves this by requiring implementations to support partial ordering of the configuration resources via the ordering element.
The ordering element offers a way for a single document to state it wishes to be ordered before or after a specific document, or a group
of documents.  Documents can be identified by the top-level name element.  It's imporant to note that there are two documents in configuration processing that are always processed in a specific order and as such the ordering element has no impact.  The implementation default configuration resource is always processed first and the WEB-INF/faces-config.xml (if present) is always processed last.

Given the above, let's start with an example straigh from the specification:



            <others />

Looking over the four documents, we see that:
  • Document A is after document B
  • Document B has no ordering requirements
  • Document C is uses the others element to say it should be ordered
    before all the other documents that are being sorted
  • Document D has no ordering requirements
The resulting parse order may be:
  1. Implementation specific configuration resource
  2. Document C
  3. Document B
  4. Document A
  5. WEB-INF/faces-config.xml (if present)

Here's a couple other examples to illustrate an important point about the ordering.  When documents state they wish to be before or after another document, it may not necessarily be the case that the documents are ordered right next to each other.  I think the following examples will clarify what I mean:

Document A - <after><others/><name>C</name></after>
Document B - <before><others/></before>
Document C - <after><others/></after>
Document D - no ordering
Document E - no ordering
Document F - <before><others/><name>B</name></before>

The resulting parser order could be [F, B, D, E, C, A], but [F, B, E, D, C, A] would also be accurate.

Here's another:

Document <no id> - <after><others/></after><before><name>C</name></before>
Document B - <before><others/></before>
Document C - no ordering
Document D - <after><others/></after>
Document E - <before><others/></before>
Document F - no ordering

Possible parsing orders are:
  • B,E,F,<no id>,C,D
  • E,B,F,<no id>,C,D
  • B,E,F,C,<no id>,D
  • E,B,F,C,<no id>,D
An important note on that last example - if a document has ordering requirements, but no name, then the ordering requirements will be ignored.

Now, there are most likely going to be cases where the resulting partial parsing order doesn't quite fit with what an application needs.
In that case, the developer can fallback to another new element called absolute-ordering.  This element is only valid within the WEB-INF/faces-config.xml and will be ignored in all other cases.  The use of this element allows the developer complete control over the order that faces-config documents will be processed.

Here's a simple example:

In this case, the parsing order would be:
  • Implementation specific configuration resource
  • Document C
  • Document A
  • WEB-INF/faces-config.xml
It's pretty simple, however, developers should be aware that any documents that aren't explicitly referenced within the absolute-ordering element will not be processed.  Though it is possible to include those documents without having to enumerate them all individually.

        <others />
In this example, assuming we started with documents [A, B, C, D], then the resulting parse order may look like:

  • Implementation specific configuration resource
  • Document C
  • Document B
  • Document D
  • Document A
  • WEB-INF/faces-config.xml

Note that B/D could be interchanged.  The others element may appear any where within the absolute-ordering element, but it may only do so once.

JSF 2.0 passes final ballot!


Unified Expression Language and JSF 1.2/2.0

The Unified Expression Language in EE6 is getting updated to support arbitrary/parameterized method calls without having to use static EL functions.

Here's is a quick example.  Consider the following managed bean:
public class TestBean {
    private List<String> names = new ArrayList<String>();

    public String greetName(String name) {
        return "Hello, " + name;

    public List<String> getNamesGreeted() {
       return names;

and now consider the following fragment from a Facelet view:
<h:outputText value="#{bean.greetName('Bill')}" /><br />
<h:outputText value="#{bean.namesGreeted.size()}" />

The first outputText will display "Hello, Bill", and the second, displays the size of the collection of all the names greeted, which in this simple example, would be "1".

So what about parameterized MethodExpressions (i.e. <h:commandButton action="#{bean.doAction(arg1, arg2)}" ... />)?
Well, this is currently a work in progress by the EL implementation folks.  Stay tuned for updates on this particular topic.

The new EL is already available in GlassFish V3, so if you're using V3 promoted builds, you can start taking advantage of the EL now with JSF and no configuration is necessary.

If you'd like to use the new EL in GlassFish V2, you can, as long as you're not using JSP.  The JSP compiler performs static analysis of the page being compiled and will complain when it encounters parameterized expressions.  This means you'll need to use an alternative view technology such as Facelets.

The EL libraries are available at the following URLs:
Copy the two JAR files to ${GLASSFISH_HOME}/lib, then edit ${GLASSFISH_HOME}/domains/<domain_name>/config/domain.xml and add the following attribute to the java-config element:
If the classpath-prefix attribute has already been defined, then append these two jars after the existing entries.  This modification will require a restart of the domain.  After these steps are complete, you should be able to leverage the new EL features.

Lastly, I'd recommend reviewing the change log for the new expression langauge to get familiar with what it offers and its limitations.

Monday May 18, 2009

JSF 2.0 - Bookmarability/View Parameters

This seems to be one of the top features users have been requesting for JSF 2.0.  For those of you not reading the specification revisions as it has been published, the feature is available.

Bookmarkability is achieved using two new components:
  • h:link
  • h:button
Both of these components will generate a URL based on the specified navigation outcome.  Keep in mind, that in JSF 2.0, implicit navigation is available, so this outcome can be defined within the view or using standard navigation rules.

So, let's start with a simple example using one of these new components with implicit navigation.  Please note that the following examples assume that the FacesServlet is mapped to '\*.xhtml'.
    <h:link outcome="viewEntry" value="Link">
        <f:param name="entryName" value="#{someBean.entry}"/>
In the example above, outcome, again, is the result of the navigation.  In this case, since we're assuming no navigation rules have been defined in the faces-config.xml, we're navigating to viewEntry.xhtml.  The f:param tag is adding a query parameter to the generated link.  When the component is rendered, the end result is something like:
<a href="http://localhost:8080/myapp/viewEntry.xhtml?entryName=entry1">Link</a>
The same can be achieved using navigation rules defined in the faces-config.xml.  For example:

Then reference the navigation outcome in one of the new components:
<h:link outcome="redirectOutcome" value="Link" />
which generates:
<a href="http://localhost:8080/myapp/page2.xhtml?entryName=entry1">Link</a>
Now, there's a third source of parameters that has been introduced in JSF 2.0 called 'View Parameters'.  These parameters are specified as metadata to the page and can be included in the generated URLs.  There's a lot more to view parameters than what is about to be shown.  I'll go more into that later on in this entry. 

Here's a simple example of a View Parameter (assume this is defined within somepage.xhtml):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
<html xmlns=""
            <f:viewParam id="id" name="viewParam" value="#{}" />       

If the developer sets the 'includeViewParams' attribute on h:link or h:button or the include-view-params attribute on the redirect element of a navigation-case to true, then the UIViewParameters will be a part of the generated URL.

So, building off of the metadata example above, consider the following h:link within another view:
<h:link outcome="sompage.xhtml" value="Link">
    <f:param name="componentParam" value="component"/>
The generated URL would look like:
<a href="http://localhost:8080/myapp/somepage.xhtml?componentParam=component&viewParam=view">Link</a>
Keep in mind that the view parameters that are included in the generated URL will be those of of the view being navigated to.

It's also important to note that there is an order of precedence for adding the parameters from the different sources.  This order is essentially, component, navigation-case parameters, followed by view parameters.  This means that if a component specifies a parameter via f:param that has the same name as that in a navigation-case or in the view metadata, then the parameter value from the navigation-case or view metadata will not be included in the query string.  

Now, getting back to view parameters, there's some other details I'd like to share.  In 1.2, the typical GET lifecycle would result in the restore view phase being invoked immediately followed by render response.  This is still true in 2.0 \*except\* when the view being processed has view parameters.  In this case, the view parameters are processed using the standard post-back processing lifecycle (i.e. apply request values,  process validations, update model, invoke application, then render response).   Processing view parameters in this fashion allows developers to attach converters and validators to the view parameters to enforce the integrity of the parameter data being passed to the view.  For example:

            <f:viewParam id="id" name="id" value="#{newsReader.selectedStoryId}"
                     requiredMessage="You did not specify an id. (The id parameter is missing)"
                     converterMessage="Invalid id. (The id parameter is not a number)"
                     validatorMessage="Invalid id. (The id parameter is not a positive number)">
                <f:validateLongRange minimum="1"/>

Lastly, developers need not restrict their usage of f:metadata to view parameters only.  Facelets templating features and view events (i.e. f:event) can also be specified.  One useage restriction of f:metadata needs to be kept in mind though - it must be defined within the view and not within a template.  If this restriction isn't observed, the content within f:metadata will not be processed.

That should cover the basics for now.  Please download the Mojarra 2.0.0 nightly and give this feature a shot.  Feel free to ask questions on the GlassFish Webtier forums, and if you think you found an issue, please let us know about it.




« July 2016