2014-10-20 13 views
7

Mit Wildfly 8.1 Ich habe mehrere Bohnen, die ich versuche, mehrere EJB ineinander zu injizieren. Sagen wir, ich habe 3 Bohnen:Warum statusfreie Beans als Pseudo-Scoped behandelt werden und keine zirkulären Abhängigkeiten haben können?

@Stateless 
public class A{ 
    @Inject 
    private B b; 
} 

@Stateless 
public class B{ 
    @Inject 
    private C c; 
} 

@Stateless 
public class C{ 
    @Inject 
    private A a; 
} 

Offensichtlich habe ich kreisförmige Abhängigkeit. Laut Spezifikation:

Der Behälter ist erforderlich Zirkularitäten in den Bohne Abhängigkeitsgraphen, wobei mindestens eine bean teilnehmenden in jeder Kreis Kette von Abhängigkeiten hat einen normalen Umfang

Lauf obigen Code zu unterstützen, Behälter resultiert in einem Fehler der Form:

org.jboss.weld.exceptions.DeploymentException: WELD-001.443: Pseudo scoped bean zirkuläre Abhängigkeiten hat. Abhängigkeitspfad:

-Session Bean [Klasse A mit Qualifier [@Default @Any]; lokale Schnittstellen sind [A] BackedAnnotatedField] @Inject Privat B,

[..]

Meine Frage ist: Was ist der Umfang der @Stateless Bohnen? Ist es standardmäßig @ Dependent? Und vor allem, wie kann ich zirkuläre Abhängigkeiten zwischen Stateless Session Beans aktivieren?

Sorry, wenn die Frage zu trivial ist. Ich werde alle guten weiterführenden Quellen schätzen, die das vorgestellte Verhalten erklären werden. Danke im Voraus.

AKTUALISIERT Ok. Ich habe die Problemumgehung gefunden. Ich habe @EJB Annotation anstelle von @Inject verwendet, aber dies erklärt nicht das seltsame Verhalten von @Inject. Die Frage bleibt offen, aber wie Mika vorgeschlagen hat, könnte es ein ungelöstes Problem sowohl in der CDI-Spezifikation als auch in Weld RI sein.

+0

ich keine Antwort haben, aber es ist keine triviale Frage. Es gab eine Diskussion darüber zwischen den CDI-Mitgliedern. Schauen Sie sich die CDI spec jira an, es sollte ein Problem zu diesem Thema geben. –

+0

@MikeBraun Könnten Sie vielleicht einen Link zum Jira-Problem geben? Ich habe gesucht, aber ich bin mir nicht sicher, ob ich auf die richtige suche. – iku

+0

ist es CDI-414, siehe https://issues.jboss.org/browse/CDI-414 –

Antwort

9

Es ist ein Fehler in wildfly/jboss CDI-Implementierung. Die aktuelle Problemumgehung (wie von @MikeBraun vorgeschlagen) in der Problembeschreibung https://issues.jboss.org/browse/CDI-414 ist die Verwendung der @ EJB-Annotation anstelle von @Inject.

3

@Stateless hat keinen Anwendungsbereich und hat keine Korrelation zu einem Bereich. Ihre Beans enden als @Dependent, da Sie keinen anderen Bereich auf Ihren Beans annotiert haben.

Sie müssen ihnen einen normalen Bereich geben - @RequestScoped oder @ApplicationScoped, aber ich bin mir nicht sicher, ob beides in Ihrem Fall sinnvoll ist.

+0

Ihre Lösung ist nur gültig, wenn sie innerhalb der Web-Schicht verwaltet wurde. Wie es EJB Bean ist, ist es eher ein Fehler innerhalb der CDI-Implementierung. – iku

+0

Dem stimme ich nicht zu. Scoping Stateless macht hier keinen Sinn und ich denke, es würde nicht einmal funktionieren. Nur Stateful-Beans können Bereiche haben. Tatsache ist, dass CDI keine wirklich überzeugende Antwort auf das Phänomen "@Stateless" hat. Eine zustandslose Bean ist eher ein Endpunkt, der Nachrichten abgehört, als eine normale Bean. Deshalb sind Selbstinjektion und zirkuläre Abhängigkeiten keine Probleme. Ein zustandsloser Proxy ist mehr wie eine URL. Wenn ein Methodenaufruf stattfindet, wird er an eine beliebige Bean dieses Typs gesendet (eine neue Instanz, eine aus einem Pool, immer dieselbe, ...). Also würde das Anfrageziel hier völlig falsch sein. –

1

Dies beantwortet nicht die gesamte Frage, aber es war der erste Treffer bei Google, als ich kreisförmige Abhängigkeitsausnahmen suchte. Ich hoffe, dies wird anderen Programmierern helfen, eine schnellere Antwort hier zu finden, ist meine Lösung.

Der Code, die zirkuläre Abhängigkeit Ausnahme verursachen:

class A{ 
    @Inject B b; 
    public void foo(){ 
     b.bar(); 
    } 
    public void quux(){ 
     //some code 
    } 
} 
class B{ 
    @Inject A a; 
    public void bar(){ 
     //some code 
    } 
    public void baz(){ 
     a.quux(); 
    } 
} 

Eine Lösung, das Problem zu lösen, ist durch die Verwendung javax.enterprise.inject.Instance

class A{ 
    @Inject B b; 
    public void foo(){ 
     b.bar(); 
    } 
    public void quux(){ 
     //some code 
    } 
} 
class B{ 
    @Inject Instance<A> a; 
    public void bar(){ 
     //some code 
    } 
    public void baz(){ 
     a.get().quux(); 
    } 
}