138

SO のように EL でマネージド Bean を参照しようとすると、通常は Bean プロパティが設定されるとき、または Bean アクションが呼び出されるときに、例外がスローされることがあります#{bean.entity.property}javax.el.PropertyNotFoundException: Target Unreachable

次の 5 種類のメッセージがあるようです。

  1. ターゲットに到達できません。識別子 'bean' が null に解決されました
  2. ターゲットに到達できません。'entity' が null を返しました
  3. ターゲットに到達できません。「null」は null を返しました
  4. ターゲットに到達できません。''0'' が null を返しました
  5. ターゲットに到達できません。'BracketSuffix' が null を返しました

それらはすべてどういう意味ですか? それらはどのように発生し、どのように解決する必要がありますか?

4

18 に答える 18

261

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.xmlWAR で 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.xmlbean-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.RequestScopedjavax.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.xmlJSF 2.3 固有のアノテーションを明示的に配置する必要があります。@FacesConfigこれは、Servlet 3.x では必要ありません。

  • javax.*パッケージの名前が からに変更された最初のバージョンである CDI 3.0 を使用する場合jakarta.*、すべてのデプロイメント記述子ファイルbeans.xmlweb.xmlfaces-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_0andに置き換えるだけです。2.02_12.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_2andに置き換えるだけです。2.22_32.3

  • javax.annotation.ManagedBeanの代わりに誤ってインポートしたわけではありませんjavax.faces.bean.ManagedBean。IDE オートコンプリートに注意してください。Eclipse は、リストの最初の項目として間違ったものを自動提案することが知られています。

  • まったく同じバッキング Bean クラスで、別のマネージド Bean 名とともに@ManagedBeanJSF 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">

  • は、どの子コンポーネントの属性でも#{item}参照されていません。ビューのレンダリング時ではなく、ビューのビルド時に属性が実行さbindingれるため、これは正しくありません。bindingさらに、コンポーネント ツリーには物理的に 1 つのコンポーネントしかなく、各反復ラウンドで単純に再利用されます。つまり、実際にはbinding="#{bean.component}"の代わりにを使用する必要がありbinding="#{item.component}"ます。しかし、はるかに良いのは、Bean へのコンポーネントの結合を完全に取り除き、この方法で解決しようと考えた問題に対する適切なアプローチを調査/質問することです。「バインディング」属性は JSF でどのように機能しますか?も参照してください。いつ、どのように使用する必要がありますか?


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/libEAR/libやその他の場所に存在する必要はありません。

Eclipse を使用している場合は、バッキング Bean クラスが にあることsrcを確認し、[プロジェクト] > [自動ビルド]が有効になっていることを確認します。Maven を使用している場合は、バッキング Bean クラスが にあり、またはにないことを確認してください。 WebContentsrc/main/javasrc/main/resourcessrc/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}nullproperty#{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:

于 2015-05-08T16:15:02.090 に答える
7

まだ行き詰まっている人のために...

CDI で NetBeans 8.1 および GlassFish 4.1 を使用すると、何らかの理由で、リモート サーバーではなくローカルでのみこの問題が発生しました。トリックは何をしましたか:

-> NetBeans が提供するデフォルトの pom バージョンである javaee-web-api 6.0 の代わりに、javaee-web-api 7.0 を使用します。

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-web-api</artifactId>
    <version>7.0</version>
    <scope>provided</scope>
    <type>jar</type>
</dependency>

-> この javaee-web-api-7.0.jar を lib としてサーバー (domain1 フォルダー内の lib フォルダー) にアップロードし、サーバーを再起動します。

于 2016-02-04T00:08:51.030 に答える
1

Mojarra 2.3 https://github.com/eclipse-ee4j/mojarra/issues/4734のバグである可能性もあります

于 2020-10-17T17:42:40.853 に答える
0

私の場合の問題は、パラメーターを受け取るコンストラクターを含めましたが、Inject アノテーションを使用して空のコンストラクターを含めなかったことです。

@Inject public VisitorBean() {}

コンストラクターなしでテストしたところ、これも機能するようです。

于 2019-02-26T20:12:38.550 に答える
0

1. トピック (ターゲット到達不能、識別子 'bean' が null に解決);

@BalusCと他の共有者の貴重な回答を確認しましたが、私のシナリオではこの問題を超えています。別の名前で新しい xhtml を作成し、別の名前で Bean クラスを作成した後、新しい Bean クラスと新しい xhtml ファイルにコードを段階的に (コピーアンドペーストではなく) 書きました。

于 2019-05-30T10:27:21.527 に答える
-1

古いスタイルでの JSF の操作 次のように、 beans-config.xmlファイル (WEB-INF フォルダーにある) でマネージド Bean を定義し、web.xmlファイルでそれへの参照を作成する必要があります。

beans-config.xml

<managed-bean>
  <managed-bean-name>"the name by wich your backing bean will be referenced"</managed-bean-name>
  <managed-bean-class>"your backing bean fully qualified class name"</managed-bean-class>
  <managed-bean-scope>session</managed-bean-scope>    
</managed-bean>

(他のスコープも使ってみましたが・・・)

web.xml

<context-param>
  <param-name>javax.faces.CONFIG_FILES</param-name>
  <param-value>"/WEB-INF/beans-config.xml</param-value>
</context-param>
于 2016-10-11T17:39:16.857 に答える
-2

別の手がかり: 私は JSF を使用していて、mvn 依存関係を追加しました: com.sun.faces jsf-api 2.2.11

    <dependency>
        <groupId>com.sun.faces</groupId>
        <artifactId>jsf-impl</artifactId>
        <version>2.2.11</version>
    </dependency>

次に、Primefaces に変更して、primefaces の依存関係を追加しようとしました。

<dependency>
    <groupId>org.primefaces</groupId>
    <artifactId>primefaces</artifactId>
    <version>6.0</version>
</dependency>

xhtml を h: から p: に変更し、xmlns:p="http://primefaces.org/ui をテンプレートに追加しました。JSF のみで、プロジェクトは正常に実行され、マネージド Bean は正常に到達しました。Primefaces を追加すると、到達不能なオブジェクト (javax.el.propertynotfoundexception) を取得していました.問題は、JSF が Primefaces ではなく ManagedBean を生成していたことでした.私はオブジェクトに対して primefaces を要求していました.私は.pom から jsf-impl を削除しなければなりませんでした.プロジェクトをインストールします。この時点からすべて問題ありませんでした。お役に立てば幸いです。

于 2016-11-15T08:06:01.630 に答える