What Do JSF Guys Do In Munich?

November 14, 2009 by andyschwartz

The same thing as everyone else apparently: drink beer!

Cheers From Munich

Kito, Matthias, Andy

I had the honor of attending/presenting at W-JAX 2009 in Munich this week. The highlight of the conference for me was of course getting to spend time with friends/colleagues old and new.

Three things that I learned while in Munich:

  1. Hanging around Matthias is a great way to meet interesting people.
  2. When in Munich, try the grilled pork  knuckle at Haxnbauer.
  3. A good presentation can work even if you don’t speak the language.

On Friday I sat in on (fellow EG member) Martin Marinschek’s talk titled “Wie Sie Ihre JSF-Anwendeng garantiert nicht produktiv bekommen”, which covered 17 tips for how *not* to build your JSF application. Martin had a light hearted (but informative) tone that the audience clearly enjoyed.  I had a blast trying to guess what the tips were based on keywords/APIs in the slides. :-)

On Thursday evening a group of us JSF folks ventured out of the hotel (yay!) and into Munich city center for dinner. We avoided the Hofbrauhaus (worried it would be a bit too touristy/loud) and instead ended up at the Schneider-Weisse beer house.

JSF In Munich

JSF Munich Crew: Kito, Matthias, Andy, Thomas (of JSF/Ajax Matrix fame), Martin

We ate roast pork shoulder, had a few drinks and discussed politics, religion, the fate of mankind and all other matters philosophical and metaphysical.  Not a word about JSF the entire evening!

Okay, actually, no… that is a total lie.  Either way, it was a wonderful evening and I am so happy that I had the chance to be there.

Thanks Matthias for helping to bring me to W-JAX, for being a great translator, host and friend, and also for buying me my first beer in over 20 years!

Tomorrow morning I am off to Antwerp to meet up with Pete Muir and Dan Allen.  We will be discussing JSF 2 future/community in our university session at Devoxx on Monday:

JSF 2 And Beyond: Keep the progress coming

If you are going to be at Devoxx and you are even remotely interested in JSF, you won’t want to miss this talk. Hope to see you there!

Anyone Have An Oversized Foam Cowboy Hat That I Can Borrow?

September 13, 2009 by andyschwartz

I couldn’t resist posting this screen shot from the Devoxx 2009 speakers page:

Need Foam Cowboy Hat

Okay, yes, I admit, I am a Java Posse geek. So I was pretty tickled to see this particular configuration of speakers. Clearly it is time for me to get a new headshot. If only I had one of those cool foam cowboy hats! :-)

(More info on my upcoming talks coming soon!)

What’s New in JSF 2?

July 31, 2009 by andyschwartz

With so many sources of information available on JSF 2, why bother with another overview? After all, this ground has already been covered quite extensively:

One problem I have been facing is deciding where to point my Oracle colleagues who are interested in a quick introduction to the JSF 2.0 feature set. The spec contains all of the information, but that’s some pretty heavy reading. The blogs do a phenomenal job of covering specific features but do not provide a big picture overview. The Webinar provides the big picture overview, but some folks might prefer reading over listening/watching. The slides also provide an overview, but I wanted something with more prose than bullets.

So, on the theory that more is good, and since I could not find quite what I was looking for, I decided to spend some time writing up my own take on the new JSF 2.0 feature set. Of course, I borrowed from all of the above sources while working on this, so many thanks to my JSF colleagues for making my job easier!

Note that I do not attempt to cover these features in extreme detail. This is just an overview. However, each section includes links to more detailed information where available, so please click through if you do not find the level of detail that you need here.

Contents

View Declaration Language and Facelets

Not to knock JSP, but even JSP champions must admit: JSP as the primary view technology for JSF has not been a walk in the park. The problems have been discussed for years, dating back to the now classic Improving JSF by Dumping JSP, published back in 2004 just months after the JSF 1.0 spec was released. As of JSF 1.2/JSP 2.1, several of the key issues have been addressed. However, the JSF/JSP combination certainly has room for improvement.

The JSF community has not been sitting still. Several JSF-optimized alternatives to JSP have emerged, including Apache Shale’s Clay (now retired), JSFTemplating and Facelets. However, the lack of a standard solution remains a sore point for JSF users. JSF 2.0 recognizes the need for a standard alternative to JSP and addresses this by taking two steps.

First, JSF 2 provides a generic foundation for integrating view declaration languages into the JSF runtime environment. The ViewDeclarationLanguage API defines the contract through the JSF runtime interacts view declaration language implementations in order to complete tasks such as building up the component tree. This contract allows framework authors to define their own view declaration languages and integrate these with JSF in a standard way.

Second, JSF introduces the first standard non-JSP view declaration language: Facelets! JSF 2.0 includes a re-purposed version of the Facelets 1.x API/implementation. This 2.0 version of Facelets should be very familiar to anyone who has been using Facelets 1.x. Most of the 1.x APIs are present, though there has been some tweaking/repackaging as part of the standardization process.

The inclusion of Facelets as a standard view declaration language should ease any concerns that development teams may have about embracing this technology.

While Facelets is a new focus for the JSF specification, JSP support is still available for those users who are not ready to make the jump to a new view definition technology. Note, however, that the JSP side of the JSF specification is basically standing still. None of the new features that involve new tags (composite components, system events, Ajax, etc…) are exposed through JSP.

Links

Composite Components

Let’s take a quick look at how to implement a custom component in JSF 1.x: Just implement your UIComponent subclass, and… done! Oh,wait… you might want to move your markup rendering code into a Renderer. Oh, and don’t forget to register your component and renderer in a faces-config.xml file. Er… then you just need to implement your JSP tag. Oh, and don’t forget that tld!

Okay, so JSF custom component development has always been a chore. The problems have long been known and are well documented.

JSF 2 greatly simplifies custom component development with the introduction of the “composite component” feature. This feature allows a custom component to be implemented with a single file – no Java code required.

Let’s take a look at the obligatory “Hello, World!” example, starting with a composite component that renders the salutation:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:composite="http://java.sun.com/jsf/composite">
<head>
<title>My First Composite Component</title>
</head>
<body>

<composite:interface>
    <composite:attribute name="who"/>
</composite:interface>

<composite:implementation>
    <h:outputText value="Hello, #{cc.attrs.who}!"/>
</composite:implementation>

</body>
</html>

The composite component is defined via an XML file containing XHTML contents plus elements from the “http://java.sun.com/jsf/composite” namespace. The <composite:interface> element contains metadata that describes the characteristics of component, such as supported attributes, facets and attach points for event listeners. The <composite:implementation> element contains the markup that is substituted for the composite component when it is referenced by a consuming page.

To make the composite component available for use, we simply drop this file into a “resources” directory (more on resource loading later). The tag name for the composite component is derived from the file name. The tag namespace is based on the location of the composite component within the resources directory.

If we dump the above code in a “Hello.xhtml” file inside of a “resources/greet” directory, we end up with the following:

  • Tag name: hello
  • Tag namespace: http://java.sun.com/jsf/composite/greet

We can then reference our new component as follows:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:greet="http://java.sun.com/jsf/composite/greet">

  <!-- Snip -->

  <greet:hello who="World"/>

</html>

That’s quite a simplification from earlier days of writing UIComponent subclasses, renderers, tags, faces-config.xml entries and tlds!

The composite component architecture is much more sophisticated than demonstrated with this minimal sample. Support for all of the usual component-centric functionality is provided, including inserting facets, adding children, attaching listeners, validators, converters, etc… See the links below for more extensive coverage of JSF 2 composite components.

Links

Ajax

Here we are, 2009, four years since the term Ajax was coined. Hasn’t the JSF/Ajax integration problem been solved yet?

Well, actually, yes, it has. If the JSF AJAX Component Library Feature Matrix is any indication, this problem has been solved many times!

The availability of so many JSF/Ajax frameworks is a good indication that JSF provides a strong foundation for Ajax. So, does that mean that we are done? What’s left for the JSF spec to do?

Well, two things actually:

  1. Compatibility. While it is impressive that so many JSF/Ajax solutions are available, the subtle differences between these solutions lead to cross-framework compatibility problems.
  2. Native Support. Isn’t it time that JSF users have access to Ajax functionality without requiring a 3rd party framework?

JSF 2 attempts to address both of these issues by providing various new Ajax-related APIs and infrastructure. Let’s take a look at these by walking through the lifecycle of a typical Ajax request.

Ajax Request Lifecycle

Starting on the client, JSF 2 exposes a new JavaScript API, jsf.ajax.request(), that issues an Ajax request back to the current view. This method collects any data that needs to be included with the request, prepares the request payload, registers a response handling callback and then posts the request back into the Faces lifecycle.

Once the request enters the Faces lifecycle, the state of the Ajax request is captured via the PartialViewContext. This object provides access to information such as which components are targeted for processing/rendering. The PartialViewContext’s processPartial() method uses this information to perform partial subtree processing/rendering.

When the rendered response is sent back to the client, the callback previously provided by jsf.ajax.request() is invoked. This callback automatically updates the client-side DOM to reflect the newly rendered markup.

In order to encourage compatibility across JSF components/frameworks, the request and response payloads have also been standardized.

<f:ajax>

The jsf.ajax.request() JavaScript API is a primitive that is primarily targeted for use by frameworks as well as by the JSF implementation itself. JSF 2 also includes a declarative approach that is intended to be more convenient for page authors. This approach leverages the new <f:ajax> tag.

Instead of manually coding the JavaScript for the Ajax request call:

  <h:commandButton onclick="jsf.ajax.request(this,event,{render:'foo'});return false;"/>

Page authors can declaratively specify the same behavior:

  <h:commandButton">
    <f:ajax render="foo"/>
  </h:commandButton>

The presence of the <f:ajax> tag enhances the markup of the associated component to include a script that triggers the Ajax request. This allows Ajax requests to be issued without requiring the page author to write any JavaScript code.

Links

State Saving

JSF state saving has long been a sore point, both for application developers as well as component developers. The main problem for application developers is that the size of the saved state can be large. This makes client-side state saving impractical and leads to session state bloat. For component developers, the issue is that implementing saveState and restoreState methods is tedious and error prone.

JSF 2.0 addresses these issues with the introduction of a new “partial” state saving mechanism. This solution was inspired by a proposal that Adam Winer made (and implemented in Apache Trinidad) over 3 years ago. The key concept is that saving the entire state of the component tree is redundant, since the component tree can always be restored to its initial state by re-executing the view (ie. by re-executing Facelet handlers to re-create the component tree).

If we use the view definition to restore the component tree to its initial state, then the only state that needs to be saved is state that has been modified since the view was initially created. And since in most cases the number of components that are modified after component tree creation is small, the size of this delta state is typically much smaller than the full component tree state.

A requirement for the delta/partial state saving approach is that component implementations must know when their initial state has been fully configured. JSF 2 introduces the PartialStateHolder contract to help with this requirement. The PartialStateHolder’s markInitialState() method is called to notify the implementing component that its intial state has been established. Only modifications that occur after this notification need to be saved.

A second API has been introduced to help component implementations manage their state: StateHelper. The StateHelper provides storage for component state (such as attributes, listeners, etc…) and relieves the component author from having to provide custom saveState and restoreState implementations.

As a result of these new APIs, JSF 2 state saving is both more efficient and easier to use!

If the PartialStateHolder/StateHelper APIs seem vaguely familiar to you, you just might be thinking of Apache Trinidad’s FacesBean.

Links

System Events

JSF 1.x includes two event delivery mechanisms. FacesEvents are delivered to FacesListeners in response to user interaction, such as editing an input component, or activating a command component. PhaseEvents are delivered to PhaseListeners at the beginning and end of each phase in the Faces lifecycle. These solutions do not include notification of other interesting events that occur during the processing of a Faces request.

JSF 2’s system events provide the ability to deliver SystemEvents to SystemEventListeners at arbitrary points during the request processing lifecycle. System events fall into two categories: global system events and component system events.

Global system events are delivered in response to application-wide activities, for example Application initialization/destruction. Listeners for these events are registered via a call to Application.subscribeToEvent().

Component system events are specific to individual component instances. For example, a component system event is delivered each time a component has been added to the view, or rendered, or validated. Component system event listeners are typically registered via a call to UIComponent.subscribeToEvent(). However, component system events also bubble up to the Application, where they are re-delivered to Application-level listeners. This allows global monitoring of component-related events.

Both global and component system events are fired by calling Application.publishEvent().

In order to simplify listener registration for component-specific events, JSF also provides a declarative listener registration solution via the <f:event> tag. To register a listener declaratively, simply place the <f:event> tag inside of the target component. For example:

  <h:inputText>
    <f:event type="preValidate" listener="#{bean.doSomePreValidation}"/>
  </h:inputText>

This registers the method located at #{bean.doSomePreValidation} as a pre-validation listener for the parent inputText component.

By providing notification of all sorts of activities that previously went undetected, system events open up many possibilities for page authors, component authors, framework authors and also for the JSF implementation itself!

Links

Navigation

Implicit Navigation

In JSF 1.x, even the most trivial navigation cases required an entry in faces-config.xml. For example, when navigating from page1 to page2 in response to a “success” outcome on a command component in page1 required the following XML boilerplate code:

  <navigation-rule>
    <from-view-id>/page1.xhtml</from-view-id>
    <navigation-case>
      <from-outcome>success</from-outcome>
      <to-view-id>/page2.xhtml</to-view-id>
    </navigation-case>
  </navigation-rule>

Fun stuff, right?

JSF 2.0 introduces a simplification that reduces navigation-related grunge code: implicit navigation. If no matching navigation case is found after checking all available rules, the navigation handler checks to see whether the action outcome corresponds to a view id. If a view matching the action outcome is found, an implicit navigation to the matching view occurs.

The end result: smaller faces-config.xml files. Oh, and happier JSF users.

Conditional Navigation

Another enhancement to the navigation subsystem is the addition of conditional navigation cases. The conditional navigation feature allows navigation cases to specify a pre-condition that must be met in order for the navigation case to be accepted. The pre-condition is specified as an EL expression using the new <if> configuration element:

    <navigation-case>
      <from-outcome>success</from-outcome>
      <to-view-id>/page2.xhtml</to-view-id>

      <!-- Only accept this case if the following condition is true -->
      <if>#{foo.someCondition}</if>

    </navigation-case>

One of the motivations behind this feature is to allow pre-conditions to be implemented in a loosely coupled, navigation-agnostic way. Instead of requiring a managed bean or business layer object return a navigation-centric outcome value, we can now use EL to interact with arbitrary properties/methods on these objects, freeing these objects from awareness of the JSF navigation system.

Preemptive Navigation

The JSF 1.x navigation system is a black box. The only entry point, NavigationHandler.handleNavigation(), simply evaluates the navigation rules and causes a navigation to occur, without giving any insight into how the navigation target is determined.

JSF 2.0 provides more transparent view of the navigation system. The new ConfigurableNavigationHandler API provides access to metadata describing the available navigation rules/cases. In particular, the getNavigationCase method allows clients to ask the ConfigurableNavigationHandler to determine which navigation case matches a particular outcome and from action. With this new contract, it is possible to “preemptively” evaluate navigation rules and retrieve the resulting target view id and URL.

Why is this interesting? Well, before JSF 2.0, navigation rules were explicitly the domain of POST requests. Previously, the only time that navigation rules came into play was during the invoke application phase while handling a POST. By making the navigation rules available outside of invoke application, we open up the possibility of leveraging this information at other points in the lifecycle, for example, during render response.

As we’ll see in the next topic, this has some interesting consequences relating to better support for GET-based navigation and bookmarkability, an area that has received much interest in recent years.

Links

GET Support

It’s not so much that JSF 1.x does not provide any support for GET request handling… after all, there are some low-level primitives (like PhaseListeners) available. However, there is no denying that GET requests are a second-class citizen in earlier versions of the JSF specification. JSF 2.0 introduces several features that tackle this shortcoming.

View Parameters

The JSF 1.x specification goes to great lengths to provide a robust lifecycle for processing of values arriving from the client via Http requests. Values are pulled from the request, converted from strings to the proper target type, validated against application-specified constraints and finally, pushed into the model. Very powerful.

Of course, there is one caveat: all of this processing only applies to values arriving on POST requests. If the same value arrives via a GET request, well… tough luck! Or, well, maybe write a PhaseListener to manually process the request. Oh, and good luck reusing your converter/validator implementations to process those values!

JSF 2 brings some sanity to this situation with the introduction of “view parameters”, inspired by Seam’s page parameters. View parameters provide a simple, declarative way to map incoming request parameter values to any EL-reachable location. These mappings are specified using the new <f:viewParam> component, which lives in the (also new) <f:metadata> section of the view, eg:

  <f:metadata>
    <f:viewParam name="foo" value="#{bean.foo}"/>
  </f:metadata>

The above sample specifies that the value of the request parameter with the name “foo” will automatically be picked off of the request and pushed into the property at #{bean.foo}. So if we receive a GET request as follows:

page1.jspx?foo=bar

The value #{bean.foo} property will be set to “bar” when JSF starts processing the request. No more need to manually code this sort of mapping in a PhaseListener. Yay!

But wait, there is more… The <f:viewParam> component happens to be an EditableValueHolder, which means that view parameters can participate in conversion/validation. You can attach any converter/validator to an <f:viewParam> component , just as you would with, say, <f:inputText>. No more need to write custom conversion/validation logic specifically for GET processing.

PreRenderView Event

View parameters bring to GET requests much of the JSF request processing lifecycle that was formerly reserved for POSTs: request parameter decoding, type conversion, validation and model updates. But view parameters stop short of one last important step: invoking application-defined listeners. For this, system events come to the rescue.

JSF 2 includes a PreRenderViewEvent that is fired after view parameters have finished processing, but before the view is rendered. The pre-render view listener can be registered using the <f:event> tag, eg:

  <f:metadata>
    <f:viewParam name="foo" value="#{bean.foo}"/>
    <f:event type="preRenderView" listener="#{bean.doSomething}"/>
  </f:metadata>

This listener might be used to load data or set up context that is required prior to rendering. In addition, the listener may choose to programmatically navigate away from the requested view in the event that some pre-condition is not met (eg. the user does not have access to the requested page).

With the addition of view parameters and the pre-render view event, the GET request processing lifecycle is finally on par with the rich lifecycle provided for POSTs.

<h:link>/<h:button>

Now that we have the ability to respond to GET requests more effectively, what about the flip side? How do we issue these GET requests in the first place? Looking at the JSF 1.x components, <h:commandButton> and <h:commandLink> do not fit the bill as these components are form/POST-centric. <h:outputLink> works, but has the drawback that it requires manual construction of the destination URL.

JSF 2 includes two new components that simplify GET-centric navigation: <h:link> and <h:button>. With these components, the page author no longer needs to hand code the destination URL. These components leverage the JSF navigation system to determine the appropriate destination. Instead of explicitly specifying the URL, users specify the desired logical outcome, eg:

  <h:link outcome="success"/>

Preemptive navigation is used to translate this logical outcome into a physical destination. At render time, the navigation system is consulted to map the outcome to a target view id, which is then transparently converted into the destination URL. This frees the page author from having to worry about manual URL construction.

Note that the URL construction process is not solely based on the target view id. The <h:link> and <h:button> components also integrate nicely with view parameters. By specifying the includeViewParams attribute, eg:

  <h:link outcome="success" includeViewParams="true">

The view parameters specified by the destination view are taken into account when building up the URL – ie. an inverse mapping of the view parameters is applied. Each view parameter value is extracted from the location specified by its EL expression, converted to a string, and added to the query string under the view parameter’s name.

This provides a simple yet powerful mechanism inserting required parameters into the query string. It also provides a nice technique for transferring request-scope data across requests.

In addition, page authors may manually insert query parameters using the <f:param> tag, eg:

  <h:link outcome="success">
    <f:param name="foo" value="bar"/>
  </h:link>

And of course, the key benefit of this solution: the resulting URLs are bookmarkable!

Links

Scopes

View Scope

View scope is one of two new scopes introduced in JSF 2 that fall into the category of “longer than request, shorter than session” scopes. As the name implies, state that is placed into view scope is preserved until the user finishes interaction with the current view. If you have ever had the joy of trying to figure out why your command component isn’t firing after binding the rendered attribute to a request-scoped managed bean, view scope may just be the answer to your problems.

View scope state can be accessed programmatically via UIViewRoot.getViewMap(). EL access is available via the #{viewScope} implicit object.

Flash Scope

JSF 2 borrows a concept from Rails with the introduction of the new flash scope. Flash scope provides a short-lived conversation. State that is placed into flash scope is propagated across a single view transition, including surviving redirects, and is cleaned up before moving on to yet another view. If you have been resorting to session scope to store state that needs to survive a redirect, flash scope might just be for you.

Flash scope state can be accessed programmatically via the ExternalContext.getFlash() API. EL access is available via the #{flash} implicit object.

Custom Scopes

JSF 2 also provides a small enhancement to the managed bean system to allow faces-config.xml authors to place managed beans into custom scopes. The trick is that custom scopes are specified via an EL expression rather than a keyword, eg:

  <managed-bean>
    <managed-bean-name>foo</managed-bean-name>
    <managed-bean-class>com.foo.Foo</managed-bean-class>
    <managed-bean-scope>#{someCustomScope}</managed-bean-scope>
  </managed-bean>

The EL expression identifies the location of a map that holds the properties for the scope. When it is time to instantiate a custom-scoped managed bean, the managed bean system automatically pushes the new instance into the map under the specified name.

Links

Configuration

Managed Bean Annotations

JSF 2 provides a long awaited usability improvement with the introduction of annotation-based configuration. The goal of these annotations is to reduce the size and complexity of faces-config.xml files, which have a tendency to get quickly out of hand. The first set of annotations allows developers to configure managed beans. The old style XML configuration:

  <managed-bean>
    <managed-bean-name>foo</managed-bean-name>
    <managed-bean-class>com.foo.Foo</managed-bean-class>
    <managed-bean-scope>session</managed-bean>
  </managed-bean>

Can now be replaced with annotations on the bean class:

@ManagedBean
@SessionScoped
public class Foo {
}

The name for the managed bean is automatically derived from the name of the annotated class. In the above example, the presence of @ManagedBean annotation on the Foo class makes a managed bean with the name “foo” available. Alternatively, the @ManagedBean annotation also allows a name to be specified explicitly.

Annotations are also available for the other scopes, as well as for managed properties.

Note: An effort is underway to unify these bean/scope annotations across specifications (eg. JSF, JCDI) for Java EE 6. In the meantime, the JSF 2 managed bean annotations are considered an optional part of the JSF 2 specification. Mojarra and MyFaces already provide implementations of these optional annotations.

Component Annotations

As part of the effort to prune down XML configuration bloat, JSF 2 also includes annotations targeted at authors of custom components (and associated objects). These annotations include:

  • @FacesComponent
  • @FacesRenderer
  • @FacesConverter
  • @FacesValidator
  • @FacesBehavior

Of course, the good old faces-config.xml elements are still present for those who prefer to go that route.

Faces-config.xml Ordering

A long-standing problem with faces-config.xml loading is that the order in which these files are loaded is unspecified. For the most part (eg. for managed bean or navigation configuration) the order is not significant. However, there are certain cases, such as decorating Application-level objects (eg. ViewHandlers), where the order may matter.

During the JSF 1.2 timeframe, both MyFaces and the JSF RI adopted a convention whereby faces-config.xml files are loaded based on an order derived from the containing jar file’s name. However, this was just a temporary implementation-level solution that was put in place until the issue could be addressed by the specification.

JSF 2 solves this problem by allowing faces-config.xml files to provide ordering-related hints. Each faces-config.xml file may now declare a name (via a new <name> element) that can be referenced by other faces-config.xml files for ordering purposes. A new <ordering> element and sub-elements allow relative ordering requirements to be specified.

This addition to the spec provides a much cleaner/safer way for the various frameworks/component sets to play together in the JSF ecosystem. No more jar file name hacking!

Project Stage

Project stage is a new configuration option that allows the application developer/deployer to specify a hint to the JSF implementation regarding the role of the current deployment. Valid values include:

  • Development
  • Production
  • SystemTest
  • UnitTest

This hint allows the JSF implementation to optimize its behavior for the current stage. For example, the JSF implementation might provide more verbose development-time diagnostics than would be practical for a production environment.

For a more specific example, check out the Mojarra team’s recent use of project stage to provide automatic compression of JSF’s own JavaScript library.

The project stage can be set either as a context parameter (“javax.faces.PROJECT_STAGE”) or via JNDI (“java:comp/env/jsf/ProjectStage”).

And, yes, my good friend and colleague Matthias Wessendorf would also like to see the project stage exposed as a system property. :-)

Links

Behaviors

The original JSF 1.0 specification introduced the concept of “attached objects” – ie. objects that are not UIComponents, but are attached to UIComponents in order to influence some aspect of the component’s behavior. This technique is used for conversion and validation by value holding components, eg:

  <h:inputText value="#{foo.value}">
    <f:convertNumber integerOnly="true"/>
  </h:inputText>

JSF 2 adds a new class of attached object: the ClientBehavior. Whereas converters/validators focus on value processing, client behaviors assist in enhancing a component’s client-side functionality. Before client behaviors, page authors were forced to resort to hand-coding scripts and manually wiring these scripts up via event handling attributes, eg:

  <h:commandLink onclick="return confirm('Really???')"/>

Client behaviors allow such scripts to be packaged up into reusable bundles that can be attached to components declaratively, eg:

  <h:commandLink>
    <foo:confirm message="Really???"/>
  </h:commandLink>

This declarative approach is made possible by the introduction of two new contracts (along with various supporting APIs). The ClientBehavior contract specifies how client behavior implementations provide access to scripts and more generally how these objects participate in the component lifecycle. The ClientBehaviorHolder contract specifies how client behaviors are attached to components, similar to how EditableValueHolder specifies how converters and validators are attached.

In addition to defining these new contracts, JSF 2 also includes one concrete ClientBehavior implementation: the AjaxBehavior. The declarative form of this client behavior should be familiar from our earlier discussion on Ajax:

  <h:commandLink>
    <f:ajax/>
  </h:commandLink>

Although the JSF specification only defines a single concrete client behavior, the client behavior architecture is designed for extensibility. Expect to see plenty of third party client behavior implementations popping up!

Links

Validation

Bean Validation

The Bean Validation JSR (JSR-303) defines a generic, tier-independent mechanism for specifying data validation constraints. The specification includes several standard constraint annotations (eg. @NotNull, @Size, @Min, @Max, etc…) and also allows custom constraints to be defined.

JSF 2 provides built-in integration with JSR-303 constraints. In environments where a bean validation implementation is present, JSF automatically validates constraints for beans that are referenced by UIInput values.

In addition, <f:validateBean> may be used to fine tune bean validation behavior. For example, the validationGroups attribute may be used to manually specify which validation groups should be taken into account when validating a particular component:

  <h:inputText value="#{bean.foo}">
    <f:validateBean validationGroups="com.foo.validation.groups.Billable"/>
  </h:inputText>

When validation constraints fail, any associated error messages are automatically translated into FacesMessages by the JSF implementation, thus communicating the failures to the end user without placing any burden on the application developer.

Empty Field Validation

In previous JSF releases, Validators were not applied to EditableValueHolder components with null/empty submitted values. Unfortunately, this behavior limits the utility of constraints that actually check null/empty values, such as the JSR 303 @NotNull constraint. In order to support @NotNull and other similar constraints, JSF 2 changes the behavior of null/empty value validation. As of JSF 2, when a JSR-303 implementation is present, null/empty values are validated.

Since this may cause problems for legacy Validator implementations that do not expect to see null/empty values, the javax.faces.VALIDATE_EMPTY_FIELDS context parameter can be used to disable this behavior.

New Validators

In addition to <f:validateBean>, JSF 2 includes two other new validators:

  1. <f:validateRequired> provides required field validation.
  2. <f:validateRegexp> provides regular expression-based validation

Links

Error Handling

JSF users who are new to Facelets will appreciate the more informative Facelets error page that provides information such as: line numbers! (And no, not just stack trace line numbers, but actual line numbers within the Facelets file.)

Of course, error pages are only useful in cases where the triggering exceptions are allowed to propagate up to the error handling layer and not pre-maturely consumed. The JSF 2 specification helps in this area with the introduction of the new ExceptionHandler API. JSF implementations are now required to allow all “unexpected” exceptions to propagate out of the current lifecycle phase so that they can be handled globally by an ExceptionHandler instance.

This change should reduce/eliminate those mysterious, hard to debug “swallowed” exceptions, as the ExceptionHandler now acts as a central clearing house for exceptions. Another advantage of this centralization is that it allows users/frameworks to devise more sophisticated error handling strategies.

Resource Loading

If you spend time implementing custom JSF components of any complexity, eventually you are going to run into the question: what do I do with my component’s images (or JavaScript libraries, or style sheets)? Just about every JSF component framework has run into this problem and, in the absence of a standard solution, has solved this problem in its own proprietary way.

JSF 2 provides a standard solution to this problem with the introduction of the ResourceHandler API. The ResourceHandler is responsible for serving up resources (images, JavaScript files, style sheets, etc…) from well-known locations on the class path. Resource requests are routed through the FacesServlet, which passes these request onto the ResourceHandler for processing. This solution allows components and their resource dependencies to be bundled in the same jar file with no need for a bonus servlet, servlet filter or phase listener to serve up these artifacts.

JSF 2 also provides several new features in order to facilitate insertion of resource references. Authors of custom Java components can annotate their UIComponent subclasses with the @ResourceDependency annotation to identify any resources that need to be pulled in when the component is used. Composite component authors can use the new <h:outputScript> and <h:outputStylesheet> to pull in scripts and style sheets. The #{resource} implicit object provides direct EL access to resource URLs.

The @ResourceDependency annotation and the <h:outputScript>/<h:outputStylesheet> components take advantage of another new feature: resource relocation. Resource relocation gives the component/page author control over where resource references are inserted into the rendered markup. For example, resource references may be inserted into the document head or at the end of the body. In addition to providing flexibility in where resources are inserted, a beneficial side effect of resource relocation is that duplicate resource references are automatically pruned out.

Note that in order to support resource relocation, JSF 2 introduces two other new components: <h:head> and <h:body> These components render the HTML head/body markup and also provide a target for relocatable resources.

Links

Tree Visiting

JSF 1.2 included the most useful addition of the UIComponent.invokeOnComponent() API. This provided the ability to invoke a callback on a single component instance in context. This functionality is particularly handy for any case where a single component (or subtree) needs to be targeted. (Think Ajax.)

While invokeOnComponent() is an excellent solution for the single component case, it is not particularly optimized for the multiple component case. If you need to target two components (eg. need to render two separate subtrees while processing an Ajax request), invokeOnComponent() will work, but requires two tree traversals in order to locate the two components. What happens if you need to render five separate subtrees? Or, even worse, what if you want to visit every component in context? Unfortunately invokeOnComponent() is not the answer.

JSF 2.0 solves the multi-component visiting case by introducing a sibling API to invokeOnComponent(): UIComponent.visitTree(). Both of these APIs traverse the component tree and invoke a callback on a subset of components. While invokeOnComponent() is designed to visit a single component, visitTree() may visit multiple components – and possibly all components – during its traversal. The set of components to visit is specified via a VisitContext that is passed into the visitTree() call.

While tree visiting is currently used under the covers by JSF implementations for features such as Ajax and state saving, the hope is that JSF frameworks/users will find other use cases where this new API proves helpful. If you currently have any case where you are calling invokeOnComponent() repeatedly (or are calling findComponent() when you should be calling invokeOnComponent()), be sure to check out the new tree visitor API!

Links

Conclusion

When I starting thinking about writing this article, I was hoping to provide a comprehensive overview of the entire JSF 2 feature set. As I got further into this undertaking, I realized that covering every single new feature/API in a single blog entry might be a bit, well… unwieldy. As such I decided to trim back my plans, but just slightly. There are a small number of minor API additions that I have not discussed here. Perhaps I’ll add a new section on these minor APIs at some point. For the moment, I am hoping that the information provided here is sufficiently complete to meet my original goal of providing a good introduction to the JSF 2 feature set.

If I have missed some feature/API that you think deserves discussion here, please leave a comment. Or if you know of other good sources of information, please leave a link. I am planning to update this blog from time to time with links to new blogs/articles as they become available, perhaps even to some that I write myself. :-)

Still Here

January 5, 2009 by andyschwartz

Just wanted to post a quick note to let you all know that this blog isn’t dead yet! For the folks who have posted comments/questions on library partitioning: thank you for your interest – and sorry that I have not been able to respond just yet. I will be following up soon.

To anyone who happens to stumble by here, thanks for dropping in and happy new year!

Back From AjaxWorld

October 28, 2008 by andyschwartz

In spite of the fact that both Roger and I arrived at AjaxWorld carrying our east coast colds, we managed to make it through our “JSF and Ajax” presentation. Couple of snapshots from the presentation:

Andy and Jeremy Geelan

Roger and Andy

Two other EG members presented on JSF-related topics. Ted Goddard (ICEsoft) presented on ICEfaces’s support for Ajax Push on the iPhone. Ted’s presentation included a fun live demo where iPhone-enabled audience members were able to get into an ICEfaces-based chat room and push messages to each other. Jeremy Grelle (SpringSource) presented on Spring’s Ajax support, including coverage of Spring Faces and an interesting demo of “progressive enhancement”.

One other notable JSF-related presentation: Wesley Hales (JBoss/Red Hat) provided a great introduction to the state of affairs in the portal/portlet world. Wesley discussed how both ICEfaces and RichFaces approach portlet integration, and also covered how emerging standards will make life easier for Ajax/portlet development.

Other JSF old-timers (and old friends) John Fallows and Jonas Jacobi also presented, though not on JSF. John and Jonas focused on HTML 5, in particular on the WebSocket API and how Kaazing’s offerings make it possible to take advantage of HTML 5 features today.

With several EG members actually in the same place at the same time (an unusual occurrence), we took advantage of the opportunity to hold an informal face-to-face meeting. Roger, Ted, Jeremy, John, special guest attendee Blake Sullivan (Oracle) and I met to discuss declarative solutions for Ajax, an area that we are trying to shape up for the JSF 2.0 release.

Off To AjaxWorld

October 19, 2008 by andyschwartz

I am heading out to California this week to attend AjaxWorld West in San Jose.  In addition to having the opportunity to check out all sorts of interesting sessions, I will also be presenting with Roger Kitain from Sun MicroSystems.  Our presentation is JSF and Ajax: Past, Present and Future.  As you might imagine, we’ll be taking a look at how Ajax-based solutions have evolved in the JSF world and what we expect to come next in JSF 2.0.

Of course, any trip to the Bay Area wouldn’t be complete without my usual visit to Oracle HQ.  Once AjaxWorld wraps up I’ll be spending the remainder of the week at HQ, catching up with friends and teammates both old and new.

I am looking forward to a great week in California!

JavaScript Library Partitioning Runtime

October 18, 2008 by andyschwartz

In Hello, Library Partitioning! we took our first peek at the new ADF Faces JavaScript Library Partitioning feature.  In order to support this functionality, ADF Faces introduces two new configuration files.  In this entry, we’ll see how the metadata defined by these configuration files is used to optimize the JavaScript footprint of ADF Faces.

ADF Faces loads the library partitioning configuration files at application initialization time, starting with the “feature” configuration file.  Since the goal is to allow custom component authors to leverage the library partitioning system for their own JavaScript code, we use a tried and true technique for locating all available feature configuration files: ClassLoader.getResources().  Given a path to a resource file, ClassLoader.getResources() scans all jars on the class path and returns references to any matching files that are found.  This mechanism should be familiar to JSF users: it is the same approach used to locate faces-config.xml files.

In order to locate feature configuration files, ADF Faces searches for all “adf-js-features.xml” files in the “META-INF” directory.  This allows custom component authors that want to participate in JavaScript library partitioning to simply drop a “META-INF/adf-js-features.xml” file into their jar.  No explicit registration is necessary.  Any feature configuration files found are loaded into memory and merged into a common data structure.  Of course, ADF Faces provides its own feature configuration file so that its own features are always available.

In the case of the “partition” configuration, we only have one configuration file per application.  ADF Faces looks for this file, named “adf-js-partitions.xml”, in the “WEB-INF” directory of the web application.  If no such file is found, ADF Faces falls back to a default partition configuration that it provides.  The default partitioning is meant to provide reasonable behavior for most applications, though application developers are welcome to optimize as needed for their application.

Now that we’ve got all of this information available, how is it actually put to use?

During the render traversal, ADF Faces collects information about which JavaScript features are required by the page.  At the end of the traversal, the complete set of JavaScript features required by the (rendered) page contents is known.  Once we know the set of required JavaScript features, we use our partition configuration to map this to the set of required partitions.  And given the set of required partitions, we simply render HTML <script> references to these partitions, just before the end of the HTML document.

That’s it!  By using this technique, we end up pulling in just those “chunks” of JavaScript code that are needed by the page, thus reducing the total amount of code that needs to be downloaded/loaded.

Hello, JavaScript Library Partitioning!

October 14, 2008 by andyschwartz

In Almost Getting To The Point, we took a look at requirements for a solution to the JavaScript size vs # of round trips dilemma.  In this entry, we’ll see how those requirements translate into an actual solution as implemented by the ADF Faces “JavaScript library partitioning” feature.  In this solution, we have three types of JavaScript artifacts:

1. The JavaScript “class”

This is a coherent set of code contained in a single file, which typically implements the equivalent of a class.  For example, the “oracle/adf/view/js/component/rich/layout/AdfRichPanelStretchLayout.js” file contains the JavaScript code for the af:panelStretchLayout’s JavaScript component class.

In our solution the class is the smallest unit of content that can be aggregated.

2. The JavaScript “feature”

Since component authors do not want application developers to have hard dependencies on JavaScript file names or paths, we introduce the concept of the JavaScript “feature”.  The JavaScript feature is a collection of JavaScript files that are associated with a logical identifier that describes the feature.

For example, the af:panelStretchLayout component implementation is contained within two JavaScript files:

* oracle/adf/view/js/component/rich/layout/AdfRichPanelStretchLayout.js
* oracle/adfinternal/view/js/laf/dhtml/rich/AdfDhtmlPanelStretchLayoutPeer.js

These two files are grouped into the “AdfRichPanelStretchLayout” feature.  This allows application developers to refer to the af:panelStretchLayout code by the name “AdfRichPanelStretchLayout”, without having to worry about the number, name or locations of files that are used to implement this feature.

3. The JavaScript “partition”

JavaScript “features” are usually small units of JavaScript code – typically a few related files that combine to implement a single area of functionality (such as a user interface component).  JavaScript “partitions” group JavaScript features into larger collections with the goal of influencing download size/number of round trips

For example, it’s not uncommon for applications that use the af:panelStretchLayout component to also use the af:panelSplitter component.  These two components often go hand in hand.  Assuming we have both an “AdfRichPanelStretchLayout” feature and an “AdfRichPanelSplitter” feature, these two features would be a good candidate to be placed in the same JavaScript library partition.

Looking at the division of responsibilities, we have:

  • Component authors place their JavaScript code in files.
  • Component authors are responsible for grouping these files into logical “features”.
  • Application developers are responsible for further grouping these features into larger “partitions”.

In order to support these responsibilities, the ADF Faces JavaScript library partition solution introduces two new configuration files: the JavaScript feature configuration file and the JavaScript partition configuration file.  Let’s take a look at each of these.

The feature configuration file is an XML-based file that groups JavaScript files into features.  A (slightly simplified) sample feature definition for our AdfRichPanelStretchLayout feature:

<?xml version="1.0" encoding="utf-8"?>

<features xmlns="http://xmlns.oracle.com/adf/faces/feature">

  <!-- Define the contents of the AdfRichPanelStretchLayout feature -->
  <feature>
    <feature-name>AdfRichPanelStretchLayout</feature-name>
    <!-- This feature contains two classes - the component and the peer -->
    <feature-class>oracle/adf/view/js/component/rich/layout/AdfRichPanelStretchLayout.js</feature-name>
    <feature-class>oracle/adfinternal/view/js/laf/dhtml/rich/AdfDhtmlPanelStretchLayoutPeer.js</feature-name>
  </feature>

  <!-- Other feature definitions go here -->

</features>

Pretty simple really.
The partition configuration is similar, but groups features into partitions:

<?xml version="1.0" encoding="utf-8"?>
<partitions xmlns="http://xmlns.oracle.com/adf/faces/partition">

  <!-- Define the contents of the "stretch" partition -->
<partition>
<partition-name>stretch</partition-name>
    <feature>AdfRichPanelStretchLayout</feature>
    <feature>AdfRichPanelSplitter</feature>
  </partition>

  <!-- Other partition definitions go here -->
</partitions>

ADF Faces provides a feature configuration file for its own set of components/framework features and also provides a default partition configuration so that application developers are not required to define a partitioning themselves.

So, now that we’ve got all of this wonderful information about our JavaScript code base, what do we do with it?  That’s the topic of the next entry of course. :-)

Almost Getting To The Point

October 14, 2008 by andyschwartz

In Does Size Matter? we concluded that, while aggregating JavaScript code is generally a good thing, at a certain point we might need to back off and consider breaking up our code.  At the moment ADF Faces is at one end of the size vs. round trip spectrum.  The number of round trips is optimized by combining all JavaScript code into a single library (single round-trip).  At the other end of the spectrum, we could optimize total downloaded code size by breaking out each JavaScript “class” into its own library (many round trips).  Clearly some happy medium – a balance between size and round trips – is needed.

Perhaps the ideal solution would be a GWT-like approach.  We could consider analyzing JavaScript code usage to determine the bare minimum code requirements down to the method level.  While this would certainly lead to a highly optimized solution, it does have one drawback.  This is hard!  In a traditional JEE/JSP/JSF application, JavaScript code lives in a number of places, some of which are not exactly easy to identify.  JavaScript code may be bundled up into jar files or war files (not too hard to identify), or may live inside of JSPs or other templates (slightly harder to identify), or may be generated programmatically via Java code (very hard to identify).  That’s not to say that this approach is impossible or not worthwhile; this is clearly an idea that is worth pursuing.  However, given the scope of such a project, a solution along these lines was simply not in the cards for our current release.

So, if we aren’t able to perform code analysis to produce a minimal application-specific JavaScript library, what are our other options?  Let’s start by considering some requirements that we would like our solution to meet.

1.  Aggregation.  We want a solution that allows us to group JavaScript files into larger “chunks”.  At the moment, the ADF Faces JavaScript code is delivered in one big chunk.  We want to break this up into smaller chunks that can be delivered to the browser independently.

2.  Specificity.  Any given chunk should only be downloaded/loaded on pages that need the chunk.  So, for example, if the JavaScript code for the af:richTextEditor  component lives in its own chunk, this code should only be pulled in on pages which use the af:richTextEditor component.

3. Cacheability.  Chunks should be cacheable.  That is, the contents of the chunks should not vary from page to page.  If a chunk is required by both page A and page B, it should not be necessary to download the chunk a second time when navigating from page A to page B.

4. Tunability.  The number and content of the chunks should be configurable at the application level.  Different applications have different JavaScript usage patterns and should be able to optimize the chunks (ie. optimize the size vs. round-trip trade-off) accordingly.

5. Abstraction.  When defining the contents of a chunk, the application developer should not be required to reference the physical JavaScript file names or locations.  For example, when defining a chunk that includes the JavaScript code for the af:richTextEditor component, the application developer should not need to know that the af:richTextEditor implementation relies on code located in the “oracle/adfinternal/view/js/laf/dhtml/rich/AdfDhtmlRichTextEditorPeer.js” file.  File names and locations are implementation details that are easily changed/re-factored.  Instead of relying on file names, the application developer should reference the code via some logical identifier that is guaranteed not to change.  This protects both the component author (freedom to change/re-factor) and the application developer (freedom from breaking when pesky component authors make changes).

6. Defaults.  Some default set of chunks should be provided so that application developers are not forced to go to the trouble of defining their own chunk layout.

7. Ordering.  The solution should ensure that chunks are loaded in an order that honors code dependencies between chunks.  If chunk A depends on code in chunk B, chunk A should be loaded before chunk B.

8. Extensibility.  Custom components should be able to participate in the solution.  That is, it should be possible to chunk custom component code in the same manner as ADF Faces framework/component code.

Assuming we’ve hit the key requirements (and hopefully we did, as I am running out of serious-sounding words to describe each requirement), these requirements translate into a fairly straightforward solution.  Which of course is the topic of my next entry. :-)

Does Size Matter?

October 13, 2008 by andyschwartz

When it comes to JavaScript code size, of course it does.  Too much code leaves users waiting impatiently for JavaScript libraries to download.  Or worse, not waiting.  Even in cases where users have a warm browser cache, the overhead of loading large libraries into the JavaScript engine can slow down page view/transition times, making your web application feel less responsive.

Size is an issue for any web application framework that includes a client-side component.  ADF Faces is no exception.  In this blog entry we’ll take a look at how ADF Faces attempts to deal with its (growing) JavaScript code base.

Our initial approach to managing our JavaScript code consisted of three steps:

1. Aggregate

In ADF Faces each JavaScript “class” lives in its own file.  This simplifies the development process, making it easier to manage a large code base.  However, with over 400 JavaScript classes/files, serving each of these up in separate requests is not an option.

Fortunately, the Apache Trinidad ResourceLoader architecture comes to the rescue.  In particular, Trinidad’s AggregatingResourceLoader makes it easy to merge multiple files into a single resource at runtime.  ADF Faces uses this to merge *all* of its JavaScript code into a single library.

2. Minimize

When working with a large JavaScript code base, code maintainability is an important consideration.  Developers should be able to freely add comments/whitespace and to use descriptive variable/method names.  Of course, such verbosity is not appreciated when it comes to download size, and comments, white spaces and descriptive names are wasted on the JavaScript engine.

Again, Apache Trinidad provides a solution here.  Trinidad includes a JavaScript obfuscator that handily strips comments, whitespaces and obfuscates/minimizes local variable names.  ADF Faces integrates the Trinidad JavaScript obfuscator into its own build process.  As a result, writing comments, or whitespace, or using descriptive variable names in the ADF Faces JavaScript code base is not a crime but instead is encouraged.

3. Compress

Minimization is a good start, but not a good place to stop.  When it comes to optimizing download sizes, compression is king.  The current generation of web browsers all support gzip-compressed JavaScript payloads.  We typically use Oracle Web Cache to help with this.

This strategy seemed reasonable when it was first put it in place two and half years ago.  At that point, our minimized JavaScript code base maxed out at around 540K, which compressed down to roughly 120K.  Not exactly small, but manageable.

Of course, ADF Faces development has not stood still over the last two and a half years.  Our component set has doubled.  A range of new architectural features has been added.  As you might imagine, new components and features translates into more JavaScript code.

How much more?  As of the recent JDeveloper 11g production release, our total minimized code size is now in the vicinity 1.4M.  After compression this comes back down to 320K.

Okay, definitely not small.

What lessons can we take away here?

Well, one lesson is that compression is our friend.  JavaScript code compresses nicely – compressing can cut down the download size (and thus download time) by ~75%.  This is good.

On the flip side, a tough lesson is that client-based components/features come at a price: increased JavaScript code size.  At a certain point, the simple aggregate/minimize/compress strategy of JavaScript code management seems no longer up to the task.

What to do?  In the next entry, we’ll consider alternate strategies for managing a large JavaScript code base.