1.ターゲット到達不能、識別子「bean」がnullに解決されました
つまり、マネージドBeanのインスタンス自体は、EL内のその識別子(マネージドBean名)からは正確に見つかりませんでした#{bean}
。
原因の特定は、3つのステップに分類できます。
a。誰が豆を管理していますか?
b。(デフォルトの)管理Bean名は何ですか?
c。バッキングBeanクラスはどこにありますか?
1a。誰が豆を管理していますか?
最初のステップは、Beanインスタンスの管理を担当するBean管理フレームワークを確認することです。それはJSFを経由して@ManagedBean
?それともCDI経由@Named
ですか?それともSpring via @Component
ですか?同じバッキングBeanクラスに複数のBean管理フレームワーク固有のアノテーションが混在していないことを確認できますか?たとえば@Named @Component
、または@Named @ManagedBean
、または@ManagedBean @Component
。これは間違っています。Beanは最大で1つのBean管理フレームワークで管理する必要があり、そのフレームワークは適切に構成する必要があります。どちらを選択すればよいかわからない場合は、バッキングBean(@ManagedBean)またはCDI Bean(@Named)に進んでください。とSpring JSFの統合:JSFマネージドBeanにSpringコンポーネント/サービスを注入する方法
場合には、それはだJSFを経由してBeanを管理しています@ManagedBean
、あなたは以下の点を確認してくださいする必要があります。
faces-config.xml
ルート宣言はJSF 2.0と互換性があります。したがって、XSDファイルとでversion
は、少なくとも JSF 2.0 以上を指定する必要があり、したがって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">
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は、リストの最初の項目として間違ったものを自動提案することが知られています。
- 異なるマネージドBean名とともに、非常に同じバッキングBeanクラスで
@ManagedBean
JSF 1.xスタイルの<managed-bean>
エントリをオーバーライドしませんでしたfaces-config.xml
。これはに優先し@ManagedBean
ます。faces-config.xml
JSF 2.0以降、マネージドBeanを登録する必要はありません。削除するだけです。
- ランタイムクラスパスはクリーンで、JSF API関連のJARに重複がありません。複数のJSF実装(MojarraとMyFaces)が混在していないことを確認してください。ターゲットコンテナがすでにJSF APIをバンドルしている場合は、webappに沿って別のJSFまたはJava EE API JARファイルを提供しないようにしてください。JSF wikiページの「JSFのインストール」セクションも参照してください。JSFのインストール手順について。コンテナー自体ではなくWARからコンテナーバンドルJSFをアップグレードする場合は、WARバンドルJSF API / implを使用するようにターゲットコンテナーに指示したことを確認してください。
- JSF管理BeanをJARにパッケージ化する場合は、JARに少なくともJSF 2.0互換性があることを確認して
/META-INF/faces-config.xml
ください。JARファイルで提供されるJSF管理対象Beanを参照する方法も参照してください。
あなたがしている場合、実際にジュラシックJSF 1.xのを使用して、アップグレードすることはできません、あなたは経由でBeanを登録する必要が<managed-bean>
でfaces-config.xml
はなく、@ManagedBean
。JSF 2.xライブラリがもうないようにプロジェクトのビルドパスを修正することを忘れないでください(@ManagedBean
アノテーションが混乱して正常にコンパイルされないようにするため)。
を介して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と同じように動作します。CDI 1.1の互換性があります場合はbeans.xml
、明示的でversion="1.1"
、それはデフォルトでのみ登録する@Named
豆をしてこのような明示的なCDIスコープ注釈@RequestScoped
、@ViewScoped
、@SessionScoped
、@ApplicationScoped
、などの場合は、あなたも、これらの明示的に使われていない、CDI管理対象BeanをとしてすべてのBeanを登録しようとします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>
bean-discovery-mode="annotated"
(デフォルト)でCDI 1.1+を使用する場合javax.faces.bean.RequestScoped
は、CDIスコープではなくJSFスコープなどを誤ってインポートしていないことを確認してください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
、で設定するか、またはJSF 2.3固有の@FacesConfig
アノテーションをWARの任意のクラス(通常、ある種のアプリケーションスコープの起動クラス)に配置する必要があります。
- TomcatやJettyなどの非Java EEコンテナーには、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
(空のままにしておくことができる)ことを確認してください。
を介して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構成関連のトラブルなど)
場合には、それはだRepeaterコンポーネントの経由(ネストされた)豆を管理していますvar
(例:属性<h:dataTable var="item">
、<ui:repeat var="item">
、<p:tabView var="item">
、など)や、あなたが実際に得た「目標到達不能は、識別子『アイテム』 nullに解決」、あなたは以下のことを確認する必要があります:
1b。(デフォルトの)管理対象Beanの名前は何ですか?
次に、登録されている管理対象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月以前にリリースされた溶接のバージョンではなく、2015年6月以降に発売溶接のバージョン(2.2.14 / 2.3.0.B1 / 3.0.0.A9)にもOpenWebBeansでも同様ですにおける監督CDI仕様。これらのWeldバージョンおよびすべてのOWBバージョンでは、最初の文字のみが小文字になり#{fOOBean}
ます。
foo
以下のようなマネージドBean名を明示的に指定した場合、
@Named("foo")
public class FooBean {}
または同等にと@ManagedBean(name="foo")
か@Component("foo")
、それが唯一で利用できるようになります#{foo}
ので、ないことで#{fooBean}
。
1c。バッキングBeanクラスはどこにありますか?
3番目のステップは、バッキングBeanクラスがビルドおよびデプロイされたWARファイルの適切な場所にあるかどうかをダブルチェックすることです。実際にコードを書き、ブラウザでF5キーを押すのが忙しい場合に備えて、プロジェクトとサーバーの完全なクリーン、再構築、再デプロイ、再起動を適切に実行したことを確認してください。それでも無駄な場合は、ビルドシステムにWARファイルを生成させます。WARファイルは、ZIPツールで抽出して検査します。.class
バッキングBeanクラスのコンパイル済みファイルは、のパッケージ構造に存在する必要があります/WEB-INF/classes
。または、JARモジュールの一部としてパッケージ化されている場合、コンパイルされた.class
ファイルを含むJARは、/WEB-INF/lib
たとえばEAR /lib
や他の場所に存在していてはならず、存在する必要があります。
Eclipseを使用している場合、バッキングBeanのクラスが含まれていることを確認しますsrc
ので、やない WebContent
、とことを確認するプロジェクト>ビルドが自動的に有効になります。あなたはMavenを使用している場合は、バッキングBeanのクラスが含まれていることを確認しますsrc/main/java
ので、およびないでsrc/main/resources
かsrc/main/webapp
。
EJB + WARを持つEARの一部としてWebアプリケーションをパッケージ化する場合、バッキングBeanクラスがWARモジュールにあり、したがってEARモジュールにもEJBモジュールにもないことを確認する必要があります。ビジネス層(EJB)には、Web層(WAR)関連のアーティファクトがないようにする必要があります。これにより、ビジネス層は、複数の異なるWeb層(JSF、JAX-RS、JSP /サーブレットなど)で再利用できます。
2.ターゲット到達不能、「エンティティ」がnullを返しました
これは、ネストされたプロパティentity
が#{bean.entity.property}
返された場合と同じnull
です。これは通常、JSFが以下のような入力コンポーネントを介して値を設定する必要がある場合にのみ公開されますが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」として公開されます。これにより、ネストされたプロパティがかなりある場合にのみ、デバッグと修正が少し難しくなります#{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
: