[UPDATE: Nach der Diskussion über die Glassfish-Foren/ML bei http://forums.java.net/jive/thread.jspa?messageID=480532 ein Bug eingereicht wurde gegen Glassfish https://glassfish.dev.java.net/issues/show_bug.cgi?id=13040 Für dieses Problem.]"Kann ejbRef für ejb konvertieren" auf CDI (Weld) Injektion von @Stateless EJB in @SessionScoped JSF2 Bohne in Glassfish
Ich versuche, eine lokale No-Interface-Ansicht eines @Stateless EJB in eine JSF2 @ Named @ javax.enterprise.context.SessionScoped-Backing-Bean zu injizieren. Das EJB ist eines von mehreren, die eine abstrakte generische Basisklasse erweitern. Die Injektion von "@Inject TheEJBClass varName" schlägt fehl mit "Konnte ejbRef für ejb TheEJBClass nicht in ein Geschäftsobjekt vom Typ" my.package.name.TheAbstractBase "konvertieren. [Bearbeiten: Es stellt sich tatsächlich heraus, dass die Injektion erfolgreich ist, aber die Methodenauflösung im injizierten Proxy für von Superklassen geerbte Methoden fehlschlägt.] Wenn ich "@EJB TheEJBClass varName" verwende, bleibt varName null, dh es wird nichts injiziert.
Details:
ich Glassfish 3.0.1 auf Linux (Ubuntu 10.04, falls es wichtig ist) und mit meiner Datenmodell Injektion von EJBs in meine JSF2 Sitzung reale Probleme bei der Ausführung der Handhabung scoped Modelle mit CDI (Weld) . Und ja, bevor Sie fragen, ich habe beans.xml an Ort und Stelle und CDI aktiviert, um die Injektion durchzuführen.
Wenn ich es mit einem @EJB Anmerkung injizieren, zum Beispiel:
@EJB TheEJBClass memberName;
... ist die EJB nicht tatsächlich injiziert, member null zu verlassen.
Wenn ich es mit einem CDI @Inject Anmerkung injizieren:
@Inject TheEJBClass memberName;
... dann CDI beschwert, wenn ich eine Methode der „Mitgliedsname“ aufrufen, die in TheEJBClass in einer übergeordneten Klasse von TheEJBClass und nicht außer Kraft gesetzt implementiert hat seine selbst, Berichterstattung:
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)
....
ich die Basis für konkrete Klasse Umwandlung versucht habe und de-generifying, aber das gleiche Problem auftreten, so dass ich glaube nicht, dass ich die Weld Bugs mit generischer Base bin schlagen (https://jira.jboss.org/browse/WELD-305, https://jira.jboss.org/browse/WELD-381, https://jira.jboss.org/browse/WELD-518).
den Umriss des Codes, mit vollem Paket Qualifikation auf Anmerkungen zur Klarheit hinzugefügt ist:
// 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;
}
}
Hinweis, dass die Injektion tut Arbeit, wenn ich TheAbstractBase.getValue() in TheEJBClass außer Kraft setzen, oder wenn ich Rufen Sie eine Methode auf, die in TheEJBClass definiert ist, und keine Superklasse. Es scheint, dass das Problem etwas mit Vererbung zu tun hat.
Sehr ähnlicher Code, der die eingebauten Lifecycle- und Injection-Funktionen von JSF2 nutzte, aber da es sich um ein neues Projekt handelt und CDI in der Zukunft liegt, dachte ich, dass es am besten ist, CDI zu verwenden. Hier ist, was ich begann mit der Verwendung von JSF2/EJB-Injektion, die gearbeitet:
// 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;
}
}
arbeite ich zur Zeit auf die Zusammenstellung eines in sich geschlossenen Testfall, dachte aber, ich die Frage jetzt im Fall abfeuern würde dieses ist etwas, wo ich nur etwas albernes mache oder es gibt eine bekannte Lösung, die mein Google-Fu nicht finden kann. Warum hat es mit JSF2/EJB-Injektion funktioniert, aber mit CDI-Injektion fehlgeschlagen?
(Da-re geschrieben auf den Glassfish-Foren als http://forums.java.net/jive/thread.jspa?threadID=152567)
Ich habe einen Testfall erstellt, der dieses Problem veranschaulicht. Es scheint so, als ob der von CDI generierte JavaAssist-Wrapper Verweise auf Methoden, die in Superklassen definiert sind, auflöst. Das Problem liegt nicht in der Injektionszeit, sondern zu dem Zeitpunkt, zu dem eine von einer Oberklasse geerbte Methode über den injizierten Wrapper aufgerufen wird. Die Verwendung von JSF2 oder CDI Namen und Umfang hat nichts damit zu tun, es ist nur @EJB vs @Inject Siehe Kommentare und Beispiele in: http://www.postnewspapers.com.au/~craig/public_files_keep/ ErrorDemo.zip (src) und http://www.postnewspapers.com.au/~craig/public_files_keep/ErrorDemo.war (webapp). –
... und für Bonus-Schmerzen ist das Problem in JBoss AS 6 ziemlich umgekehrt. Die CDI-Injektion funktioniert gut, aber die JSF2-Injektion schlägt fehl. –