4
votes

I rode that is recommended to use CDI beans as backing beans instead of JSF managed beans.

So i decided to create a little example, to understand how it works, for a @RequestScopedBean:

-instead of using @ManagedBean("beanName") ,i use @Named("beanName")

-instead of using javax.faces.bean.RequestScopped i use javax.enterprise.context.RequestScoped;

The demo program is very simple, i have a field and a submit button, when the user inputs something and the page is refreshed, the inputed value is not displayed anymore(It last while the request lasts right?). I think i did everything ok, but i get an exception that says:

WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception javax.el.PropertyNotFoundException: /index.xhtml @19,47 value="#{cdiBean.passedValue}": Target Unreachable, identifier 'cdiBean' resolved to null

This is how my program looks like:

index.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">

<h:head>
        <title>RequestScope demo CDI(Component Dependency Injection)</title>
</h:head>

<h:body>

    <h:form>

    <h3>RequestScope demo CDI(Component Dependency Injection)</h3>

    <h:inputText value="#{cdiBean.passedValue}"/>
    <br/>
    <h:commandButton value="submit" action="index"/>

    </h:form>
</h:body>
</html>

DemoBB.java

package backingbeans;

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named("cdiBean")//The Named anotation indicates that this is a CDI bean
@RequestScoped//If we use CDI beans the @RequestScoped annotation must come from: javax.enterprise.context.RequestScoped;
public class DemoBB {

    //This value will be saved on the session only until the server responds to the request
    private String passedValue;

    public String getPassedValue() {
        return passedValue;
    }

    public void setPassedValue(String passedValue) {
        this.passedValue = passedValue;
    }   
}

-Where is my mistake?

-What is the advantage of using this approach? I still don't understand that.

1

1 Answers

3
votes

Do you have an empty beans.xml along with your web.xml? I think it is mandatory to be there.

Read section 15.6 here. Quote from it:

CDI doesn't define any special deployment archive. You can package beans in JARs, EJB-JARs or WARs—any deployment location in the application classpath. However, the archive must be a "bean archive". That means each archive that contains beans must include a file named beans.xml in the META-INF directory of the classpath or WEB-INF directory of the web root (for WAR archives). The file may be empty. Beans deployed in archives that do not have a beans.xml file will not be available for use in the application.

In an embeddable EJB container, beans may be deployed in any location in which EJBs may be deployed. Again, each location must contain a beans.xml file.