Archive for February, 2015

What’s new in JSF 2.3?

6 February 2015

The process of developing JSF 2.3 started late september 2014, which is approximately 1.5 half year after JSF 2.2 was finalized. It currently has an anticipated release date of Q3 2016, which is aligned with the anticipated release date of Java EE 8.

So what will be in JSF 2.3?

The official JSR gives some hints, but is a little vague in what will actually be done. This time around, there is little big upfront planning and because of resources the scope of new features is kept limited.

There have been a few important changes in the organization of the EG as well. While Ed Burns is still the spec lead, there is now a co-spec lead: Manfred Riem. As can be seen from the commit log, Manfred is currently most involved with working in the Mojarra source code. At a personal level, a big change is that both my co-worker Bauke (BalusC) as well as myself are now members of the JSF EG and are actively contributing to JSF.

So instead of merely monitoring the trunk of the reference implementation to see what’s new as I did for JSF 2.2, I’ll now be reporting from the inside 😉

Download

Latest 2.3 snapshot: implementation jar, source jar

Latest JSF 2.3 blog posts

The following in an excerpt of a list of blog posts from around the net about JSF 2.3 that I found interesting. The full list can be found on my ZEEF page.

New features

CDI


Injection and EL resolving of JSF artifacts (spec issue 1316) (partially)

JSF has traditionally used static entry methods and chaining to let the user obtain the various artifacts that it provides, such as the FacesContext, session map, external context, etc. The following gives a few examples of this:

FacesContext facesContext = FacesContext.getCurrentInstance()
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
Map<String, Object> cookieMap = FacesContext.getCurrentInstance().getExternalContext().getRequestCookieMap();
Map<String, Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap();
// etc

Especially the artefacts that have to be obtained by deep chaining can be problematic. Not only makes this the code verbose and hard to read, it can also be unclear to users that the view map has to be obtained via the view root but the cookie map via the external context as shown above.

Furthermore, the pattern makes it hard to override what is returned by the runtime. In JSF it IS possible to influence this by providing/setting a custom FacesContext, but especially for the deeper chained artefacts multiple levels or wrapping are then required, which is not always trivial to implement. The problem there is clearly that the abstraction is at the wrong level; providing an alternative view map requires a custom faces context, which provides a wrapped view root, which then finally provides the view map we wanted to provide.

A more modern approach in Java EE is to inject artefacts in order to obtain them (essentially flattening the lookup) and to provide alternative producers for those when the need to override them arises.

JSF 2.3 will therefore provide default producers for the most important artefacts, which at the moment being:

  • ViewRoot
  • ViewMap (@ViewMap)
  • RequestCookieMap (@RequestCookieMap)
  • SessionMap (@SessionMap)
  • ApplicationMap (@ApplicationMap)
  • FacesContext
  • ExternalContext

The general types, in this case the maps, need an extra qualifier to avoid clashing with other producers. The JSF specific types however don’t need such qualifier since JSF is the sole owner of these types.

Obtaining the JSF artefacts is therefore as easy as can be; one only needs to know the type of the artefact one wants. For example:

@Inject
private ExternalContext context;

For the ones that do need a qualifier, this qualifier has to be looked-up of course, but that’s essentially a flat lookup. For example:

@Inject
@ApplicationMap
private Map<String, Object> applicationMap;

Furthermore, somewhat as a side-effect of Injection in more JSF artifacts, user created instances of the following artefacts are also injectable:

  • Converter
  • Validator
  • Behavior

This list is somewhat different, as we’re not talking about say -the- Converter instance within the current scope, but about a specific named custom converter in the user’s application. E.g.

@Inject
@FacesConverter(value = "myConverter", managed = true)
private Converter myConverter;

Note that this particular injection pattern is possible, but not entirely how things are normally done in CDI.

Commits for this feature have been done between 13/okt/14 and 29/jan/15.


Injection in more JSF artifacts (spec issue 1316) (partially)

In JSF 2.1 very few JSF artifacts were injection targets. In JSF 2.2 injection was made possible in a huge amount of additional artefacts but the very ones where injection actually matters most, converters and validators, were mysteriously left in the cold.

In JSF 2.3 this has now finally been taken care of as the following artefacts have been added to the list of injection targets:

  • javax.faces.convert.Converter
  • javax.faces.validator.Validator
  • javax.faces.component.behavior.Behavior

However, in contrast to the artefacts already on this list these new 3 are not automatically injection targets. They will only become so when a new attribute called “managed” on the corresponding annotations @FacesConverter, @FacesValidator and @Behavior is set to true. Furthermore all these 3 annotations have been upgraded to being CDI qualifiers by adding the @Qualified annotation to their definition.

The existing attributes of @FacesConverter, @FacesValidator and @Behavior have not been modified, meaning they are all *binding*, as is the new attribute “managed”.

What happens behind the scenes now is that when JSF needs a converter it simply asks the CDI bean manager for a bean that implements Converter with a qualifier @FacesValidator that has the “managed” attribute set to true and the value (coverterId) or forClass attribute set to the right value (which is why it’s important that these attributes are all binding).

It then wraps the bean returned by CDI in a delegating converter instance. This wrapper then delegates to the bean returned by CDI. This wrapper can be state-saved, but since the CDI bean is stored in a transient field it won’t save&restore that. Instead, it will only save&restore the converterId or forClass. The restored wrapper will then use the JSF Application instance to ask for a converter with said converterId or forClass (which will go to CDI again, and will do the wrapping again, so we have a double wrapped converter at this point).

In effect the mechanism is essentially quite like the age old workaround of using an EL expression pointing to a managed bean for a converter or validator.

An example of a JSF 2.3 converter in which injection can take place:

@FacesConverter(value = "myConverter", managed = true)
public class MyConverter implements Converter {
 
    @Inject
    private MyService service;
 
    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        // Convert string to Object here
    }
 
    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        // Convert Object to String here
    }
}

Note that this new style converter must have a constructor as defined by CDI (a no-args one here) and the alternative constructor is not supported here.

Commits for this feature have been done between 14/Jan/15 and 15/jan/15.

Lifecycle


System event published after view rendered (spec issue 1135)

JSF 2 introduced the concept of system events, which are events that can be fired by arbitrary objects at arbitrary points during the request processing lifecycle.

In the current version JSF 2.2 there are some 20 events defined, e.g. PostAddToViewEvent, PostConstructViewMapEvent, PreValidateEvent, and specifically PreRenderViewEvent.

However, while there’s a PreRenderViewEvent that’s published right before a view is rendered, there’s no event published right after. Such event can be useful for a variety of things, such as per view clean-ups, post rendering view processing, state handling, etc.

For these reasons and simply to be more consistent JSF 2.3 will add a new event called the PostRenderViewEvent, which as its name implies is published immediately after a view is rendered.

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:f="http://xmlns.jcp.org/jsf/core">
 
    <h:body>
        <f:event type="postRenderView" listener="#{myBean.doPostProcessing}" />
 
     	<!-- Rest of view here -->
    </h:body>
</html>

Commits for this feature have been done on 31/jan/15.

Java API


Support for the Iterable interface in UIData and UIRepeat (spec issue 1103)

From the beginning of JSF, the UIData component (known from e.g. <h:dataTable>) and UIRepeat (known from e.g. <ui:repeat>) only realistically supported the List, native array and JSF specific DataModel as input for its value binding. This meant other collection types had to be expressed as one of these types.

In JSF 2.2 UIData was extended to support Collection as well, but UIRepeat was mysteriously left out (which is one reason why UIRepeat should really share common functionality with UIData; it happens much more often that both should be updated but only one of them is)

The thing is that while Collection support is nice, it’s actually just as easy to support Iterable. It’s perhaps a small oversight that this was not supported right from the beginning, but in JSF 2.3 this will finally be addressed.

Just as with the Collection support in 2.2, Iterable will be added to the bottom of the list of types being checked, so for Iterables that are also a List or Collection (in case of UIData), the existing code will take precedence.

The following are now the supported types for UIData:

  • null (becomes empty list)
  • javax.faces.model.DataModel
  • java.util.List
  • java.lang.Object[]
  • java.sql.ResultSet
  • javax.servlet.jsp.jstl.sql.Result
  • java.util.Collection
  • java.lang.Iterable new!
  • java.lang.Object (becomes ScalarDataModel)

And the following are the supported types for UIRepeat:

  • null (becomes empty list)
  • javax.faces.model.DataModel
  • java.util.List
  • java.lang.Object[]
  • java.sql.ResultSet
  • java.lang.Iterable new!
  • java.lang.Object (becomes ScalarDataModel)

Note that both Result and Collection are missing for UIRepeat. The latter will be handled by Iterable, since it’s the base class of Collection. Result is actually missing, likely because its JSP specific and UIRepeat was designed specifically for Facelets).

Commits for this feature have been done on 2/mar/15 and the associated issue has been marked as resolved.


Support for the Map interface in UIData and UIRepeat (spec issue 1364)

Besides support for the Iterable interface in UIData and UIRepeat, JSF 2.3 will also add support for maps. The way this is done is closely aligned with how JSTL has supported maps for many years:

Existing JSTL based looping through a map

<c:forEach var="entry" items="${myMap}">
  Key: <c:out value="${entry.key}"/>
  Value: <c:out value="${entry.value}"/>
</c:forEach>

New JSF 2.3 based looping through a map using ui:repeat

<ui:repeat var="entry" value="#{myMap}">
    Key: #{entry.key}
    Value: #{entry.value}
</ui:repeat>

New JSF 2.3 based looping through a map using h:dataTable

<h:dataTable var="entry" value="#{myMap}">
    <h:column>#{entry.key}</h:column>
    <h:column>#{entry.value}</h:column>
</h:dataTable>

Including the Iterable support from the previous feature and the Map support discussed here, the following are now the supported types for UIData:

  • null (becomes empty list)
  • javax.faces.model.DataModel
  • java.util.List
  • java.lang.Object[]
  • java.sql.ResultSet
  • javax.servlet.jsp.jstl.sql.Result
  • java.util.Collection
  • java.lang.Iterable new!
  • java.util.Map new!
  • java.lang.Object (becomes ScalarDataModel)

And the following are the supported types for UIRepeat:

  • null (becomes empty list)
  • javax.faces.model.DataModel
  • java.util.List
  • java.lang.Object[]
  • java.sql.ResultSet
  • java.lang.Iterable new!
  • java.util.Map new!
  • java.lang.Object (becomes ScalarDataModel)

Commits for this feature have been done on 18/mar/15.

Configuration


Facelets default to non-hot reload in production (spec issue 936)

JSF has the ability to cache Facelets. Caching here means that the result of the XML parsing and compilation step is kept in memory, e.g. Facelets will not read the XML from disk at every request and will not reparse that XML either. (it will however still do the composition of includes and templates at every request)

While the default is not specified, the RI (Mojarra) uses a default of 2 seconds before it looks on disk again if the source file has changed or not. There is a setting to control this default, namely the javax.faces.FACELETS_REFRESH_PERIOD context parameter in web.xml. For example, the following sets a timeout of 10 seconds:

<context-param>
    <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
    <param-value>10</param-value> <!-- Cache for 10 seconds -->
</context-param>

There are two special values; -1 means no refresh (cache indefinitely), while 0 means no caching at all (always hot reload).

For production usage there really is only 1 sensible value, and that’s -1, as the Facelets source files will of course not change during production.

JSF 2.0 introduced a setting to indicate the stage its in, which includes the Production stage.

JSF 2.3 now finally adds one and one together and defines that when the project stage is Production (which incidentally is the default stage) the Facelets refresh period is -1 (no refresh).

Commits for this feature have been done on 25/feb/15.


That’s it for now! I’ll periodically update this page to cover the latest JSF 2.3 developments. In the short term this may be a dedicated folder to store views and a generic parameter adding to the Converter and Validator interfaces, but this is all preliminary.

Arjan Tijms

css.php best counter