Keywords: javax.el.PropertyNotFoundException | Target Unreachable | Expression Language | Managed Beans | CDI | JSF | Spring | Exception Handling
Abstract: This article provides an in-depth analysis of the common javax.el.PropertyNotFoundException: Target Unreachable exception encountered when using Expression Language (EL) in frameworks like JSF and CDI. By examining five distinct error message types, including 'identifier resolved to null' and 'entity returned null', it explains root causes such as misconfigured managed bean frameworks, null nested properties, and invalid collection indices. The paper offers systematic diagnostic steps and solutions, covering configuration essentials for CDI, JSF, and Spring, along with code examples and best practices to help developers effectively prevent and fix these issues.
Exception Overview and Classification
In Java EE or Jakarta EE applications, when referencing managed beans using Expression Language (EL), such as #{bean.entity.property}, the javax.el.PropertyNotFoundException: Target Unreachable exception is frequently thrown, typically during bean property setting or action invocation. Based on error messages, it can be categorized into five types:
- Target Unreachable, identifier 'bean' resolved to null
- Target Unreachable, 'entity' returned null
- Target Unreachable, 'null' returned null
- Target Unreachable, ''0'' returned null
- Target Unreachable, 'BracketSuffix' returned null
Each type is analyzed below with causes and solutions.
1. Target Unreachable, identifier 'bean' resolved to null
This error indicates that EL cannot locate the managed bean instance via the identifier #{bean}. Diagnosis involves three steps: identifying the managing framework, checking the bean name, and verifying class location.
1.1 Identifying the Managing Framework
First, determine which framework manages the bean: CDI (via @Named), JSF (via @ManagedBean, deprecated), or Spring (via @Component). Avoid mixing annotations from multiple frameworks on the same class, e.g., @Named @ManagedBean, as this causes conflicts.
CDI Configuration Essentials
- CDI 1.0 (Java EE 6) requires a
/WEB-INF/beans.xmlfile, which can be empty or contain basic configuration. - CDI 1.1 (Java EE 7) by default only registers
@Namedbeans with explicit CDI scope annotations (e.g.,@RequestScoped). To register all beans, setbean-discovery-mode="all". - Avoid mistakenly importing JSF scopes (e.g.,
javax.faces.bean.RequestScoped) instead of CDI scopes (e.g.,javax.enterprise.context.RequestScoped). - Mojarra 2.3.0-2.3.2 has compatibility issues with CDI 1.1+; upgrade or add the
@FacesConfigannotation. - Non-JEE containers (e.g., Tomcat) require manual CDI installation following specific guides.
- Ensure a clean classpath, avoiding duplicate CDI API JARs.
- If beans are packaged in a JAR, include
/META-INF/beans.xml.
JSF Configuration Essentials
- Ensure
faces-config.xmlis at least JSF 2.0-compliant, using correct namespaces (e.g.,xmlns.jcp.orgfor JSF 2.2+). - Avoid importing
javax.annotation.ManagedBeaninstead ofjavax.faces.bean.ManagedBean. - Do not override
@ManagedBeanwith JSF 1.x-style<managed-bean>entries. - Clean the classpath to prevent mixing JSF implementations (e.g., Mojarra and MyFaces).
- Beans in JARs require
/META-INF/faces-config.xml.
Spring Configuration Essentials
- Configure
ContextLoaderListenerinweb.xml. - Set
SpringBeanFacesELResolverinfaces-config.xml.
1.2 Checking the Bean Name
JSF and Spring follow JavaBeans conventions, while CDI has exceptions in some versions. For example:
- A
FooBeanclass with@Nameddefaults to#{fooBean}. - For class names starting with two uppercase letters (e.g.,
FOOBean), JSF/Spring use#{FOOBean}, but some CDI implementations may use#{fOOBean}. - Explicitly specified names (e.g.,
@Named("foo")) are accessible only via#{foo}.
1.3 Verifying Class Location
Ensure bean classes are in the correct location: compiled .class files should be in /WEB-INF/classes or within JARs in /WEB-INF/lib. With Eclipse or Maven, check source folder settings and perform full clean, rebuild, and restart cycles.
2. Target Unreachable, 'entity' returned null
This error indicates that a nested property entity returns null, often when setting values via input components. For example:
<h:inputText value="#{bean.entity.property}" />
Solution: Initialize the model entity in a @PostConstruct method to ensure it is non-null. Example code:
@Named
@ViewScoped
public class Bean {
private Entity entity;
@Inject
private EntityService entityService;
@PostConstruct
public void init() {
entity = new Entity(); // or fetch from service
}
// getter method
}
Note: Use @PostConstruct instead of constructors to handle proxies and dependency injection properly. For view parameters, use <f:viewAction>. Place beans in view scope to maintain state across postbacks.
3. Target Unreachable, 'null' returned null
This error is identical to type 2, but older EL implementations incorrectly display the property name as 'null', complicating debugging. For instance, in #{bean.entity.subentity.property}, a nested level is null. Solution: Ensure all nested entities are non-null.
4. Target Unreachable, ''0'' returned null
This error occurs with bracket notation #{bean.collection[index]} when the collection is non-null but the item at the specified index does not exist. The message should be interpreted as "'collection[0]' returned null". Solution: Ensure the collection item is available.
5. Target Unreachable, 'BracketSuffix' returned null
This error is identical to type 4, but older EL implementations incorrectly display the index as 'BracketSuffix' (the character ]). Solution is the same as for type 4.
Other Common Causes
javax.el.PropertyNotFoundException can also arise from:
- Property read errors, such as missing getter methods.
- Unreadable properties, e.g., attempting to read non-existent properties on
Booleantypes. - Property access issues with Hibernate collection types like
PersistentSet. - Commented-out Facelets code still invoking EL expressions.
By applying systematic diagnostics and adhering to best practices, developers can effectively prevent and resolve these exceptions, enhancing application stability.