CDI(溶接)の「EJBREFをEJBREFに変換できません」@SessionsCoped JSF2 Beanの@SessionsCoped JSF2 Beanへの注入
-
29-09-2019 - |
質問
[アップデート: :Glassfishフォーラム/mlでの議論の後 http://forums.java.net/jive/thread.jspa?messageid=480532 ガラスフィッシュに対してバグが提出されました https://glassfish.dev.java.net/issues/show_bug.cgi?id=13040 この問題のために。
@Stateless EJBのローカルノーインターフェイスビューをJSF2 @NAMED @javax.enterprise.context.sessionscoped beanに注入しようとしています。 EJBは、抽象的な汎用ベースクラスを拡張するいくつかの1つです。 「@Inject theejbclass varname」の注入は、「ejbrefをejb theejbclassの型型クラスmy.package.name.theabstractbaseのビジネスオブジェクトに変換することができない」で失敗します。 編集:実際、注入は成功しますが、スーパークラスから継承されたメソッドの注入プロキシのメソッド解像度は失敗します。 「@ejb theejbclass varname」を使用すると、varnameはnullのままです。つまり、注入されません。
詳細:
LinuxでGlassfish 3.0.1を実行しています(Ubuntu 10.04が重要な場合)、CDI(WELD)を使用してJSF2セッションスコープモデルにデータモデルEJBのインジェクションを処理するのに実際の問題があります。そして、はい、あなたが尋ねる前に、私はbeans.xmlを所定の位置に置いており、CDIがアクティブになってインジェクションを実行しています。
@EJBアノテーションで注入する場合、例:
@EJB TheEJBClass memberName;
... EJBは実際には注入されておらず、メンバー名Nullを残します。
CDI @Injectアノテーションで注入する場合:
@Inject TheEJBClass memberName;
...それから、CDIは、Theejbclassのスーパークラスで実装されており、その自己を無効にしていない「MemberName」の方法を呼び出すと不満を言います。
java.lang.IllegalStateException: Unable to convert ejbRef for ejb TheEJBClass to a business object of type class my.package.name.TheAbstractBase
at
com.sun.ejb.containers.EjbContainerServicesImpl.getBusinessObject(EjbContainerServicesImpl.java:104)
at
org.glassfish.weld.ejb.SessionObjectReferenceImpl.getBusinessObject(SessionObjectReferenceImpl.java:60)
....
ベースをコンクリートクラスに変換して生成しようとしましたが、同じ問題に遭遇したので、溶接バグを汎用的なベースで打つとは思いません(https://jira.jboss.org/browse/weld-305, https://jira.jboss.org/browse/weld-381, https://jira.jboss.org/browse/weld-518).
明確に追加された注釈の完全なパッケージの資格を備えたコードの概要は次のとおりです。
// JSF2 managed backing bean.
//
// Called via #{someJSF2Model.value} in a JSF2 page
//
@javax.inject.Named
@javax.enterprise.context.SessionScoped
public class SomeJSF2Model implements Serializable {
@javax.inject.Inject TheEJBClass member;
public Integer getValue() {
return member.getValue();
}
// blah blah
}
// One of several EJB classes that extend TheAbstractBase
@javax.ejb.Stateless
public class TheEJBClass extends TheAbstractBase {
// blah blah
// does **NOT** override "getValue()"
}
public abstract class TheAbstractBase {
// blah blah
public Integer getValue() {
return 1;
}
}
注射に注意してください します Theabclassのtheabstractbase.getValue()をオーバーライドした場合、またはスーパークラスではなくejbclassで定義されたメソッドを呼び出す場合。問題は相続と関係があるようです。
JSF2の組み込みライフサイクルとインジェクション機能を使用した非常によく似たコードは機能しましたが、これが新しいプロジェクトであり、CDIが将来物事が向かっている場所であることを考えると、CDIを選ぶのが最善だと思いました。 JSF2/EJBインジェクションを使用して始めたものは次のとおりです。
// JSF2 managed backing bean. Using @ManagedBean and JSF2's @SessionScoped
// instead of CDI @Named and CDI @SessionScoped this time.
//
@javax.faces.bean.ManagedBean
@javax.faces.bean.SessionScoped
public class SomeJSF2Model implements Serializable {
@javax.ejb.EJB TheEJBClass member;
public Integer getValue() {
return member.getValue();
}
// blah blah
}
// One of several EJB classes that extend TheAbstractBase
// Unchanged from CDI version
@javax.ejb.Stateless
public class TheEJBClass extends TheAbstractBase {
// blah blah
// does **NOT** override "getValue()"
}
// Unchanged from CDI version
public abstract class TheAbstractBase {
// blah blah
public Integer getValue() {
return 1;
}
}
私は現在、自己完結型のテストケースをまとめることに取り組んでいますが、これが私がただ愚かなことをしていることや、よく知られているソリューションがある場合、私のGoogle-Fu isn 'nn' nn」の場合に備えて、私は今私が質問を解雇すると思いました。見つけるために。なぜJSF2/EJB注射で動作したのに、CDI注射で失敗したのですか?
(Glassfishフォーラムで再投稿されているため http://forums.java.net/jive/thread.jspa?threadid=152567 )
解決
上記のように、それは溶接/グラスフィッシュのバグです。
修正:Glassfishをあきらめ、Jbossに移動します。これは実際にほとんど動作します。