jsf - Identifying and solving javax.el.PropertyNotFoundException: Target Unreachable -
when trying reference managed bean in el #{bean.entity.property}
, javax.el.propertynotfoundexception: target unreachable
exception being thrown, when bean property set, or when bean action invoked.
there seem 5 different kinds of messages:
- target unreachable, identifier 'bean' resolved null
- target unreachable, 'entity' returned null
- target unreachable, 'null' returned null
- target unreachable, ''0'' returned null
- target unreachable, 'bracketsuffix' returned null
what mean? how caused , how should solved?
1. target unreachable, identifier 'bean' resolved null
this boils down managed bean instance not found identifier (managed bean name) in el #{bean}
.
identifying cause can breakdown in 3 steps:
a. who's managing bean?
b. what's (default) managed bean name?
c. where's backing bean class?
1a. who's managing bean?
first step checking bean management framework responsible managing bean instance. jsf via @managedbean
? or cdi via @named
? or spring via @component
? can make sure you're not mixing multiple bean management framework specific annotations on same backing bean class? e.g. @named @component
, or @named @managedbean
, or @managedbean @component
. wrong. bean must managed @ 1 bean management framework , framework must configured. if have no idea choose, head backing beans (@managedbean) or cdi beans (@named)? , spring jsf integration: how inject spring component/service in jsf managed bean?
in case it's jsf who's managing bean via @managedbean
, need make sure of following:
the
faces-config.xml
root declaration compatible jsf 2.0. xsd file ,version
must @ least specify jsf 2.0 or higher , not 1.x.<faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd" version="2.0">
or if you're on jsf 2.2, of course specify such.
<faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd" version="2.2">
- you didn't accidentally import
javax.annotation.managedbean
instead ofjavax.faces.bean.managedbean
. watch out ide autocomplete, eclipse known autosuggest wrong 1 first item in list. - you didn't override
@managedbean
jsf 1.x style<managed-bean>
entry infaces-config.xml
on same backing bean class along different managed bean name. 1 have precedence on@managedbean
. registering managed bean infaces-config.xml
not necessary since jsf 2.0, remove it. - your runtime classpath clean , free of duplicates in jsf api related jars. make sure you're not mixing multiple jsf implementations (mojarra , myfaces). make sure don't provide jsf or java ee api jar file along webapp when target container bundles jsf api out box. see "installing jsf" section of our jsf wiki page jsf installation instructions. in case intend upgrade container-bundled jsf war on instead of in container itself, make sure you've instructed target container use war-bundled jsf api/impl.
- if you're packaging jsf managed beans in jar, make sure jar has @ least jsf 2.0 compatible
/meta-inf/faces-config.xml
. see how reference jsf managed beans provided in jar file? if you're actually using jurassic jsf 1.x, , can't upgrade, need register bean via
<managed-bean>
infaces-config.xml
instead of@managedbean
. don't forget fix project build path such don't have jsf 2.x libraries anymore (so@managedbean
annotation wouldn't confusingly compile).
in case it's cdi who's managing bean via @named
, need make sure of following:
cdi 1.0 (java ee 6) requires
/web-inf/beans.xml
file in order enable cdi in war. can empty or can have following content:<?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> </beans>
cdi 1.1 (java ee 7) without
beans.xml
, or emptybeans.xml
file, or above cdi 1.0 compatiblebeans.xml
behave same cdi 1.0. when there's cdi 1.1 compatiblebeans.xml
explicitversion="1.1"
, default register@named
beans with explicit cdi scope annotation such@requestscoped
,@viewscoped
,@sessionscoped
,@applicationscoped
, etc. in case intend register beans cdi managed beans, without explicit cdi scope, use below cdi 1.1 compatible/web-inf/beans.xml
bean-discovery-mode="all"
set (the defaultbean-discovery-mode="annotated"
).<?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" version="1.1" bean-discovery-mode="all"> </beans>
when using cdi 1.1
bean-discovery-mode="annotated"
(default), make sure didn't accidentally import jsf scope suchjavax.faces.bean.requestscoped
instead of cdi scopejavax.enterprise.context.requestscoped
. watch out ide autocomplete.- non-java ee containers tomcat , jetty doesn't ship cdi bundled. need install manually. it's bit more work adding library jar(s). tomcat, make sure follow instructions in answer: how install , use cdi on tomcat?
- your runtime classpath clean , free of duplicates in cdi api related jars. make sure you're not mixing multiple cdi implementations (weld, openwebbeans, etc). make sure don't provide cdi or java ee api jar file along webapp when target container bundles cdi api out box.
if you're packaging cdi managed beans jsf views in jar, make sure jar has @ least valid
/meta-inf/beans.xml
(which can kept empty).
in case it's spring who's managing bean via @component
, need make sure of following:
spring being installed , integrated per its documentation. importantingly, need @ least have in
web.xml
:<listener> <listener-class>org.springframework.web.context.contextloaderlistener</listener-class> </listener>
and in
faces-config.xml
:<application> <el-resolver>org.springframework.web.jsf.el.springbeanfaceselresolver</el-resolver> </application>
(above know regard spring — don't spring — feel free edit/comment other probable spring related causes; e.g. xml configuration related trouble)
in case it's repeater component who's managing (nested) bean via var
attribute (e.g. <h:datatable var="item">
, <ui:repeat var="item">
, <p:tabview var="item">
, etc) , got "target unreachable, identifier 'item' resolved null", need make sure of following:
the
#{item}
not referenced inbinding
attribtue of child component. incorrectbinding
attribute runs during view build time, not during view render time. moreover, there's physically 1 component in component tree reused during every iteration round. in other words, should usingbinding="#{bean.component}"
instead ofbinding="#{item.component}"
. better rid of component bining bean altogether , investigate/ask proper approach problem thought solve way. see how 'binding' attribute work in jsf? when , how should used?
1b. what's (default) managed bean name?
second step checking registered managed bean name. jsf , spring use conventions conform javabeans specification while cdi has exceptions depending on cdi impl/version.
a
foobean
backing bean class below,@named public class foobean {}
will in bean management frameworks have default managed bean name of
#{foobean}
, per javabeans specification.a
foobean
backing bean class below,@named public class foobean {}
whose unqualified classname starts @ least 2 capitals in jsf , spring have default managed bean name of unqualified class name
#{foobean}
, conform javabeans specificiation. in cdi, case in weld versions released before june 2015, not in weld versions released after june 2015 (2.2.14/2.3.0.b1/3.0.0.a9) nor in openwebbeans due an oversight in cdi spec. in weld versions , in owb versions first character lowercased#{foobean}
.if have explicitly specified managed bean name
foo
below,@named("foo") public class foobean {}
or equivalently
@managedbean(name="foo")
or@component("foo")
, available#{foo}
, not#{foobean}
.
1c. where's backing bean class?
third step doublechecking if backing bean class @ right place in built , deployed war file. make sure you've performed full clean, rebuild, redeploy , restart of project , server in case busy writing code , impatiently pressing f5 in browser. if still in vain, let build system produce war file, extract , inspect zip tool. compiled .class
file of backing bean class must reside in package structure in /web-inf/classes
. or, when it's packaged part of jar module, jar containing compiled .class
file must reside in /web-inf/lib
, not e.g. ear's /lib
or elsewhere.
if you're using eclipse, make sure backing bean class in src
, not webcontent
, , make sure project > build automatically enabled. if you're using maven, make sure backing bean class in src/main/java
, not in src/main/resources
or src/main/webapp
.
if you're packaging web application part of ear ejb+war(s), need make sure backing bean classes in war module , not in ear module nor ejb module. business tier (ejb) must free of web tier (war) related artifacts, business tier reusable across multiple different web tiers (jsf, jax-rs, jsp/servlet, etc).
2. target unreachable, 'entity' returned null
this boils down nested property entity
in #{bean.entity.property}
returned null
. exposes when jsf needs set value property
via input component below, while #{bean.entity}
returned null
.
<h:inputtext value="#{bean.entity.property}" />
you need make sure have prepared model entity beforehand in @postconstruct
, or <f:viewaction>
method, or perhaps add()
action method in case you're working crud lists and/or dialogs on same view.
@named @viewscoped public class bean { private entity entity; // +getter (setter not necessary). @inject private entityservice entityservice; @postconstruct public void init() { // in case you're updating existing entity. entity = entityservice.getbyid(entityid); // or in case want create new entity. entity = new entity(); } // ... }
as importance of @postconstruct
; doing in regular constructor fail in case you're using bean management framework uses proxies, such cdi. use @postconstruct
hook on managed bean instance initialization (and use @predestroy
hook on managed bean instance destruction). additionally, in constructor wouldn't have access injected dependencies yet, see nullpointerexception while trying access @inject bean in constructor.
in case entityid
supplied via <f:viewparam>
, you'd need use <f:viewaction>
instead of @postconstruct
. see when use f:viewaction / prerenderview versus postconstruct?
you need make sure preserve non-null
model during postbacks in case you're creating in add()
action method. easiest put bean in view scope. see how choose right bean scope?
3. target unreachable, 'null' returned null
this has same cause #2, (older) el implementation being used buggy in preserving property name display in exception message, incorrectly exposed 'null'. makes debugging , fixing bit harder when you've quite nested properties #{bean.entity.subentity.subsubentity.property}
.
the solution still same: make sure nested entity in question not null
, in levels.
4. target unreachable, ''0'' returned null
this has same cause #2, (older) el implementation being used buggy in formulating exception message. exposes when use brace notation []
in el in #{bean.collection[index]}
#{bean.collection}
non-null, item @ specified index doesn't exist. such message must interpreted as:
target unreachable, 'collection[0]' returned null
the solution same #2: make sure collection item available.
5. target unreachable, 'bracketsuffix' returned null
this has same cause #4, (older) el implementation being used buggy in preserving iteration index display in exception message, incorrectly exposed 'bracketsuffix' character ]
. makes debugging , fixing bit harder when you've multiple items in collection.
other possible causes of javax.el.propertynotfoundexception
:
- javax.el.elexception: error reading 'foo' on type com.example.bean
- javax.el.elexception: not find property actionmethod in class com.example.bean
- javax.el.propertynotfoundexception: property 'foo' not found on type com.example.bean
- javax.el.propertynotfoundexception: property 'foo' not readable on type java.lang.boolean
- javax.el.propertynotfoundexception: property not found on type org.hibernate.collection.internal.persistentset
- outcommented facelets code still invokes el expressions #{bean.action()} , causes javax.el.propertynotfoundexception on #{bean.action}
Comments
Post a Comment