How to get JSF 2.2 (Mojarra), CDI (Weld) and @FlowScoped running in a Servlet Container (Jetty/Tomcat)

One major disadvantage when using JSF and CDI in combination is that the @ViewScoped annotation is not working anymore. At least up to JSF 2.1. Additional frameworks like Apache CODI or Seam 3 offered workarounds for this problem. The latest JSF 2.2 corrects this flaw and offers a working version of @ViewScoped out of the box. Furthermore it delivers the more powerful alternative @FlowScoped to the limited @ConversationScoped.

JSF 2.2 currently depends on the Servlet API 3.0. The servlet container Jetty supports this since Jetty 8. Tomcat does so since version 7.

Let’s assume that we have a maven project and want to use Mojarra as the JSF implementation. The necessary dependencies could be the following:

<dependency>
    <groupId>com.sun.faces</groupId>
    <artifactId>jsf-api</artifactId>
    <version>2.2.4</version>
</dependency>
<dependency>
    <groupId>com.sun.faces</groupId>
    <artifactId>jsf-impl</artifactId>
    <version>2.2.4</version>
</dependency>

When using the Mojarra implementation of JSF we also need to define the following listener in the web.xml:

<listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>

Now we should have a working JSF 2.2 and could already start using the new @ViewScoped annotation (in javax.faces.view). The @FlowScoped annotation is a CDI-only scope, though. When Mojarra gets initialized (ConfigureListener), it will check the presence of a CDI BeanManager. If none could be found, the Flows won’t get loaded and won’t work. No error will occur and no info message will appear. It just won’t work.

To get CDI (Weld in particular) running in Jetty or Tomcat, one might follow the official weld documentation chapter 18.3. This will lead to the definition of the following additional listener:

<listener>
    <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>

One very important thing to note is to define the Weld-listener before the JSF-Listener. Otherwise the CDI environment won’t be setup at the startup of JSF and the Flows aren’t loaded.

If everything was configured correctly, we should now have a working combination of the powerful JSF 2.2 and CDI.