[解決済み] javax.el.PropertyNotFoundException の識別と解決。ターゲットに到達できない
質問
ELでマネージドBeanを参照しようとすると、以下のようになります。
#{bean.entity.property}
のように参照しようとすると、時々
javax.el.PropertyNotFoundException: Target Unreachable
例外が投げられることがあります。通常、ビーンプロパティが設定されるとき、またはビーンアクションが起動されるときです。
メッセージの種類は5つあるようです。
- ターゲットに到達できません。識別子 'bean' は null に解決されました。
- ターゲットに到達できず、'entity'がnullに返されました。
- ターゲットに到達できず、'null' が null を返しました。
- ターゲットに到達できず、''0''が返され、nullが返される
- ターゲットに到達できず、'BracketSuffix' が null で返されました。
これらはすべて何を意味するのでしょうか。どのように引き起こされ、どのように解決すべきなのでしょうか?
どのように解決するのですか?
1. ターゲットに到達できません。識別子 'bean' は null に解決されました。
これは、管理されたビーンインスタンス自体が、以下のようなELでまさにその識別子(管理されたビーン名)で見つけることができなかったということに帰結します。
#{bean}
.
原因の特定は、3つのステップに分けることができます。
a. 誰がそのビーンを管理しているのか?
b. (デフォルトの)管理されたビーン名は何ですか?
c. バッキングビーンクラスはどこですか?
1a. 誰がビーンを管理しているのか?
最初のステップは、どのビーン管理フレームワークがビーンインスタンスの管理を担っているかを確認することでしょう。それは
CDI
を経由して
@Named
? それとも
JSF
を経由して
@ManagedBean
? それとも
春
を経由して
@Component
? 全く同じバッキングビーンクラスに複数のビーン管理フレームワーク固有のアノテーションを混在させていないことを確認できますか?例えば
@Named @ManagedBean
,
@Named @Component
または
@ManagedBean @Component
. これは誤りである。Beanは少なくとも1つのBean管理フレームワークによって管理されなければならず、そのフレームワークは適切に構成されていなければなりません。どれを選べばいいのかすでにわからない場合は、次のサイトへ向かってください。
Backing Bean (@ManagedBean) か CDI Beans (@Named) か?
と
Spring JSFの統合:JSFマネージドBeanにSpringコンポーネント/サービスを注入する方法は?
万が一、それが
CDI
でビーンを管理している人が
@Named
を使用している場合、次のことを確認する必要があります。
-
CDI 1.0 (Java EE 6) では、CDI 1.0 に対応するために
/WEB-INF/beans.xml
ファイルが必要です。これは 空の または以下の内容を含むことができます。<?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) を一切使用せずに
beans.xml
がない場合、あるいは空のbeans.xml
ファイル、あるいは上記の CDI 1.0 互換のbeans.xml
は、CDI 1.0と同じ動作をします。CDI 1.1互換のbeans.xml
があり、明示的にversion="1.1"
を指定した場合、デフォルトでは@Named
ビーンズ と のような明示的なCDIスコープアノテーションは@RequestScoped
,@ViewScoped
,@SessionScoped
,@ApplicationScoped
など。明示的なCDIスコープを持たないものも含め、すべてのビーンをCDIマネージドビーンとして登録したい場合は、以下のCDI 1.1互換の/WEB-INF/beans.xml
とbean-discovery-mode="all"
を設定します(デフォルトはbean-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>
-
CDI 1.1+を使用する場合
bean-discovery-mode="annotated"
(デフォルト) を使っている場合、誤ってJSFスコープをインポートしていないか確認してください。javax.faces.bean.RequestScoped
CDI スコープの代わりにjavax.enterprise.context.RequestScoped
. IDEのオートコンプリートで気をつけること。 -
Mojarra 2.3.0-2.3.2 と CDI 1.1+ を使っているときに
bean-discovery-mode="annotated"
(デフォルト) を使用している場合、Mojarra を 2.3.3 以降のバージョンにアップグレードする必要があります。 バグ . アップグレードができない場合は、以下のいずれかの方法でbean-discovery-mode="all"
でbeans.xml
とするか、JSF2.3特有の@FacesConfig
アノテーションを WAR 内の任意のクラス (一般的にはアプリケーションスコープのスタートアップクラスのようなもの) に付けることができます。 -
Servlet 4.0 コンテナで JSF 2.3 を使用する場合、そのコンテナ内で
web.xml
で宣言されたServlet 4.0コンテナでJSF 2.3を使う場合、JSF 2.3特有の@FacesConfig
アノテーションを WAR 内の任意のクラス (一般的にはアプリケーションスコープのスタートアップクラスのようなもの) に明示的に付ける必要があります。これは、Servlet 3.xでは必要ありません。 -
CDI 3.0を使用する場合、最初のバージョンでパッケージ名が
javax.*
からjakarta.*
というように、すべてのデプロイメントディスクリプタファイルがbeans.xml
,web.xml
,faces-config.xml
は適合する 新しいjakartaee
スキーマ に準拠しないので、古いjavaee
スキーマに準拠しません。<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_3_0.xsd" version="3.0" bean-discovery-mode="all"> </beans>
-
TomcatやJettyのような非JEEコンテナは、CDIをバンドルして出荷されません。手動でインストールする必要があります。これは、単にライブラリJAR(複数可)を追加するよりも少し手間がかかります。Tomcat については、この回答の指示に従っていることを確認してください。 TomcatにCDIをインストールして使用する方法は?
-
ランタイムのクラスパスがクリーンで、CDI API関連のJARに重複がないこと。複数のCDI実装(Weld、OpenWebBeansなど)が混在していないことを確認してください。ターゲットコンテナがすでにCDI APIをバンドルしている場合、別のCDI、あるいはJava EE APIのJARファイルをwebappと共に提供しないことを確認してください。
-
JSFビューのCDIマネージドBeanをJARでパッケージングしている場合、そのJARは少なくとも有効な
/META-INF/beans.xml
があることを確認してください (これは空のままでもかまいません)。
万が一、それが
JSF
を介してBeanを管理している人が、2.3以降非推奨の
@ManagedBean
で、CDIに移行できない場合、次のことを確認する必要があります。
-
は
faces-config.xml
ルート宣言は、JSF 2.0 と互換性があります。そのため、XSD ファイルとversion
は 少なくとも は JSF 2.0 以上を指定してください。<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">
JSF 2.1では、単に
2_0
と2.0
によって2_1
と2.1
をそれぞれJSF 2.2 以降を使用しているのであれば、必ず
xmlns.jcp.org
名前空間の代わりにjava.sun.com
に置き換えます。<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">
JSF 2.3では、単に
2_2
と2.2
によって2_3
と2.3
をそれぞれ -
誤ってインポートしていない
javax.annotation.ManagedBean
の代わりにjavax.faces.bean.ManagedBean
. IDE のオートコンプリートでは、Eclipse はリストの最初のアイテムとして間違ったものを自動提案することが知られているので、注意してください。 -
をオーバーライドしていない
@ManagedBean
をJSF 1.xのスタイルで<managed-bean>
のエントリでfaces-config.xml
のエントリは、全く同じバッキングビーンクラスに、異なるマネージドビーン名で追加されます。こちらは@ManagedBean
. で管理されたビーンを登録することはfaces-config.xml
の登録は、JSF2.0以降では不要なので、削除してください。 -
ランタイムクラスパスがクリーンで、JSF API関連のJARに重複がないこと。複数の JSF 実装 (Mojarra と MyFaces) を混合していないことを確認してください。ターゲットコンテナがすでにJSF APIをバンドルしている場合、別のJSFやJava EE APIのJARファイルをwebappと共に提供しないことを確認してください。以下も参照してください。 JSF wikiページの "JSFのインストール"のセクションを参照してください。 を参照してください。コンテナ自体ではなく、コンテナ・バンドルされた JSF を WAR からアップグレードする場合、ターゲット・コンテナに WAR バンドルされた JSF API/impl を使用するように指示したことを確認します。
-
JSFマネージドビーンをJARでパッケージングする場合、そのJARが少なくともJSF2.0互換の
/META-INF/faces-config.xml
. また、以下を参照してください。 JARファイルで提供されるJSFマネージドBeanを参照するにはどうすればよいですか? -
もし、あなたが 実際に を使用していて、アップグレードできないのであれば、ビーンを
<managed-bean>
でfaces-config.xml
の代わりに@ManagedBean
. JSF 2.x ライブラリがないように、プロジェクトのビルドパスを修正することを忘れないでください。@ManagedBean
アノテーションがコンパイルに成功するような混乱を招かないように)。
万が一、それが
春
でビーンを管理している場合
@Component
で管理している場合、以下のことを確認する必要があります。
-
Springが以下のようにインストールされ、統合されていること。 のドキュメントに従ってインストールされ、統合されています。 . 重要なのは、少なくともこれを
web.xml
:<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
そして、これを
faces-config.xml
:<application> <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver> </application>
-
(上記は私が知っているSpringに関すること全てです。私はSpringはやりません。Springに関連すると思われる他の原因、例えばXML設定に関するトラブルがあれば、自由に編集/コメントしてください)
万が一、それが
リピータコンポーネント
であり、その
var
属性で管理されています (例
<h:dataTable var="item">
,
<ui:repeat var="item">
,
<p:tabView var="item">
など)で、実際に "Target Unreachable, identifier 'item' resolved to null" が発生した場合、以下のことを確認する必要があります。
-
その
#{item}
が参照されないのはbinding
アトリビュートで参照されていません。これはbinding
属性はビューの構築時に実行され、ビューのレンダリング時には実行されないからです。さらに、コンポーネント ツリーには物理的に 1 つのコンポーネントしかなく、繰り返しラウンドごとに再利用されるだけです。つまり、実際に使用するのはbinding="#{bean.component}"
の代わりにbinding="#{item.component}"
. しかし、より良い方法は、ビーンに結合するコンポーネントを完全に取り除き、この方法で解決しようと思った問題のための適切なアプローチを調査したり尋ねたりすることです。また JSFでは'binding'属性はどのように機能するのですか?いつ、どのように使うべきですか?
1b. (デフォルトの)マネージド・ビーン名は何ですか?
第二段階は、登録されたマネージドビーンの名前を確認することです。JSFとSpringでは、以下のような規約があります。 JavaBeansの仕様 を採用していますが、CDIはCDI impl/versionによって例外が発生します。
-
A
FooBean
のようなバッキングビーンクラスを作成します。@Named public class FooBean {}
は、すべてのビーン管理フレームワークにおいて、デフォルトの管理ビーン名である
#{fooBean}
を持つことになります。 -
A
FOOBean
のようなバッキングビーンクラスを作成します。@Named public class FOOBean {}
非修飾クラス名が少なくとも2つの大文字で始まる場合、JSFとSpringでは、非修飾クラス名と全く同じデフォルトのマネージドBean名を持ちます。
#{FOOBean}
また,JavaBeansの仕様に適合する。CDIでは、2015年6月以前にリリースされたWeldバージョンでもそうですが、2015年6月以降にリリースされたWeldバージョン(2.2.14/2.3.0.B1/3.0.0.A9)でもOpenWebBeansでは CDI仕様の見落とし . これらのWeldバージョンとすべてのOWBバージョンでは、最初の文字が小文字になっただけの#{fOOBean}
. -
マネージドビーンの名前を明示的に指定した場合
foo
のようにします。@Named("foo") public class FooBean {}
あるいは、同じように
@ManagedBean(name="foo")
または@Component("foo")
によってのみ利用可能になります。#{foo}
であり、したがって ではなく によって#{fooBean}
.
1c. バッキングビーンクラスはどこだ?
3番目のステップは、バッキングビーンクラスがビルドおよびデプロイされたWARファイルの正しい場所にあるかどうかを再確認することです。実際にコードを書くのに忙しく、ブラウザで F5 をせっせと押していた場合に備えて、プロジェクトとサーバーの完全なクリーニング、再構築、再デプロイ、再起動を適切に実行したことを確認します。それでもダメなら、ビルドシステムがWARファイルを生成するので、それをZIPツールで解凍して検査します。コンパイルされた
.class
ファイルは、バッキングビーンクラスのパッケージ構造内の
/WEB-INF/classes
. または、JAR モジュールの一部としてパッケージ化されている場合、コンパイルされた
.class
ファイルに存在する必要があります。
/WEB-INF/lib
に存在しなければならず、例えば EAR の
/lib
などではありません。
Eclipseを使用している場合、バッキングビーンクラスが
src
であり、したがって
ではなく
WebContent
であることを確認し
プロジェクトを自動的にビルドする
が有効になっていることを確認します。Mavenを使用している場合、バッキングビーンクラスが
src/main/java
にあることを確認し、その結果
ではなく
で
src/main/resources
または
src/main/webapp
.
EJB+WAR(s)でEARの一部としてWebアプリケーションをパッケージングしている場合、バッキングBeanクラスがWARモジュールにあり、したがってEARモジュールにもEJBモジュールにもないことを確認する必要があります。ビジネス層(EJB)は、複数の異なるウェブ層(JSF、JAX-RS、JSP/サーブレットなど)で再利用できるように、ウェブ層(WAR)関連の成果物から解放される必要があります。
2. ターゲットに到達できず、'entity' が null を返しました。
これは要するに
のネストされた
プロパティ
entity
のように
#{bean.entity.property}
が返される
null
. これは通常、JSFが以下のものを必要とする場合にのみ公開されます。
を設定します。
の値を
property
の値を入力コンポーネントで設定し、一方
#{bean.entity}
が返されるのに対し、実際には
null
.
<h:inputText value="#{bean.entity.property}" />
あらかじめモデルの実体を
@PostConstruct
で、あるいは
<f:viewAction>
メソッド、あるいは
add()
メソッド、あるいは同じビューで CRUD リストやダイアログを操作する場合には
@Named
@ViewScoped
public class Bean {
private Entity entity; // +getter (setter is not necessary).
@Inject
private EntityService entityService;
@PostConstruct
public void init() {
// In case you're updating an existing entity.
entity = entityService.getById(entityId);
// Or in case you want to create a new entity.
entity = new Entity();
}
// ...
}
の重要性については
@PostConstruct
を使用するビーン管理フレームワークを使用している場合、通常のコンストラクタでこれを行うと失敗します。
プロキシ
を使用するビーン管理フレームワークを使用している場合、失敗します。常に
@PostConstruct
を使ってマネージドビーンのインスタンス初期化をフックしてください(そして
@PreDestroy
を使用してマネージドビーンのインスタンスの破壊にフックします)。さらに、コンストラクタでは、注入された依存関係にはまだアクセスできないので、以下を参照してください。
コンストラクタで @Inject ビーンにアクセスしようとすると NullPointerException が発生します。
.
万が一
entityId
を介して提供される場合
<f:viewParam>
を介して提供される場合、あなたは
<f:viewAction>
の代わりに
@PostConstruct
. また
f:viewAction / preRenderViewとPostConstructはいつ使い分けるのですか?
を保存していることを確認する必要があります。
null
にのみ作成している場合、ポストバック時にこのモデルを保持する必要があります。
add()
アクションメソッドでのみ作成される場合です。最も簡単なのは、ビュースコープにビーンを置くことでしょう。また
正しいビーンスコープを選択する方法は?
3. ターゲットに到達できず、'null' が null を返しました。
2.と同じ原因ですが、使用されているELの実装が、例外メッセージに表示するプロパティ名を保存する際に、多少バグがあり、最終的に'null'と誤って表示されてしまいます。このため、次のようなネストしたプロパティがある場合、デバッグや修正が少し難しくなります。
#{bean.entity.subentity.subsubentity.property}
.
解決策はやはり同じで、問題のネストされたエンティティが
null
であることを確認すること、すべてのレベルで
4. ターゲットに到達できず、''0''が null を返しました。
これも2と同じ原因ですが、使用されている(古い)ELの実装が例外メッセージの表現にバグを持っているだけです。これは、中括弧を使った記法の場合にのみ現れます。
[]
のようにELで
#{bean.collection[index]}
ここで
#{bean.collection}
自体は非 NULL ですが、指定されたインデックスの項目は存在しません。このようなメッセージは、その後、次のように解釈されなければなりません。
ターゲットに到達できません。'collection[0]'はnullを返しました。
解決方法も2.と同じで、コレクションアイテムが利用可能であることを確認することです。
5. ターゲットに到達できず、'BracketSuffix' が null を返しました。
これは実は#4と同じ原因ですが、使用されている(古い)ELの実装が例外メッセージに表示する反復インデックスを保存する際に多少バグがあり、最終的に'BracketSuffix'として不正に公開されたもので、実際には文字である
]
. これは、コレクションに複数のアイテムがある場合、デバッグと修正を少し難しくするだけです。
その他の原因として考えられるのは
javax.el.PropertyNotFoundException
:
- javax.el.ELException。com.example.Beanのタイプで'foo'を読み取るエラー
- javax.el.ELException: com.example.Bean クラスで actionMethod プロパティが見つかりませんでした。
- javax.el.PropertyNotFoundException。プロパティ 'foo' が com.example.Bean 型で見つかりませんでした。
- javax.el.PropertyNotFoundException。プロパティ 'foo' は java.lang.Boolean 型で読み取り可能ではありません。
- javax.el.PropertyNotFoundException: プロパティが org.hibernate.collection.internal.PersistentSet タイプで見つかりません。
- アウトコメントされたFaceletsコードは、まだ#{bean.action()}のようなEL式を呼び出し、#{bean.action}でjavax.el.PropertyNotFoundExceptionを発生させています。
関連
-
[解決済み] javax.faces.application.ViewExpiredException: ビューを復元できませんでした
-
[解決済み] <f:facet>は何をするもので、どのような場合に使用するのですか?
-
[解決済み] java.lang.ClassNotFoundException: javax.servlet.jsp.jstl.core.Config [duplicate].
-
[解決済み] p:dashboardが終了してもソート順を維持する。
-
[解決済み] actionとactionListenerの違い
-
[解決済み] ビーンスコープを正しく選ぶには?
-
[解決済み] commandButton/commandLink/ajax アクション/リスナーメソッドが呼び出されないか、入力値が設定/更新されない。
-
[解決済み] Java EE / JSF で j_security_check を使用してユーザー認証を行う。
-
[解決済み] javax.el.PropertyNotFoundException の識別と解決。ターゲットに到達できない
-
[解決済み] h:commandLinkの代わりにh:outputLinkを使うべきですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] JSF 2.2でターゲットが到達できない、識別子がヌルに解決される [重複] 。
-
[解決済み] java.lang.ClassNotFoundException: javax.servlet.jsp.jstl.core.Config [duplicate].
-
[解決済み] javax.validation.ConstraintViolationException
-
[解決済み] commandButton/commandLink/ajax アクション/リスナーメソッドが呼び出されないか、入力値が設定/更新されない。
-
[解決済み】JSFリソースライブラリは何のためにあり、どのように使用すべきですか?
-
[解決済み】JSF 2.0 Faceletsを使用してXHTMLに別のXHTMLを含めるにはどうすればよいですか?
-
[解決済み] JSF2 FaceletsでJSTL...意味があるのか?
-
[解決済み] Java EE / JSF で j_security_check を使用してユーザー認証を行う。
-
[解決済み] divタグをレンダリングできるjsfコンポーネントは何ですか?
-
[解決済み] h:commandLinkの代わりにh:outputLinkを使うべきですか?