When learning JSF, occasionally you’ll forget some detail and end up with an error in the browser. This page simply enumerates some errors I’ve encountered in my journey, and identifies the corresponding causes.
Can’t Resolve a Managed Bean
/address.xhtml @17,38 binding="#{addressBean.city}": Target Unreachable, identifier 'addressBean' resolved to null
The important thing to note here is that the identifier that couldn’t be resolved (“addressBean”) is the name of a bean that should be available in the JSF context. There are a couple of reasons this can happen:
- The bean doesn’t have the correct annotations.
- The view doesn’t reference the correct name for the bean.
Getting the Annotations Right
Every bean that is referenced in a JSF view must be properly annotated (or configured in faces-config.xml
). There are two ways to do this, depending on whether your application runs in a modern Java EE container (e.g. JBoss, Wildfly, Glassfish, WebLogic, WebSphere, etc) or a simple servlet container, like Tomcat.
Bean annotations using CDI
Java EE 6 (and later) containers have built-in support for Contexts and Dependency Injection (CDI) services. If your application is designed to run in a Java EE container, you should prefer the use of CDI annotations for your JSF beans. The applicable CDI annotation for a JSF bean is @javax.inject.Named
.
[java]
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
@Named
@RequestScoped
public class AddressBean {
private String city;
private String state
…
}
[/java]
Note that, in addition to the @Named
annotation, your bean will typically have a scope annotation. When using CDI, it is important that the scope annotation come from the javax.enterprise.context
package.
Bean annotations using JSF
If your application is designed to run in a simple servlet container, like Tomcat, CDI isn’t usually available. In this case, your managed beans will use the @javax.faces.bean.ManagedBean
specified in the JSF API.
[java]
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
@Named
@RequestScoped
public class AddressBean {
private String city;
private String state
…
}
[/java]
Note that, the scope annotation specified here also comes from the javax.faces.bean
package.
Another @ManagedBean
Annotation
The Commons Annotation specification (JSR-250) also defines a @javax.annoation.ManagedBean
. This annotation is not supported by the JSF standard, and can cause JSF to fail to resolve a bean reference.
If your bean appears to have a @ManagedBean
annotation but JSF is complaining that it cannot resolve the bean reference, carefully check your import statements to verify that you are importing javax.faces.bean.ManagedBean
.
Getting the Name Right
The identifier that you use in a JSF view depends on how you’ve applied the @Named
or @ManagedBean
. JSF resolves bean references by name (not by type). When troubleshooting a problem in resolving a managed bean, carefully check the identifier specified in the view and make certain that it corresponds to the annotations applied to the bean.
Default Bean Naming
When a name is not explicitly specified in the bean annotation, the unqualified class name is used as the bean name. The beans in the preceding examples used @Named
or @ManagedBean
without providing an explicit name attribute. The bean class name used in each example was AddressBean
, therefore the bean identifier to use in a view would be addressBean
.
Note that the first letter of the class name was converted to lower case in the default bean name. If the class name starts with two or more upper case letters, this conversion will not occur. For example, if your bean class name was URLBean
, the bean name would default to URLBean
, not uRLBean
or urlBean
.
Explicit Bean Naming with CDI
When using CDI, you can explicitly specify a bean name by providing the name as an annotation attribute:
[java]
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
@Named(“address”)
public class AddressBean {
…
}
[/java]
Explicit Bean Naming with JSF
When using JSF annotations, you can explicitly specify a bean name using the name
attribute:
[java]
import javax.faces.bean.ManagedBean
import javax.faces.bean.RequestScoped;
@ManagedBean(name = “address”)
public class AddressBean {
…
}
[/java]
When troubleshooting a problem in resolving a managed bean, carefully check the name specified in the view and make certain that it corresponds to the annotations applied to the bean.