1.ターゲットに到達できず、識別子「bean」がnullに解決されました
これは、管理対象 Bean インスタンス自体が EL のような正確な識別子 (管理対象 Bean 名) では見つからなかったことに要約されます#{bean}
。
原因の特定は、次の 3 つのステップに分けることができます。
を。誰がBeanを管理していますか?
b. (デフォルトの) マネージド Bean 名は何ですか?
c. バッキング Bean クラスはどこにありますか?
1a. 誰がBeanを管理していますか?
最初のステップは、Bean インスタンスの管理を担当する Bean 管理フレームワークを確認することです。CDI経由ですか@Named
?それともJSF経由@ManagedBean
ですか?それともSpring経由@Component
ですか?同じバッキング Bean クラスに複数の Bean 管理フレームワーク固有のアノテーションを混在させていないことを確認できますか? 例: @Named @ManagedBean
、@Named @Component
、または@ManagedBean @Component
。これは間違っています。Bean は、最大で 1 つの Bean 管理フレームワークによって管理され、そのフレームワークが適切に構成されている必要があります。どちらを選択すればよいかわからない場合は、バッキング Bean (@ManagedBean) または CDI Bean (@Named)に進んでください。およびSpring JSF統合:Springコンポーネント/サービスをJSFマネージドBeanに注入する方法は?
経由で Bean を管理しているのがCDIである場合@Named
は、次のことを確認する必要があります。
CDI 1.0 (Java EE 6) では、/WEB-INF/beans.xml
WAR で CDI を有効にするためにファイルが必要です。空にすることも、次のコンテンツのみを含めることもできます。
<?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 と同じように動作します。beans.xml
明示的なと互換性のある CDI 1.1 がある場合、デフォルトでは、、、などの明示的な CDI スコープ アノテーションを持つBeanversion="1.1"
のみが登録されます。 CDI スコープは、以下の CDI 1.1 と互換性のあるセットを使用します (デフォルトは です)。@Named
@RequestScoped
@ViewScoped
@SessionScoped
@ApplicationScoped
/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+ を使用する場合は、 CDI スコープ の代わりにbean-discovery-mode="annotated"
などの JSF スコープを誤ってインポートしていないことを確認してください。IDE オートコンプリートに注意してください。javax.faces.bean.RequestScoped
javax.enterprise.context.RequestScoped
Mojarra 2.3.0-2.3.2 と CDI 1.1+ を (デフォルト) で使用する場合、バグbean-discovery-mode="annotated"
により Mojarra を 2.3.3 以降にアップグレードする必要があります。アップグレードできない場合は、 に設定するか、JSF 2.3 固有のアノテーションを WAR の任意のクラス (通常はアプリケーション スコープのスタートアップ クラスのようなもの) に配置する必要があります。bean-discovery-mode="all"
beans.xml
@FacesConfig
JSF 2.3 を Servlet 4.0 コンテナ上で Servlet 4.0 準拠として宣言されている場合、WAR 内の任意のクラス (通常はある種のアプリケーション スコープのスタートアップ クラス) にweb.xml
JSF 2.3 固有のアノテーションを明示的に配置する必要があります。@FacesConfig
これは、Servlet 3.x では必要ありません。
javax.*
パッケージの名前が からに変更された最初のバージョンである CDI 3.0 を使用する場合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 をボックスにバンドルしている場合は、webapp に沿って別の CDI または Java EE API JAR ファイルを提供しないようにしてください。
JSF ビューの CDI マネージド Bean を JAR にパッケージ化する場合は、JAR に少なくとも有効な/META-INF/beans.xml
(空にしておくことができる) があることを確認してください。
since 2.3 deprecated を介して Bean を管理しているのがJSF@ManagedBean
であり、CDI に移行できない場合は、次のことを確認する必要があります。
ルートfaces-config.xml
宣言は JSF 2.0 と互換性があります。そのため、XSD ファイルと は少なくともJSF 2.0 以上を指定する必要があるため、1.x ではありませんversion
。
<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 の場合は、and をそれぞれ2_0
andに置き換えるだけです。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 の場合は、and をそれぞれ2_2
andに置き換えるだけです。2.2
2_3
2.3
javax.annotation.ManagedBean
の代わりに誤ってインポートしたわけではありませんjavax.faces.bean.ManagedBean
。IDE オートコンプリートに注意してください。Eclipse は、リストの最初の項目として間違ったものを自動提案することが知られています。
まったく同じバッキング Bean クラスで、別のマネージド Bean 名とともに@ManagedBean
JSF 1.x スタイル<managed-bean>
エントリによって をオーバーライドしませんでした。faces-config.xml
これは よりも優先され@ManagedBean
ます。JSF 2.0 以降、マネージド Bean を登録するfaces-config.xml
必要はありません。削除するだけです。
実行時クラスパスがクリーンで、JSF API 関連の JAR に重複がありません。複数の JSF 実装 (Mojarra と MyFaces) を混在させていないことを確認してください。ターゲットコンテナがすでに JSF API をそのままバンドルしている場合は、webapp に沿って別の JSF や Java EE API JAR ファイルを提供しないようにしてください。JSF のインストール手順については、JSF wiki ページの「JSF のインストール」セクションも参照してください。コンテナー自体ではなく、WAR からコンテナーにバンドルされた JSF をアップグレードする場合は、WAR にバンドルされた JSF API/impl を使用するようにターゲット コンテナーに指示したことを確認してください。
JSF マネージド Bean を JAR にパッケージ化する場合は、JAR に少なくとも JSF 2.0 と互換性のある/META-INF/faces-config.xml
. JAR ファイルで提供される JSF 管理対象 Bean を参照する方法も参照してください。
実際にjurassic JSF 1.x を使用していて、アップグレードできない場合は、ではなく<managed-bean>
inを介して Bean を登録する必要があります。プロジェクトのビルド パスを、JSF 2.x ライブラリがなくなるように修正することを忘れないでください (注釈が混乱して正常にコンパイルされないようにするため)。faces-config.xml
@ManagedBean
@ManagedBean
を介して Bean を管理しているのがSpringの場合@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 構成に関連する問題などです)
属性 (例: 、、など) を介して (ネストされた) Bean を管理しているリピーター コンポーネントであり、実際に「ターゲットに到達できません。識別子 'item' が null に解決されました」というメッセージが表示された場合は、次のことを確認する必要があります。 :var
<h:dataTable var="item">
<ui:repeat var="item">
<p:tabView var="item">
1b. (デフォルトの) マネージド Bean 名は何ですか?
2 番目のステップは、登録されたマネージド Bean 名を確認することです。JSF と Spring の使用規則はJavaBeans 仕様に準拠していますが、CDI には CDI の実装/バージョンに応じた例外があります。
以下のようなFooBean
バッキング Bean クラス、
@Named
public class FooBean {}
すべての Bean 管理フレームワークで#{fooBean}
、JavaBeans 仕様に従って、デフォルトのマネージド Bean 名は になります。
以下のようなFOOBean
バッキング Bean クラス、
@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) には当てはまりません。 CDIスペック。これらの Weld バージョンおよびすべての OWB バージョンでは、最初の文字のみが小文字になってい#{fOOBean}
ます。
foo
以下のようにマネージドBean名を明示的に指定した場合、
@Named("foo")
public class FooBean {}
または同等に@ManagedBean(name="foo")
orの場合@Component("foo")
、それは によってのみ利用可能に#{foo}
なり、 によっては利用できなく#{fooBean}
なります。
1c。バッキング Bean クラスはどこにありますか?
3 番目のステップは、バッキング Bean クラスがビルドおよびデプロイされた WAR ファイル内の適切な場所にあるかどうかを再確認することです。コードを書いたりブラウザで焦って F5 キーを押したりするのに忙しい場合に備えて、プロジェクトとサーバーの完全なクリーン、再構築、再デプロイ、再起動を適切に実行したことを確認してください。それでもうまくいかない場合は、ビルド システムに WAR ファイルを生成させ、ZIP ツールで抽出して検査します。.class
バッキング Bean クラスのコンパイル済みファイルは、.xml のパッケージ構造に存在する必要があります/WEB-INF/classes
。または、JAR モジュールの一部としてパッケージ化されている場合、コンパイルされた.class
ファイルを含む JAR は、 /WEB-INF/lib
EAR/lib
やその他の場所に存在する必要はありません。
Eclipse を使用している場合は、バッキング Bean クラスが にあることsrc
を確認し、[プロジェクト] > [自動ビルド]が有効になっていることを確認します。Maven を使用している場合は、バッキング Bean クラスが にあり、またはにないことを確認してください。 WebContent
src/main/java
src/main/resources
src/main/webapp
EJB+WAR を使用して Web アプリケーションを EAR の一部としてパッケージ化する場合は、バッキング Bean クラスが WAR モジュールにあり、EAR モジュールでも EJB モジュールでもないことを確認する必要があります。ビジネス層 (EJB) には Web 層 (WAR) 関連のアーティファクトがないようにする必要があります。これにより、ビジネス層は複数の異なる Web 層 (JSF、JAX-RS、JSP/サーブレットなど) で再利用できます。
2.ターゲットに到達できません、「エンティティ」はnullを返しました
これは、返されるようにネストされたプロパティに要約されます。これは通常、JSF が以下のような入力コンポーネントを介して値を設定する必要がある場合にのみ公開されますが、実際には.entity
#{bean.entity.property}
null
property
#{bean.entity}
null
<h:inputText value="#{bean.entity.property}" />
同じビューで CRUD リストやダイアログを操作している場合は、 、 メソッド、またはおそらくアクション メソッドで@PostConstruct
モデル<f:viewAction>
エンティティを事前に準備しておく必要があります。add()
@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
; CDI などのプロキシを使用する Bean 管理フレームワークを使用している場合、通常のコンストラクターでこれを行うと失敗します。@PostConstruct
マネージド Bean インスタンスの初期化をフックするために常に使用します (@PreDestroy
マネージド Bean インスタンスの破棄をフックするために使用します)。さらに、コンストラクターでは、注入された依存関係にまだアクセスできません。コンストラクターで @Inject Bean にアクセスしようとしているときに NullPointerExceptionも参照してください。
entityId
が 経由で提供される場合は、 の代わりに<f:viewParam>
を使用する必要があります。f:viewAction / preRenderView と PostConstruct をいつ使用するかを参照してください。<f:viewAction>
@PostConstruct
また、アクション メソッドnull
でのみ作成する場合に備えて、ポストバック中に非モデルを保持することを確認する必要があります。add()
最も簡単なのは、Bean をビュー スコープに配置することです。適切な Bean スコープを選択する方法も参照してください。
3.ターゲットに到達できません、「null」はnullを返しました
これは実際には #2 と同じ原因があります。使用されている (古い) EL 実装のみが、例外メッセージに表示するプロパティ名を保持する際にややバグがあり、最終的に「null」として誤って公開されます。so のようにネストされたプロパティがかなりある場合、これはデバッグと修正を少し難しくするだけです#{bean.entity.subentity.subsubentity.property}
。
問題のネストされたエンティティがnull
すべてのレベルで , でないことを確認してください。
4. ターゲットに到達できません。''0'' が null を返しました
これも #2 と同じ原因で、使用されている (古い) EL 実装のみが例外メッセージの作成にバグがあります。これは、それ自体が非 null である場合の[]
ように、EL でブレース表記を使用する場合にのみ公開されますが、指定されたインデックスの項目は存在しません。このようなメッセージは、次のように解釈する必要があります。#{bean.collection[index]}
#{bean.collection}
ターゲットに到達できません。'collection[0]' が null を返しました
解決策も #2 と同じです: コレクション アイテムが利用可能であることを確認します。
5.ターゲットに到達できません、「BracketSuffix」はnullを返しました
これは実際には #4 と同じ原因があります。使用されている (古い) EL 実装のみが、反復インデックスを保持して例外メッセージに表示する際に多少バグがあり、最終的に実際には文字である 'BracketSuffix' として誤って公開されます]
。これは、コレクションに複数のアイテムがある場合に、デバッグと修正を少し難しくするだけです。
その他の考えられる原因javax.el.PropertyNotFoundException
: