0

I read somewhere that it's better to use CDI @Named instead of JSF @ManagedBean, because of CDI, so I'm trying to convert some of my code. I'm trying to use @Named in JSF, but it's always unreachable. When using @ManagedBean there was no problem.

I'm using it like @ManagedBean, as below

CustomerBacking.java

package com.wordpress.marczykm.backing;

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

@Named("customer")
@RequestScoped
public class CustomerBacking {

    @EJB
    private CustomerService customerService;

    public CustomerBacking() {
    }

    public String addCustomer(Customer customer) {
        customerService.addCustomer(customer);
        return "customer_overview";
    }

    public Customer getCustomer(){
        return customerService.getCustomer();
    }
}

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>EJB 3.0 Test</title>
    </h:head>
    <h:body>
        <h:outputText value="#{customer.firstname}"/>
        <h:form>
            <h:outputText value="Imię"/>
            <h:inputText id="firstname" name="firstname" value="#{customer.firstname}" /><br/>

            <h:outputText value="Nazwisko"/>
            <h:inputText id="lastname" name="lastname" value="#{customer.lastname}" /><br/>

            <h:commandButton value="Dodaj" actionListener="#{customer.addCustomer}"/>
        </h:form>
</h:body>
</html>
Vasil Lukach
  • 3,658
  • 3
  • 31
  • 40
Marcin Marczyk
  • 93
  • 2
  • 10
  • 1
    You have mixed JSF namespaces and CDI ones. Try `import javax.enterprise.context.RequestScoped` instead. Also your backing bean code and xhtml don't match but I assume this to be a copy&paste error. – mabi Feb 12 '14 at 09:30
  • ok, i've edited the code (changed to proper import statement and changed annotation to `@Named("customer")`), but still after clicking the CommandButton i have __Target Unreachable, identifier 'customer' resolved to null__ error – Marcin Marczyk Feb 12 '14 at 10:03
  • How exactly did you install/enable CDI in your environment? It's by default disabled and in some servers (e.g. Tomcat) even by default not installed. – BalusC Feb 12 '14 at 10:03
  • i have just created new _Dynamic Web Project_ using Spring Tool Suite and ticked Java Server Faces in project _Properties/Project Facets_ – Marcin Marczyk Feb 12 '14 at 10:07
  • Uh, I didn't ask for that. May I assume that you have no clue how/when CDI is enabled for the environment? In technical terms, you don't have a `/WEB-INF/beans.xml` file in the web content folder at all? – BalusC Feb 12 '14 at 10:07
  • these are all steps that did. i have added beans.xml where you told. do i have to declare BackingBeans there or it can have only ` ` – Marcin Marczyk Feb 12 '14 at 10:09
  • OK, then the environment (the server where you deploy the webapp to) apparently doesn't natively support CDI. What server is it? Tomcat? How exactly did you install CDI then? By the way, you don't declare "backing beans". Instead, you declare "managed beans". With `@Named` you declare a backing bean class as a CDI managed bean. With `@ManagedBean` you declare a backing bean class as a JSF managed bean. Do you get the point? – BalusC Feb 12 '14 at 11:24
  • OK, i got it. I use Glassfish, does it support CDI natively? – Marcin Marczyk Feb 12 '14 at 11:34
  • Go to this answer http://stackoverflow.com/a/12012663/221951 and see if it's helpful for you. It seems that you've mixed some concepts. – Piotr Gwiazda Feb 12 '14 at 21:53

2 Answers2

1

To sum up, looking at Netbeans sample CDI app, the bean which needs to be accesible by JSF page needs to:

  • have @Named annotation (javax.inject.Named)
  • have scope annotation (like @SessionScoped, @RequestScoped, @ViewScoped), but imported from javax.enterprise.context.*
  • doesn't have to have empty, non-argument constructor
  • and the thing that wasn't in my code is that, that the bean needs to implement Serializable (java.io.Serializable)
  • last thing is that if your app is a web application it needs a beans.xml (can be completly empty) in WEB-INF directory, if it is a bean app it have to be in META-INF directory
Marcin Marczyk
  • 93
  • 2
  • 10
0

You don't mention which servlet container/application server and which CDI implementation version you're using.

I have no clue what Spring Tool Suite assumes as default, presumably it's Tomcat, Spring and no CDI at all, so you have to add and configure a CDI implementation (e.g. Weld or OpenWebBeans).

For CDI 1.0, you'll have to add a WEB-INF/beans.xml descriptor (which may be empty) to have your beans discovered. This is no longer necesary for CDI 1.1.

Harald Wellmann
  • 12,615
  • 4
  • 41
  • 63