What's new in JSF 2.3?

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 h2 2017, 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 JSF 2.3 snapshots
Latest JSF 2.3 milestones

Latest JSF 2.3 blog posts

The following is 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:

Artefact EL name Qualifier Type
Application #{application} - java.lang.Object (javax.servlet.ServletContext)
ApplicationMap #{applicationScope} @ApplicationMap java.util.Map<String, Object>
CompositeComponent #{cc} (Not injectable) javax.faces.component.UIComponent
Component #{component} (Not injectable) javax.faces.component.UIComponent
RequestCookieMap #{cookie} @RequestCookieMap java.util.Map<String, Object>
FacesContext #{facesContext} - javax.faces.context.FacesContext
Flash #{flash} - javax.faces.context.Flash
FlowMap #{flowScope} @FlowMap java.util.Map<Object, Object>
HeaderMap #{header} @HeaderMap java.util.Map<String, String>
HeaderValuesMap #{headerValues} @HeaderValuesMap java.util.Map<String, String[]>
InitParameterMap #{initParam} @InitParameterMap java.util.Map<String, String>
RequestParameterMap #{param} @RequestParameterMap java.util.Map<String, String>
RequestParameterValuesMap #{paramValues} @RequestParameterValuesMap java.util.Map<String, String[]>
Request #{request} (Not injectable) java.lang.Object (javax.servlet.http.HttpServletRequest)
RequestMap #{requestScope} @RequestMap java.util.Map<String, Object>
ResourceHandler #{"resource"} - javax.faces.application.ResourceHandler
Session #{session} (Not injectable) java.lang.Object (javax.servlet.http.HttpSession)
SessionMap #{sessionScope} @SessionMap java.util.Map<String, Object>
View #{view} - javax.faces.component.UIViewRoot
ViewMap #{viewScope} @ViewMap java.util.Map<String, Object>
ExternalContext #{externalContext} (new) - javax.faces.context.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.

As far as the implementation side is concerned, there's a CDI Bean<T> instance (aka "default bean") provided for every artefact. Since the term "bean" already has a meaning in JSF and CDI is not profoundly clear about this term either, the RI implementation code calls them "dynamic producer", or just "producer". Maybe "factory" would be better, but that term has a bit of a history itself and we wanted to avoid using that one.

The following shows an example of a Bean<T>/dynamic producer for the HeaderValues artefact:

public class HeaderValuesMapProducer extends CdiProducer<Map<String, String[]>> {
    
    public HeaderValuesMapProducer() {
        super.name("headerValues")
             .scope(RequestScoped.class)
             .qualifiers(new HeaderValuesMapAnnotationLiteral())
             .types(
                 new ParameterizedTypeImpl(Map.class, new Type[]{String.class, String[].class}),
                 Map.class,
                 Object.class)
             .beanClass(Map.class)
             .create(e -> FacesContext.getCurrentInstance().getExternalContext().getRequestHeaderValuesMap());
    }
    
}

Commits for this feature have been done between 13/okt/14 and 21/sep/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.


Native managed beans annotations deprecated (spec issue 1417 )

With JSF 2.0 annotations were introduced for the JSF managed bean facility. These annotations were however controversial from the start. At approximately the same time as they were being designed, there was a parallel effort started to provide a universal managed bean specification.

Because of that, the package that the JSF managed beans annotations lived in contained the following disclaimer:

At the time of this writing, a forthcoming JCP effort is being planned to extract the specification for managed beans from JSF and place it into its own specification. To account for this effort and to avoid introducing classes into JSF 2.0 that would have to be deprecated when this effort is complete, implementations of JSF 2.0 are not required to implement the “Faces Managed Bean Annotation Specification for Containers Conforming to Servlet 2.5”. However, JSF implementations are strongly encouraged to implement this specification, as it provides significant improvements in ease of use.

Of course we all know the name of this effort now; CDI.

Although effectively deprecated from day one, the now called "native" managed beans annotations from JSF had one advantage over their CDI versions and that's that they could use the important view scope (which incidentally was also introduced in JSF 2.0). It would take until JSF 2.2 for an official CDI version of that scope.

With the CDI based view scope introduced in JSF 2.2, JSF's own native bean facility could have been deprecated, but for some reason it wasn't. Now in JSF 2.3 the package containing the annotations for this facility has finally been deprecated.

The importance of this is that developers will hopefully be less confused which annotation to use (most IDEs will warn about using a deprecated type), and that JSF can take the next step; propose the entire managed bean facility for pruning. Just as EJB entity beans had no use in EJB anymore with JPA available and thus were actually removed ("pruned"), there's simply no need for JSF anymore to be in the managed bean business. JSF is already a very large spec, so removing(*) a large and now unnecessary part of it may help bringing down its size to somewhat more manageable proportions.

(* technically the pruned part of the spec will remain in existence and vendors are free to optionally implement it. The RI will always keep implementing it. So pruned does not mean "totally gone".)

Commits for this feature have been done on 25/May/16.


CDI compatible @ManagedProperty (spec issue 1418 )

With JSF 2.3 deprecating the native managed beans annotations in favour of CDI, there was one useful feature left that didn't had a full CDI compatible replacement; @ManagedProperty.

JSF co-spec lead Manfred Riem provided a simple example for a String based CDI compatible version, of which JSF 2.3 will incorporate a variant that supports basically all data types. Just like the native version type checking is delayed till runtime.

Because of the delayed type checking it not rarely makes more sense to use regular CDI injection (with optionally qualifiers if needed), but for migrating existing code or for those situations where an EL expression really is more convenient the new @ManagedProperty from the javax.faces.annotation package can be used in CDI beans.

The following shows an example:

import javax.enterprise.context.RequestScoped;
import javax.faces.annotation.ManagedProperty;
import javax.inject.Inject;
import javax.inject.Named;

@Named
@RequestScoped
public class MyBean {

    @Inject @ManagedProperty("#{someBean.someProperty}")
    private Integer injectedInteger1;
}

Commits for this feature have been done between 22/May/16 and 7/jun/16.


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.


Networking / AJAX

WebSocket integration (spec issue 1396)

WebSocket support for JSF has been talked about for quite some time, and there are fairly advanced implementations available by now.

Still, just as with the AJAX support that was added in JSF 2.0 and was available in proprietary component libraries before that, WebSocket support was seen as fundamental enough to be put directly into the core spec.

Therefor JSF 2.3 will provide direct support for WebSockets via the new tag <f:websocket>.

An important detail of the JSF 2.3 implementation of WebSocket support is that it uses the WebSocket JSR and therefor integrates with the WebSocket support offered by the server on which JSF is running. Proprietary implementations are not rarely based on frameworks such as Atmosphere. Both approaches have their own cons and pros, and just as with AJAX support the user can typically choose what to use; the version offered by core JSF, or the one by a component library.

The tag supports a number of attributes, of which the primary required attribute is "channel". The value set here can be used to send notifications to, which will then be pushed to all instances of the socket with that channel name. The second required attribute is "onmessage". Here a client-side Javascript event handler can be set that is called whenever a push arrives from the server.

The following shows a minimal example of using the tag on a JSF view:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
>
    <h:head>
        Websocket Example
    </h:head>
    <h:body>
        <f:websocket channel="myChannel" onmessage="function(message){alert(message)}" />
    </h:body>
</html>

Receiving messages is one part of the process. The other part is of course to push out a message. This can be done via the new javax.faces.push.PushContext, which can be injected anywhere where CDI is available. The following shows an example:

@Named
@RequestScoped
public class SomeBean {

    @Inject @Push
    private PushContext myChannel;

    public void send(){
        myChannel.send("Hello, from the server by push!");
    }
}

The injected PushContext is associated with one specific named channel, which by default has the same name as the instance variable in which injection takes place ("myChannel" in the example above).

Integration between JSF and WebSocket revealed one spec related problem; the WebSocket spec now assumes that the application has statically defined a so-called EndPoint via java code. In the case of <f:websocket> such required EndPoint has to be created in a more dynamic way, during runtime, or at the very least allow a (CDI) extension to define one. Unfortunately neither is possible now, at least not officially (some implementations support it anyway).

For those implementations that do not support adding an EndPoint dynamically (at the moment only GlassFish/Tyrus), a fake one has to be defined by the application. This kind of end point server no other function than to activate the container's WebSocket implementation. At the moment this is only known to be needed for GlassFish. On Tomcat and JBoss (WildFly/Undertow) this is not needed.

The following is an example of this:

public class FakeEndpoint extends Endpoint {
    @Override
    public void onOpen(Session session, EndpointConfig config) {}
}

We will try to resolve this issue with the WebSocket EG, but due to the Java EE 8 hiatus it's unfortunately profoundly difficult to start a MR or revision for any spec that hasn't started one. As an alternative we may look into defining an SPI that each container that incorporates Mojarra has to implement, and in which WebSocket activation can be done in a proprietary way.

Due to unfinished work with the CDI integration, the following parameter now has to be set (to avoid clashes with a deprecated but still used switch that looks at the 2.3 version of a faces-config.xml file, if any).

<context-param>
 <param-name>javax.faces.ENABLE_CDI_RESOLVER_CHAIN</param-name>
 <param-value>true</param-value>
</context-param>
While the fake end point is used to initialise the container, the actual WebSocket end point needs to be started as well. This can't be done by default, since otherwise there will be an open socket even when WebSocket is never used. Fully dynamically creating the end point whenever an <f:websocket> is encountered is unfortunately even harder. Therefor another setting needs to be used:
<context-param>
 <param-name>javax.faces.ENABLE_WEBSOCKET_ENDPOINT</param-name>
 <param-value>true</param-value>
</context-param> 

Further reading:

Commits for this feature have been done on 10/dec/15 and 14/mar/2016


Ajax method invocation (spec issue 613)

One of many major new features in JSF 2.0 was core support for Ajax. This effectively standardised what legendary libraries such as A4J had been doing in the years prior to that version.

One particular feature that almost every Ajax library supported wasn't standardised though. That feature is the ability to call an arbitrary server side method in a bean via Ajax. JSF 2.3 will address this omission by introducing the new <h:commandScript> component. Though many JSF libraries have something similar to this, <h:commandScript> was most directly based on the <o:commandScript> component from OmniFaces.

Simply said, the component creates a javascript function with a given name that once invoked will invoke on its turns the also given server side method via Ajax. The following shows an example:

<h:form>
    <h:commandScript name="myJsClientFunction" action="#{myBean.myJavaServerMethod('bar')}" render=":output" />
</h:form>
<h:outputText id="output" value="#{myBean.output}" />

In the example above the client side javascript myJsClientFunction will effectively be connected to the server side Java myJavaServerMethod method.

Commits for this feature have been done on 27/may/16 and the associated issue has been marked as resolved.


Execute javascript from server at completion of AJAX response (spec issue 1412)

It's often quite convenient to be able to execute a piece of javascript coming from the server right after an AJAX response has been applied on the client. Various popular component libraries such as PrimeFaces and OmniFaces have their own utilities to let the developer do exactly this.

Since AJAX was introduced in JSF there technically has been some level of core support for this. Namely, the <partial-response> payload that JSF sends after an AJAX request has an <eval> section where javascript can be put for execution on the client. The response writer used for writing the partial response even had startEval and endEval methods for these, but mysteriously for about 7 years(!) those methods remained totally unused and were probably largely forgotten.

In JSF 2.3 those methods were rediscovered, and a new method was added to the PartialViewContect; List<String> getEvalScripts().

Using this new getEvalScripts() method, a JSF backing bean handling an AJAX request can easily add a piece of javascript to the AJAX response. The following shows an example:

Within a form on some view:

<h:commandButton value="submit" action="#{someBean.eval}">
    <f:ajax />
</h:commandButton>
Backing bean:
@Named
@RequestScoped
public class SomeBean {

    @Inject
    private FacesContext context;

    public void eval() {
        context.getPartialViewContext()
               .getEvalScripts()
               .add("alert('After response')");
    }
}

After pushing the button shown above, an alert with the text "After response" in it will be shown. Note that while in the example above the piece of javascript is the only thing in the payload of the response, one would normally combine this with updating data and rerendering one or more parts of the view.

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


Updating multiple forms via AJAX (spec issue 790)

Via the AJAX support that was introduced in JSF 2.0 it was made possible to selectively update one or more components and the children of those components. Since the beginning of JSF it has been possible for a view to use multiple (non-nested) forms, and this is in fact a quite common thing in JSF applications.

Curiously though, these 2 very common features didn't work at all together as was discovered soon after AJAX support was added to JSF in 2009. What happens is that in JSF each form needs a hidden input field for the view state. This field is normally added in a somewhat non-trivial way, which is e.g. the reason a caching component can't directly cache a form. Now the AJAX partial-response from JSF 2.0 didn't take this fact into account at all, and would just contain the markup of the updated form without the view state field (which incidentally is exactly what you would get when using a caching or buffering component on a form).

The partial-response did contain the updated view state value, but strangely enough the spec said that this should only be used to update the view state field of the submitting form. This may have been a mistake or an oversight at the time.

The result is that after an AJAX update that involves the update of multiple forms (directly or via their parent components), the view is left in a broke state. JSF forms without the view state field present simply don't work. Mojarra provided a limited implementation specific fix where you had to explicitly specify all forms to be updated (even if you were updating a single parent of all those forms), and some libraries like OmniFaces provided a limited fix as well.

Part of the problem why this is a difficult issue to fix is the fact that JSF can also be used in a Portlet environment. In such environment it's not possible to have a javascript just update all JSF forms that it finds, as these may belong to different Portlets (the markup rendered by different Portlets is all part of the same HTML document with very little to no browser enforced isolation between them).

Below is an example of this problem. First consider the following view:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:h="http://xmlns.jcp.org/jsf/html">
    <h:head/>
    <h:body>
        <h:panelGroup id="panel1" layout="block">
            <h:form id="form1">
                <h:commandButton id="button" value="submit form1 and render panel2">
                    <f:ajax execute=":form1" render=":panel2" />
                </h:commandButton>
            </h:form>
        </h:panelGroup>

        <h:panelGroup id="panel2" layout="block">
            <h:form id="form2">
                <h:commandButton id="button" value="submit form2 and render panel1">
                    <f:ajax execute=":form2" render=":panel1" />
                </h:commandButton>
            </h:form>
        </h:panelGroup>
    </h:body>
</html>

Using Mojarra 2.2.13 (on Payara 4.1.1.162) clicking the first button will result in the following partial response to be send:

<?xml version='1.0' encoding='UTF-8'?>
<partial-response id="j_id1">
    <changes>
        <update id="panel2">
            <![CDATA[
                <div id="panel2">
                    <form id="form2" name="form2" method="post" action="/test-javaee8-ajax/spec790.xhtml" enctype="application/x-www-form-urlencoded">
                        <input type="hidden" name="form2" value="form2" />
                        <input id="form2:button" type="submit" name="form2:button" value="submit form2 and render panel1" onclick="mojarra.ab(this,event,'action','form2','panel1');return false" />
                    </form>
                </div>
            ]]>
        </update>

        <update id="j_id1:javax.faces.ViewState:0">
            <![CDATA[8345405308944877647:7731292386533209235]]>
        </update>
    </changes>
</partial-response>
This will result in the HTML document be modified to effectively the HTML shown below:
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="j_idt3">
    <script type="text/javascript" src="/test-javaee8-ajax/javax.faces.resource/jsf.js.xhtml?ln=javax.faces"></script>
</head>

<body>
    <div id="panel1">
        <form id="form1" name="form1" method="post" action="/test-javaee8-ajax/spec790.xhtml" enctype="application/x-www-form-urlencoded">
            <input type="hidden" name="form1" value="form1">
            <input id="form1:button" type="submit" name="form1:button" value="submit form1 and render panel2" onclick="mojarra.ab(this,event,'action','form1','panel2');return false">
            <input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="6782127948134886858:-5613250933960587439" autocomplete="off">
        </form>
    </div>

    <div id="panel2">
        <form id="form2" name="form2" method="post" action="/test-javaee8-ajax/spec790.xhtml" enctype="application/x-www-form-urlencoded">
            <input type="hidden" name="form2" value="form2">
            <input id="form2:button" type="submit" name="form2:button" value="submit form2 and render panel1" onclick="mojarra.ab(this,event,'action','form2','panel1');return false">
        </form>
    </div>
</body>
</html>
As can be seen, the second form misses the input element with name "javax.faces.ViewState", which means when its submitted JSF won't process it.

This problem is solved in JSF 2.3 by introducing a "namespaced mode" and a "non namespaced mode", which is the default.

In namespaced mode, which is specifically intended for Portlets but can be used in other environments as well, the partial response is given an id that's taken to be the "naming container id". All predefined postback parameter names (such as "javax.faces.ViewState", "javax.faces.ClientWindow", "javax.faces.RenderKitId", etc) are prefixed with this and the naming separator (default ":"). e.g. javax.faces.ViewState" becomes "myname:javax.faces.ViewState". Namespaced mode is activated when the UIViewRoot instance implements the NamingContainer interface.

In non namespaced mode the partial response does not have an id and the "naming container id" is set to be the empty string (""). All predefined postback parameters have their normal name.

In both cases, the "jsf.js" script handles a partial response by updating all forms where the method is "post", the id attribute is present and that id attribute starts with the "naming container id". In case of non namespaced mode this will thus match every form with an id.

Using Mojarra 2.3-m07 (on Payara 4.1.1.162) and the non namespaced mode clicking the first button on the view shown above will now result in the following partial response to be send:

<?xml version='1.0' encoding='UTF-8'?>
<partial-response>
    <changes>
        <update id="panel2">
            <![CDATA[
                <div id="panel2">
                    <form id="form2" name="form2" method="post" action="/test-javaee8-ajax/spec790.xhtml" enctype="application/x-www-form-urlencoded">
                        <input type="hidden" name="form2" value="form2" />
                        <input id="form2:button" type="submit" name="form2:button" value="submit form2 and render panel1" onclick="mojarra.ab(this,event,'action','form2','panel1');return false" />
                    </form>
                </div>
            ]]>
        </update>

        <update id="j_id1:javax.faces.ViewState:0">
            <![CDATA[-8282461998981779774:413768236226206985]]>
        </update>
    </changes>
</partial-response>
After the above response has been received and processed by the "jsf.js" script, the HTML document will effectively be as shown below:
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="j_idt3">
    <script type="text/javascript" src="/test-javaee8-ajax/javax.faces.resource/jsf.js.xhtml?ln=javax.faces"></script>
</head>

<body>
    <div id="panel1">
        <form id="form1" name="form1" method="post" action="/test-javaee8-ajax/spec790.xhtml" enctype="application/x-www-form-urlencoded">
            <input type="hidden" name="form1" value="form1">
            <input id="form1:button" type="submit" name="form1:button" value="submit form1 and render panel2" onclick="mojarra.ab(this,event,'action','form1','panel2');return false">
            <input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="2250188649944914411:-7175801439454851104" autocomplete="off">
        </form>
    </div>

    <div id="panel2">
        <form id="form2" name="form2" method="post" action="/test-javaee8-ajax/spec790.xhtml" enctype="application/x-www-form-urlencoded">
            <input type="hidden" name="form2" value="form2">
            <input id="form2:button" type="submit" name="form2:button" value="submit form2 and render panel1" onclick="mojarra.ab(this,event,'action','form2','panel1');return false">
            <input type="hidden" name="javax.faces.ViewState" value="2250188649944914411:-7175801439454851104">
        </form>
    </div>
</body>
</html>
As can be seen, both forms have their view state input element now, although the second one did loose its id and autocomplete attributes.

In namespaced mode running a similar view as shown above and pressing the button again will yield the following response:

<?xml version='1.0' encoding='UTF-8'?>
    <partial-response id="j_id1">
        <changes>
            <update id="j_id1:panel2">
                <![CDATA[
                    <div id="j_id1:panel2">
                        <form id="j_id1:form2" name="j_id1:form2" method="post" action="/test-javaee8-namespacedView/spec790.xhtml" enctype="application/x-www-form-urlencoded">
                            <input type="hidden" name="j_id1:form2" value="j_id1:form2" />
                            <input id="j_id1:form2:button" type="submit" name="j_id1:form2:button" value="submit form2 and render panel1" onclick="mojarra.ab(this,event,'action','j_id1:form2','j_id1:panel1');return false" />
                        </form>
                    </div>
                ]]>
            </update>

            <update id="j_id1:javax.faces.ViewState:0">
                <![CDATA[-8822830692037537003:-3037874094673406621]]>
            </update>
    </changes>
</partial-response>
Note that the partial-response tag now has an id attribute that wasn't present in the non namespaced version, and note that the id attributes of the update tags are prefixed with exactly that value. The HTML document will look effectively like the one below afterwards:
<html xmlns="http://www.w3.org/1999/xhtml"><head id="j_id1:j_idt3">
    <script type="text/javascript" src="/test-javaee8-namespacedView/javax.faces.resource/jsf.js.xhtml?ln=javax.faces"></script>
</head>

<body>
    <div id="j_id1:panel1">
        <form id="j_id1:form1" name="j_id1:form1" method="post" action="/test-javaee8-namespacedView/spec790.xhtml" enctype="application/x-www-form-urlencoded">
            <input type="hidden" name="j_id1:form1" value="j_id1:form1">
            <input id="j_id1:form1:button" type="submit" name="j_id1:form1:button" value="submit form1 and render panel2" onclick="mojarra.ab(this,event,'action','j_id1:form1','j_id1:panel2');return false">
            <input type="hidden" name="j_id1:javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="6924255192267784760:-4075825978563358382" autocomplete="off">
        </form>
    </div>

    <div id="j_id1:panel2">
        <form id="j_id1:form2" name="j_id1:form2" method="post" action="/test-javaee8-namespacedView/spec790.xhtml" enctype="application/x-www-form-urlencoded">
            <input type="hidden" name="j_id1:form2" value="j_id1:form2">
            <input id="j_id1:form2:button" type="submit" name="j_id1:form2:button" value="submit form2 and render panel1" onclick="mojarra.ab(this,event,'action','j_id1:form2','j_id1:panel1');return false">
            <input type="hidden" name="j_id1:javax.faces.ViewState" value="6924255192267784760:-4075825978563358382">
        </form>
    </div>
</body>
</html>
As the UIViewRoot that was used in the above test is a NamingContainer, all rendered element ids are automatically prefixed as can be seen, as are the names of the input elements as shown in the HTML above.

By taking the namespaced ids into account, all forms can now be safely updated in a Portlets environment as well.

Commits for this feature have been done between 20/jun/16 and 21/jul/16.


Conversion / Validation

Class level bean validation (spec issue 1)

JSF has supported bean validation ever since JSF 2.0 was released. This support was however limited to validating individual properties bound to individual components. E.g. an input component bound to a password property of a backing bean.

Besides validating individual fields or properties, bean validation also has a concept of class level validation. This involves a special constraint validator that receives an instance of the class that has to be validated. This special validator can then do cross-field validations. For instance, check that two password fields are equal.

Class level validation does not play well with the JSF validation model though. In JSF the idea is that the model is not touched if validation fails. But to validate a class level constraint, we have to update the model with all values before proceeding. This problem was solved in OmniFaces by making a copy of the bean, storing the new values in that bean, and then validating the result.

This approach and some of the code have been standardized in JSF 2.3 by means of a new tag: <f:validateWholeBean>

Class level bean validation practically speaking most often applies to entities that have their own semantic constraints with associated validation code. Typically such entity is returned fully from a backing bean, but the properties of such entity are then bound to individual components. The OmniFaces example of class level bean validation demonstrates exactly this.

Another possibility is a more ad-hoc class level validation, for instance done by a backing bean. This can be used as a multi-field validator, where the multiple fields being validated are not necessarily part of a more structural and re-usable constraint. This usecase is in fact the major driver behind the very first JIRA issues for JSF; JAVASERVERFACES_SPEC_PUBLIC-1 which was filed in 2004!

Using class level bean validation for this usecase is slightly verbose and perhaps not a fully ideal match, but it does align well with the current strategy of delegating as much concerns as possible to existing functionality in Java EE instead of introducing native mechanisms that partially overlap with that existing functionality. We show an example of this below.

First of all, the new tag must be explicitly enabled in web.xml. If it's not enabled, the tag will do nothing. The following setting will take care of this:

<context-param>
    <param-name>javax.faces.validator.ENABLE_VALIDATE_WHOLE_BEAN</param-name>
    <param-value>true</param-value>
</context-param>

After this initial nuasance we can create a view with two input fields, and the mentioned <f:validateWholeBean> tag. There are a few things to be aware of here:

  1. At least one input component in the view must have a bean validation group set
  2. The <f:validateWholeBean> tag must appear AFTER all other input components
  3. The group for the input component(s) and the <f:validateWholeBean> tag must be the same
  4. The special default group (javax.validation.groups.Default) does not count, it's explicitly ignored.

The following gives an example:

<h:form>
    <h:inputText value="#{indexBean.foo}">
        <f:validateBean validationGroups="javax.validation.groups.Default,java.util.RandomAccess"/>
    </h:inputText>
    <h:inputText value="#{indexBean.bar}">
        <f:validateBean validationGroups="javax.validation.groups.Default,java.util.RandomAccess"/>
    </h:inputText>

    <f:validateWholeBean value="#{indexBean}" validationGroups="java.util.RandomAccess"/>

    <h:commandButton value="submit"/>
</h:form>

In order to keep the example as small as possible I re-used an existing "random" interface for the group marker. Note that the default group javax.validation.groups.Default is also added to make sure individual fields are still bean validated as well.

Next thing is the backing bean itself. In order to use class level bean validation the following has to be done:

  1. An annotation has to be defined that adheres to the bean validation spec for class level constraints
  2. A constraint validator implementation has to be provided, which takes care of the actual validation
  3. The backing bean has to be annotated with that annotation
  4. The annotation's groups attribute has to be set to the same group that was used in the view
The following gives an example of this:
@Named
@RequestScoped
@ValidIndexBean(groups = java.util.RandomAccess.class)
public class IndexBean implements ConstraintValidator<ValidIndexBean, IndexBean> {

    @Constraint(validatedBy = IndexBean.class)
    @Documented
    @Target(TYPE)
    @Retention(RUNTIME)
    public @interface ValidIndexBean {
        String message() default "Invalid Bean";
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};
    }

    @Override
    public void initialize(ValidIndexBean constraintAnnotation) {
        //
    }

    @Override
    public boolean isValid(IndexBean other, ConstraintValidatorContext context) {
        return other.getFoo().equals(other.getBar());
    }

    @NotNull
    private String foo;

    @NotNull
    private String bar;

    public String getFoo() {
        return foo;
    }

    public void setFoo(String foo) {
        this.foo = foo;
    }

    public String getBar() {
        return bar;
    }

    public void setBar(String bar) {
        this.bar = bar;
    }

}

As mentioned this is indeed slightly verbose for a one-off multiple fields validation. Specifically the verbosity of the annotation is hard to reduce in this case. A default annotation for cases like this would probably help a lot, but at the moment there's none (at least not that I know of). The unneeded initialize method could be solved if the bean validation spec used a default method in the interface for this. Unfortunately there's no bean validation spec update or even MR planned at the moment.

Note that the other instance that the isValid method receives is a "copy" of the same bean. However, currently it's not really a copy but a new instance. The JSF 2.3 implementation code principally has the same copiers available as the ones for the OmniFaces version, but because of what seems to be a bug only the so-called NewInstanceCopier actually seems to be used in practice. Unlike in OmniFaces, it's also not currently possible to explicitly select a copier strategy or provide a custom one.

Further reading:

Commits for this feature have been done between 18/sep/15 and 28/sep/15 and the associated issue has been marked as resolved.


JDK 8 time support in f:convertDateTime (spec issue 1370)

JSF 2.3 will have Java 8 as a minimum dependency. One of the big advantages of this is that it's actively able to support new features in Java 8. One of those features concern the new data and time classes in JDK 8, otherwise known as JSR 310.

JSF 2.3 will provide support for these using its existing <f:convertDateTime> converter. In JSF 2.2 and before the type attribute of this converter only supported the values "date", "time" and "both". For JSF 2.3 this has been expanded with various values as shown in the table below:

Type attribute Class involved Default when pattern not specified
both java.util.Date DateFormat.getDateTimeInstance(dateStyle, timeStyle)
date java.util.Date DateFormat.getDateTimeInstance(dateStyle)
time java.util.Date DateFormat.getDateTimeInstance(timeStyle)
localDate java.time.LocalDate DateTimeFormatter.ofLocalizedDate(dateStyle)
localTime java.time.LocalTime DateTimeFormatter.ofLocalizedTime(dateStyle)
localDateTime java.time.LocalDateTime DateTimeFormatter.ofLocalizedDateTime(dateStyle)
offsetTime java.time.OffsetTime DateTimeFormatter.ISO_OFFSET_TIME
offsetDateTime java.time.OffsetDateTime DateTimeFormatter.ISO_OFFSET_DATE_TIME
zonedDateTime java.time.ZonedDateTime DateTimeFormatter.ISO_ZONED_DATE_TIME

In addition the pattern attribute has changed as well. In JSF 2.2 when this pattern attribute was set, the other attributes were ignored and java.text.SimpleDateFormat was used exclusively. In JSF 2.3 if the type attribute is set to any of the new JDK 8/JSR 310 values then java.time.format.DateTimeFormatter will be used instead. In all cases the pattern attribute still overrides the timeStyle and dateStyle attributes.

Example of usage:

<h:inputText value="#{myBean.startTime}">
    <f:convertDateTime type="localDateTime" />
</h:inputText>

<h:outputText value="#{myBean.endDate}">
    <f:convertDateTime type="localDate" pattern="dd.MM.uu" />
</h:outputText>

Further reading:

Commits for this feature have been done between 29/sep/15 and 2/oct/15 and the associated issue has been marked as resolved.


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.


Support for custom types in UIData and UIRepeat (spec issue 1078)

A third new feature in JSF 2.3 next to support for the Iterable interface in UIData and UIRepeat, and support for the Map interface in UIData and UIRepeat is support for custom types.

This has been requested for a long time, and JSF 2.3 will now (finally) provide this support. The way this is done is by creating a wrapper DataModel for a specific type, just as one may have done years ago when returning data from a backing bean, and then annotating it with the new @FacesDataModel annotation. A “forClass” attribute has to be specified on this annotation that designates the type this wrapper is able to handle.

The following gives an abbreviated example of this:

@FacesDataModel(forClass = MyCollection.class)
public class MyCollectionModel<E> extends DataModel<E> {
    
    @Override
    public E getRowData() {
        // access MyCollection here
    }

    @Override
    public void setWrappedData(Object myCollection) {
        // likely just store myCollection
    }

    // Other methods omitted for brevity
}

Note that there are two types involved here. The “forClass” attribute is the collection or container type that the DataModel wraps, while the generic parameter E concerns the data this collection contains. E.g. Suppose we have a MyCollection<User>, then “forClass” would correspond to MyCollection, and E would correspond to User. If set/getWrappedData was generic the “forClass” attribute may not have been needed, as generic parameters can be read from class definitions, but alas.

With a class definition as given above present, a backing bean can now return a MyCollection as in the following example:

@Named
public class MyBacking {
    public MyCollection<User> getUsers() {
        // return myCollection
    }
}
h:dataTable will be able to work with this directly, as shown in the example below:
<h:dataTable value="#{myBacking.users}" var="user">
    <h:column>#{user.name}</h:column>
</h:dataTable>

Further reading:

Commits for this feature have been done on 13/jul/15 and 15/jul/15.


Default getWrapped method for FacesWrapper implementations (spec issue 1429)

JSF has an interface called FacesWrapper that's "implemented" by the more concrete wrappers such as ApplicationWrapper, ResourceHandlerWrapper, etc.

In JSF 2.2 and before the getWrapped() method from the FacesWrapper wasn't actually implemented though, but this was left open for the actual sub class of these wrappers to do. E.g. they had to add something like shown below for say the ResourceWrapper:

public class MyResourceWrapper extends ResourceWrapper {

    private Resource wrapped;

    public MyResourceWrapper(Resource wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public Resource getWrapped() {
        return wrapped;
    }
}
Not only is this a small amount of extra verbosity that needs to be added to every wrapper, it also encourages using the wrapped instance variable directly. This can be quite problematic when the wrapper itself is wrapped, something which is not that uncommon in practice.

In JSF 2.3 all standard FacesWrappers will therefor provide a default implementation of the getWrapped() method, and will introduce a new constructor that takes the artefact being wrapped as an argument. The no-args constructor is being deprecated so the IDE or compiler can issue a warning when the new super constructor is not being used by subclasses. All existing code in the RI has been updated to use the getWrapped() method exclusively instead of the instance variable they may have been using before.

The following shows an example:

public class MyResourceWrapper extends ResourceWrapper {

    public MyResourceWrapper(Resource wrapped) {
        super(wrapped);
    }
}

Commits for this feature have been done on 27/jul/16.


Components

Iteration in UIRepeat without backing model (spec issue 1102)

In JSF there are 2 main constructs for basic iterating; the JSTL derived <c:forEach> tag and the <ui:repeat> component. The main difference is that the first is a build-time component while the latter is render-time component. This means <c:forEach> is not a component itself but is capable of adding components to the component tree while <ui:repeat> is a single component that iteratively generates its output (e.g HTML).

Another difference is that <c:forEach> has a begin and end attribute that can be used for an arbitrary iteration (like in java a regular for loop), while <ui:repeat> only iterates over a collection bound to the value attribute (which is more like an enhanced for loop or stream in java).

In JSF 2.2 and before you can thus not trivially do an arbitrary iteration without a backing model (collection) during render-time. JSF 2.3 will therefor introduce support for the <c:forEach> style iteration in <ui:repeat> using attributes of the same name. The following gives an example:

<ui:repeat begin="0" end="10" step="2" var="i">
    #{i}
</ui:repeat>
The above will render the sequence 0, 2, 4, 6, 8 and 10. Note that the begin and end attributes are both inclusive, and the step attribute is optional (it'll default to 1).

Commits for this feature have been done on 17/sep/14 and 30/may/16.


Automatic conversion in UISelectMany for Collection (spec issue 1422)

The UISelectMany component (which backs e.g. the <h:selectManyMenu> tag) has an eleborate algorithm for determining how multiple values that are posted back from an HTML <select> element are converted.

The difficulty here is that contrary to converting a single value, the component primarily sees an array or a Collection as the target to store converted values in. Arrays have a non-erased element type in Java, but due to the way generics are implemented it's not always possible and certainly not easy to retrieve the generic type (and thus element type) of a Collection. Because of this, the automatic by-type conversion that JSF normally does in absence of an explicit converter was not supported when the UISelectMany component was bound to a Collection.

As the OmniFaces' SelectItemsConverter has been showing for some time it's possible to do automatic conversion from String to an object in another way. Namely, by first mapping which String value was generated for each object instance, and then using the submitted string value(s) as key to map back.

E.g. suppose we have the collection of objects {Object1, Object2, Object3} generated by select items which are initially converted to String values {"a", "b", "c"}. Each of those then become the value of the value attribute in the HTML <option> element. Now when the user posts back {"a", "c"}, the conversion from object to String is performed again in the same way as during the initial rendering (in absence of an explicit converter this means it will use a by-type converter for each non-nul, non-string object instance), but now also mapped. So, we get a map of {"a" → Object1, "b" → Object2, "c" → Object3}. We can then use this map to automatically convert "a" to Object1, and "c" to Object3.

Do note that this does require that the same select items are available before and after the postback, but this is already a requirement in JSF (so that JSF can check that only values are posted back that were also initially rendered).

In JSF 2.3 exactly this technique will now be used to automatically convert values that are posted back for a UISelectMany component that's bound to a Collection.

(Since this type of automatic conversion is also convenient for other situations it's being considered to optionally apply this same technique elsewhere as well)

The following shows an example:

On a view within a form:

<h:selectManyCheckbox value="#{myBean.selectedItems}">
    <f:selectItems value="#{myBean.allItems}" />
</h:selectManyCheckbox>

Java backing bean:

@Model
public class MyBean {

    public static enum Item {
        A, B, C;
    }

    private List<Item> selectedItems;

    public List<Item> getAllItems() {
        return asList(Item.values());
    }

    public List<Item> getSelectedItems() {
        return selectedItems;
    }

    public void setSelectedItems(List<Item> selectedItems) {
        this.selectedItems = selectedItems;
    }
}
When the <h:selectManyCheckbox> shown above is posted back, selectedItems will contain a list with the enum instances of type Item corresponding to the selection that was made, without requiring the use of an explicit converter.

Commits for this feature have been done between 14/jun/16 and 17/jun/16.


Importing constants into EL namespace (spec issue 1424)

Using the EL language a view in JSF 2.2 and earlier can make references to @Named beans and to a number of implicit objects. Constants such as enums and final static fields are not that easy to reference; they can't be easily @Named and they typically live in a class of which there's no instance and even if there is doesn't have getters for them.

Yet, such constants are often needed on a view for diverse things such as the values of a color or country selector.

The typical solution in JSF is then to have some bean return those, either directly or by first converting them into a Map or List of some kind. Because this is a somewhat tedious and often recurring task, utility libraries such as OmniFaces and PrimeFaces extensions have provided several solutions for this. EL 3.0 basically supports this too, but actually using it on a view only works in JSP.

JSF 2.3 will introduce support for using constants on a Facelets view via the new <f:importConstants> tag which is backed by the UIImportConstants component.

Using this tag, all constants of a given fully qualified type will be inserted in the application scope as a Map using the simple name of that type, or optionally a user specified name.

For instance consider the class MyClass as given below:

package mypackage;

public class MyClass 
    public static final String CONSTANT1 = "constant1"
    public static final String CONSTANT2 = "constant2"
}
Importing this via the <f:importConstants> tag will cause a Map to be created with entries {"CONSTANT1" → "constant1", "CONSTANT2" → "constant2"}, which will be put in application scope using the name MyClass.

Because a Map is made available, there's a simple handle to all values, as well as to an individual constant.

The following shows an example of importing the class given above on a Facelet. Note that the tag has to be placed in the metadata section.

On a view:

<f:metadata>
    <f:importConstants type="mypackage.MyClass" />
</f:metadata>
After this import declaration, an individual constant can be accessed as follows:
#{MyClass.CONSTANT1}
The above will print "constant1" (without the quotes).

Iterating over all constants can be done as follows:

<ui:repeat var="entry" value="#{MyClass}">
    Key: #{entry.key}
    Value: #{entry.value}
</ui:repeat>
The above will print "Key: CONSTANT1 Value: constant1 Key: CONSTANT2 Value: constant2" (without the quotes).

Besides the class shown above, importing also works for interfaces and enums, and for the static inner class versions of those.

Commits for this feature have been done on 27/jun/16.


Official spec recognition for dynamic component tree manipulation (spec issue 1007)

JSF has supported the concept of dynamic component tree manipulation for a long time. Dynamic component tree manipulation here means that the component tree as it's created by the ViewDeclaratioLanguage is afterwards manipulated via (typically) application code.

Such tree manipulation is quite comparable to manipulating a browser's DOM via e.g. JavaScript.

While modifying the DOM is quite popular and generally well documented, the JSF version is by far not as well known and remains a somewhat obscure technique. Part of the reason this is the case is that few manuals or books mention it and the spec in fact doesn't mention it at all. It therefor took a considerable amount of time for the community to truly discover what the best place is in JSF from which to do this manipulation. A few libraries such as OmniFaces build on this somewhat implicit support that JSF provides with higher level utilities.

JSF 2.3 will officially recognise the existence of dynamic component tree manipulation and demand implementations to support it by means of the following text that was added to UIComponent:

Dynamically modifying the component tree can happen at any time, during and after restoring the view, but not during state saving and needs to function properly with respect to rendering and state saving

No API or implementation changes were made for this issue.

Commits for this feature have been done on 15/sep/15.


Resources

Standardised resource rendered tracking (spec issue 1404 )

JSF 2.0 introduced the resource handler API, which is a framework facility for serving up resources like JavaScript files, style sheets, images and other files in support of components that need them. Before the introduction of this API most component libraries bundled their own solution, like e.g. a Servlet or a Filter.

While JSF 2.0 standardised an API for this, it did not standardise in this API methods to track if a given resource reference (say a link to "jsf.js" from the "javax.faces" library) has already been rendered before and to set that it has been. The two JSF implementations (Mojarra and MyFaces) both do this tracking, but in JSF 2.2 and before they had their own private implementation for this. Being a private implementation means third party libraries like PrimeFaces, OmniFaces, etc could not take advantage of this tracking, and thus could not easily extend this part of the resource API.

In JSF 2.3 tracking whether resource references have been rendered will be standardised via the introduction of two new methods for the ResourceHandler:

  • boolean isResourceRendered(FacesContext context, String resourceName, String libraryName)
  • void markResourceRendered(FacesContext context, String resourceName, String libraryName)

The two methods are connected to each other in the fact that isResourceRendered for a given resource can only return true when markResourceRendered has been called for that same resource. In other words, implementations *must* call markResourceRendered and *must* check isResourceRendered.

External libraries can therefor safely wrap the ResourceHandler and provide their custom behaviour. Alternatively they can call markResourceRendered on the default ResourceHandler to prevent a given resource reference to be rendered by the framework, i.e. so they can render that resource reference themselves in a custom way (e.g. as part of combining multiple resources into a single one).

(This is a rather advanced feature that the average JSF application developer will not likely come in contact with.)

Commits for this feature have been done between 22/jul/16 and 26/jul/16.


Resource loading for components dynamically added via ajax (spec issue 1423 )

Since JSF 2.0 components can declare a resource dependency, which will cause the JSF runtime to make sure this resource is provided to the client when the view containing that component is loaded. This happens via the resource handler API by e.g. rendering a link in the head element.

Since the initial versions of JSF it has also been possible to do dynamic component tree manipulation, which basically means programmatically adding a component to the component tree by application code after that tree has been created by the JSF runtime.

Then there's the somewhat related concept of build-time tags in JSP and Facelets based views, which can cause different component trees to be created depending on certain variables. E.g. with the c:if tag a component can be completely eliminated from the tree, which is technically quite different from setting its rendered attribute to false (although the effect on the final rendered output can be quite identical). Includes with a dynamic (EL based) src attribute are also in this category.

Finally, JSF 2.0 added support for AJAX where a partial response is send back by the server that contains directives to only update certain parts of the client side HTML/DOM tree.

As it appeared the combination of these four factors mentioned above didn't play out well; a JSF component with a resource dependency that is dynamically added via either a build-time tag or via dynamic component tree manipulation during an AJAX request (other than for the @all target) failed to have its resource provided. In other words, a component depending on a javascript would not have that javascript added after an ajax request and so would most likely fail.

In JSF 2.3 this problem has been addressed by specifying a simple but effective algorithm that JSF implementations must adhere to. No new API methods were needed for this. That algorithm in simplified wording is:

  1. After restore state has been done for an AJAX request, all component resources are marked as already rendered (as an AJAX request comes from an existing rendered view that already has al its resources)
  2. In render response if the AJAX request is not for updating @all, all component resources that are NOT marked as already rendered (which thus must be the newly added components) are put in the update section of the partial-response that's send to the client with a new identifier javax.faces.Resource
  3. The "jsf.js" script has to append every element from the update section with this new javax.faces.Resource identifier to the head of the HTML document, if that element is not already there

Note that via the condition "if that element is not already there" in the above algorithm the "jsf.js" script now takes upon it a part of deduplicating resource references, a task that was previously done solely server side.

Commits for this feature have been done on 27/jul/16.


Type-safety

Generics for ExternalContext#getInitParamterMap (spec issue 1382)

Quite a number of types in JSF originate from before generics were available in Java. In subsequent releases Java 5 was targeted and existing types and methods were extended with generic parameters.

One of the methods that was missed before is ExternalContext#getInitParamterMap, which returns a raw Map in JSF 2.2 and earlier.

In JSF 2.3 this has been corrected and ExternalContext.html#getInitParameterMap now returns a Map<String, String>.

Commits for this feature have been done on 26/aug/15.


Generics for Converter and Validator interfaces (spec issue 1355)

Both the Converter and Validator interfaces in JSF take an Object as their input value. Implementations then typically demand that this Object is of a specific type and that otherwise an exception should be thrown.

This contract predates generics and instead of demanding such type constraint via JavaDoc one can far better express this via a generic parameter. In JSF 2.3 both interfaces have now been parameterized and implementations can concisely define the exact input type, and in case of the Converter interface additionally the exact return type.

This updated interfaces are shown below:

public interface Converter<T> {
  T getAsObject(FacesContext context, UIComponent component, String value);
  String getAsString(FacesContext context, UIComponent component, T value);
}
public interface Validator<T> {
  void validate(FacesContext context, UIComponent component, T value);
}

Note that the myriad of existing Converter and Validator implementations in JSF have not been parameterized and are raw types. The reason for this is backwards compatibility.

E.g. in some obscure but possible cases code could actually depend on passing an Object to some Converter implementation. Even when such Object could only be of say type Foo, then actually typing the constructor as accepting only Foo will not compile anymore. A variety of other even more obscure but theoretical possible incompatibilities were discovered as well. One could ask how generics can ever have been introduced in the JDK itself for existing types, but even there some compromises were made (like the infamous Map#get taking an Object as input instead of the generic parameter for the key).

New converters and validators can of course take advantage of the new generic parameters, but existing ones in JSF have been frozen in time and can never change.

Commits for this feature have been done between 30/jul/15 and 18/aug/15.


Constants for "jsf.js", "javax.faces" and postback parameters (spec issue 1428)

The JSF spec defines a javascript with the name "jsf.js" which is served by JSF implementations and contains functions such as the ajax handler. The spec also defines this script is in the "javax.faces" library.

Despite these two names being effectively spec mandated constants, there wasn't an actual constant in code defined for those, and both the RI implementation as well as various libraries were using the non type-safe strings everywhere.

Likewise, a couple of spec defined request parameter names for postback parameters did not have any constants for them defined either.

JSF 2.3 will therefor introduce several new constants as shown in the table below:

New constants in JSF 2.3
Fully qualified name Value Description
javax.faces.application.ResourceHandler.JSF_SCRIPT_RESOURCE_NAME "jsf.js" Resource name of JSF script resource
javax.faces.application.ResourceHandler.JSF_SCRIPT_LIBRARY_NAME "javax.faces" Library name of JSF script resource
javax.faces.component.behavior.ClientBehaviorContext.BEHAVIOR_SOURCE_PARAM_NAME "javax.faces.source" The request parameter name whose request parameter value identifies the source component of behavior event
javax.faces.component.behavior.ClientBehaviorContext.BEHAVIOR_EVENT_PARAM_NAME "javax.faces.behavior.event" The request parameter name whose request parameter value identifies the type of behavior event
javax.faces.context.PartialViewContext.PARTIAL_EVENT_PARAM_NAME "javax.faces.partial.event" The request parameter name whose request parameter value identifies the type of partial event

The RI implementation has been updated to use these new constants.

Commits for this feature have been done between 06/jul/16 and 25/jul/16.


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

10 comments:

  1. Great, it will avoid some boilerplate code.

    ReplyDelete
  2. Galera aqui só usa Mac OSX. Fico pensando onde o Swift se coloca nessa história.

    ReplyDelete
  3. But I feel like there are tons of things that should be implemented.
    On the top of my head:

    1. Ability to ajax render the head tag. (why the hell it's not there already ?)
    2. Ability to use outputScript for external js. Why ? Because of number 3.
    3. Ordering resources in the head tag is a fucking guess work. "Has target=head even though it's in the head already ?" Go first. Be external script and last mentioned ? You go first. It's just insane. At least something like primeface f:facet = first.
    4. Make all not recognized attributes passThrough, why the flying monkey not?
    5. build and render break the encapsulation by making the developer having to think about it. Just make it work in all case somehow.
    6. No inline javascript option ?

    I've made renderers for this but it's annoying to have to retrofit it when I will update to JSF 2.3

    ReplyDelete
  4. Hi Arjan. How will server push be incorporated into JSF 2.3? From the J1 presentation by Ed Burns he moted the idea that the PushBuilder would be used in the ExternalContext.encodeResourceURL() method to push resources to the client. I have not found any information other than his presentation that confirms that this. I wondered if you have a comment on this. Thanks in advance.

    ReplyDelete
    Replies
    1. Hi Alex,

      The JavaOne presentation from Ed Burns hinted at how HTTP2 push might be incorporated into JSF. This form of push is a kind of pre-emptive pushing; the server pushes things to the client for which it anticipates the client will need it.

      The is slightly different from the current support for push in JSF 2.3 (http://arjan-tijms.omnifaces.org/p/jsf-23.html#1396), which is based on WebSockets, and where such socket is explicitly set up by the client.

      Due to a series of issues mostly relating to resource allocation at Oracle, the HTTP2 pre-emptive pushing has not been researched yet. Because of those same resource allocations problems, a practical issue is that the proposed Servlet 4.0 HTTP2 support has not been implemented yet in GlassFish, and since the GF team has other priorities it's not planned even to do implement it (see https://java.net/projects/javaee-spec/lists/users/archive/2016-05/message/2).

      Without HTTP2 being implemented in GlassFish (which is the RI), Mojarra (JSF RI) can not easily target that API, so the research and prototypes can not really start.

      Delete
  5. Are we likely to see a simple way to say, generate emails, from a JSF page.
    This was available in Seam.
    Basically; being able to have "pluggable" renders is the ideal I guess.

    ReplyDelete