@javax.faces.bean.ManagedProperty in CDI @Named bean returns null

StepTNT picture StepTNT · Mar 29, 2012 · Viewed 14k times · Source

I'm trying to deal with @javax.faces.bean.ManagedProperty but without success !

I've been following this guide, and it not seems that hard. But my code simply won't work!

Here's a little snippet

@ManagedBean
@SessionScoped
public class LoginBean {

    private User user;

    // ...
}
@Named
@RequestScoped
public class MessagesBean {

    @ManagedProperty(value = "#{loginBean}")
    private LoginBean loginBean;

    public String getUser() {
        System.err.println(loginBean == null);
        return loginBean.getUser().getUsername();
    }

    // ...
}

This code gives me a NullPointerException, saying that loginBean is null!

Any suggestion?

Answer

Matt Handy picture Matt Handy · Mar 29, 2012

You are mixing JSF managed beans with CDI beans. Your LoginBean is a JSF managed bean (it has the @ManagedBean annotation). Your MessageBean is a CDI bean (it has the @Named annotation). If you changed the Message bean to a JSF managed bean (replacing @Named with @ManagedBean) then the problem should be solved (It should work with two CDI beans as well). Or if you're using JSF 2.3 or newer, then use javax.faces.annotation.ManagedProperty instead in the CDI bean.

Here is a short overview of how injection works between both bean types:

CDI @Named --> CDI @Named (works)

CDI @Named --> JSF @ManagedBean (works only if scope of injected bean is broader)

JSF @ManagedBean --> JSF @ManagedBean (works only if scope of injected bean is broader)

JSF @ManagedBean --> CDI @Named (won't work)

But take care of the scope import classes. There are different classes for @SessionScoped and @RequestScoped depending on the bean type.

javax.faces.bean.SessionScoped for @ManagedBeans

javax.enterprise.context.SessionScoped for CDI @Named beans

In addition, for @Named (CDI) use @Inject and for @ManagedBean use @ManagedProperty. There is one thing that does not work in CDI. Your @ManagedProperty(value = "#{loginBean}") gets a full bean, but @ManagedProperty(value = "#{loginBean.user}") to get a 'property' of a bean works to. This is not directly possible in CDI with @Inject. See CDI Replacement for @ManagedProperty for a 'solution'