Java EE 8 By Example
  • Introduction
  • Overview
    • Example Codes
  • JSF 2.3
    • Activating CDI in JSF 2.3
    • Run applications in JSF 2.2 compatible mode
    • CDI alignment
    • CDI compatible @ManagedProperty
    • Inject support in Converter, Validator and Behavor
    • Websocket support
    • UIData improvements
    • Class level bean validation with f:valdiateWholeBean
    • Java 8 DateTime support
    • PostRenderViewEvent: publising events after view is rendered
    • Search expression framework
  • CDI 2.0
    • Java SE support
    • Event Priority
    • Async Events
    • Register Beans dynamicially
    • Configurators and Intercept Producers
  • JPA 2.2
    • Java 8 Datetime support
    • Return Stream based result from Query
    • More CDI Alignments
  • JSON-B 1.0
  • JSON-P 1.1
  • Bean Validation 2.0
  • JAXRS 2.1
    • Async improvements
    • Server Sent Event
    • Reactive Client
  • Java EE Security API 1.0
    • HttpAuthenticationMechanism
    • IdentityStore
    • SecurityContext
  • Servlet 4.0
    • Server Push
    • Runtime Discovery of Servlet Mappings
    • Http Trailer
  • MVC 1.0
    • Getting started with MVC
    • Handling form submission
    • Exception handling and form validation
    • Processing PUT and DELETE methods
    • Page navigation
    • MVC and CDI
    • Security
    • Bean parameter conversion
    • View engine
Powered by GitBook
On this page

Was this helpful?

  1. JSF 2.3

Activating CDI in JSF 2.3

PreviousJSF 2.3NextRun applications in JSF 2.2 compatible mode

Last updated 4 years ago

Was this helpful?

When I upgraed to the newest Java EE 8, the first thing confused me is the CDI beans are not recognized in Facelects template in a JSF 2.3 based web applicaiton, which is working in the development version, but in the final release version, they are always resolved as null. I filed an issue on and with the developers from communities and the JSF experts.

According to the content of , In a JSF 2.3 application, to activate CDI support, declaring a 2.3 versioned faces-config.xml and adding javax.faces.ENABLE_CDI_RESOLVER_CHAIN in web.xml is not enough, you have to declare @FacesConfig annotated class to enable CDI.

Here is the steps I created a workable JSF 2.3 application in Java EE 8.

  1. Create a Java web application, this can be done easily by NetBeans IDE, or generated by Maven archetype, for example.

     $ mvn archetype:generate -DgroupId=com.example
     -DartifactId=demo
     -DarchetypeArtifactId=maven-archetype-webapp
     -DinteractiveMode=false
  2. Add javaee-api in project dependencies.

     <properties>
       <version.javaee-api>8.0</version.javaee-api>
       ...// other properties
     </properties>
     <dependencyManagement>
       <dependencies>
           <dependency>
               <groupId>javax</groupId>
               <artifactId>javaee-api</artifactId>
               <version>${version.javaee-api}</version>
               <scope>provided</scope>
           </dependency>
           ...//other dependencies
        </dependencies>  
     </dependencyManagement>
     <dependencies>
        <dependency>
           <groupId>javax</groupId>
           <artifactId>javaee-api</artifactId>
        </dependency>
        ...//other dependencies
     </dependencies>
  3. Add a faces-config.xml into WEB-INF folder, it is optional in JSF 2.3. ​

     <?xml version='1.0' encoding='UTF-8'?>
     <faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_3.xsd"
           version="2.3">
     </faces-config>
  4. Declare a beans.xml, CDI is enabled by default in Java EE 7, so it is optional.

     <?xml version="1.0" encoding="UTF-8"?>
     <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
            bean-discovery-mode="all" 
            version="2.0">
     </beans>
  5. Add web.xml. It is not required by JSF, but you can customize the application by some properties.

     <?xml version="1.0" encoding="UTF-8"?>
     <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
              version="4.0">
         <context-param>
             <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
             <param-value>0</param-value>
         </context-param>
    
         <context-param>
             <param-name>javax.faces.PROJECT_STAGE</param-name>
             <param-value>Development</param-value>
         </context-param>
    
         <context-param>
             <param-name>javax.faces.validator.ENABLE_VALIDATE_WHOLE_BEAN</param-name>
             <param-value>true</param-value>
         </context-param>
    
         <context-param>
             <param-name>javax.faces.ENABLE_CDI_RESOLVER_CHAIN</param-name>
             <param-value>true</param-value>
         </context-param>
    
         <context-param>
             <param-name>javax.faces.ENABLE_WEBSOCKET_ENDPOINT</param-name>
             <param-value>true</param-value>
         </context-param> 
    
         <!--    <context-param>
             <param-name>javax.faces.DISABLE_FACESSERVLET_TO_XHTML</param-name>
             <param-value>true</param-name>
         </context-param>-->
     </web-app>

    JSF 2.3 provides some options to activate the new features added in 2.3.

    • ENABLE_VALIDATE_WHOLE_BEAN is used to enable class level Bean validation

    • ENABLE_WEBSOCKET_ENDPOINT is used to enable web socket support

    • ENABLE_CDI_RESOLVER_CHAIN is originally designed for enabling CDI, but it seems it is replaced by @FacesConfig

    • DISABLE_FACESSERVLET_TO_XHTML will disable JSF servlet mapping to *.xhtml. By default, JSF Servlet will serve \.xhtml*.

  6. Declare a @FacesConfig annotated class to activate CDI in JSF 2.3.

     @FacesConfig(
     // Activates CDI build-in beans
     version = JSF_2_3 
     )
     public class ConfigurationBean {
    
     }

    Open the source code of FacesConfig, you will know it is a standard CDI Qualifier.

     @Qualifier
     @Target(TYPE)
     @Retention(RUNTIME)
     public @interface FacesConfig {
    
         public static enum Version {
    
             /**
              * <p class="changed_added_2_3">This value indicates CDI should be used
              * for EL resolution as well as enabling JSF CDI injection, as specified
              * in Section 5.6.3 "CDI for EL Resolution" and Section 5.9 "CDI Integration".</p>
              */
             JSF_2_3
    
         }
    
         /**
          * <p class="changed_added_2_3">The value of this attribute indicates that
          * features corresponding to this version must be enabled for this application.</p>
          * @return the spec version for which the features must be enabled.
          */
         @Nonbinding Version version() default Version.JSF_2_3;
    
     }

Done.

Create a simple sample to verify if it works.

Firstly create a simple backing bean to say hello to JSF.

@Named
@RequestScoped
public class HelloBean {

    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public void sayHi() {
        this.message = this.message+ " received at " + LocalDateTime.now();
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 13 * hash + Objects.hashCode(this.message);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final HelloBean other = (HelloBean) obj;
        if (!Objects.equals(this.message, other.message)) {
            return false;
        }
        return true;
    }

}

And template will accept user input and show the message.

<!DOCTYPE html>
<html lang="en"
      xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:jsf="http://xmlns.jcp.org/jsf">
    <h:head/>

    <h:messages />

    <h:body>
        <p>
            Hello JSF 2.3 with CDI activation
        </p>

        <form jsf:id="form">
            <p>
                <strong>Welcome to JSF 2.3 world: </strong> 
                <div>#{helloBean.message}</div>
            </p>
            <p>
                <strong>Message: </strong> 
                <div><input type="text" jsf:id="message" jsf:value="#{helloBean.message}"></input></div>
            </p>
            <p>
                <input type="submit" value="Say Hi to JSF" jsf:action="#{helloBean.sayHi()}" />
            </p>
        </form>

    </h:body>

</html>

, as the codes shown above, we use all bean-discovery-mode in the beans.xml. If we switch to annotated here, we have to add @FacesConfig to every CDI backing beans, it is unreasonable.

Grab the from my GitHub account.

my Java EE 7 sample
Mojarra
discussed it
README
Another issue about JSF 2.3 still confused me and other developers
source codes