あなたが説明している構造では、目的の注射を得る方法はありません。
EJB クラスローダは WAR 内のクラスにアクセスできないため、インジェクションは代替実装を考慮しません。
EAR 構造を変更し、別の (D) を lib/jar に apppropriare と共に配置する場合は、解決策が可能ですbeans.xml
。D クラスが EJB および WAR から見えるようになり、注入は必要に応じて行われます。
編集
あなたが投稿したソリューションは、私がここで説明していますが、ほとんど機能しています。
EAR
- ejb-module-1.jar
- A.class (@Inject I)
- I.class
- C.class (@Stateless implements I)
- META-INF/beans.xml
- ejb-module-2.jar
- D.class (@Alternative @Stateless implements I)
- META-INF/beans.xml (<alternatives><class>D</class></alternative>)
- app.war
- calls A.test()
- WEB-INF/beans.xml
beans.xml
唯一の問題は、 alternative 宣言の場所を間違えたことです。
CDI 仕様 (1.1、ただし以前の実装にも適用可能) の第 5.1 章では、次のように述べられています。
モジュールが Bean アーカイブであり、代替がその Bean アーカイブで明示的に選択されていない限り、モジュール内のクラスまたは JSP/JSF ページへのインジェクション、ルックアップ、または EL 解決に代替は使用できません。
つまり、 bean を使用するクラスの同じモジュールで代替を選択する必要があります。
改訂された(そして作業中の)構造は次のとおりです。
EAR
- ejb-module-1.jar
- A.class (@Inject I)
- I.class
- C.class (@Stateless implements I)
- META-INF/beans.xml (<alternatives><class>D</class></alternative>)
- ejb-module-2.jar
- D.class (@Alternative @Stateless implements I)
- META-INF/beans.xml (empty <beans></beans>)
- app.war
- calls A.test()
- WEB-INF/beans.xml (empty <beans></beans>)
また、標準の Bean の場合、代替の選択は のモジュールに対してのみ機能しますが、代替は で宣言されbeans.xml
ますが、EJB には同じことは当てはまりません。したがって、D
代替案 (being @Stateless
) はアプリケーション全体で有効です。