Warum gibt es einen WELD-001408, auch wenn der BeanManager den EJB kennt?

8

Beim Versuch, ein Ohr zu entfalten, erhalten wir das berüchtigte WELD-001408 (siehe unten für Stacktrace).

Problem: Es scheint, dass WELD ein EJB über @Inject nicht in eine CDI-gesteuerte Bean (! = @ManagedBean) in einer lib / shared.jar injizieren kann. Warum ist das? Gibt es einen Standard, der besagt, dass dies nicht funktionieren soll?

UPDATE Ich hatte auch eine ejb-jar.xml am entsprechenden Ort ...

UPDATE2: Ich habe eine minimale Version auf github

erstellt

Zuerst das Setup - meine Forschung / Ergebnisse und detailliertere Fragen am Ende:

Wir verwenden derzeit Glassfish 4.1 = & gt; Weld 2.2.2.Final, aber der Fehler ist der gleiche wie bei Payara 4.1.1.154 = & gt; Weld 2.2.16.Final, auch Java EE 7

Layout des Ohrs

%Vor%

In der shared.jar gibt es

%Vor%

AEjb ist ein EJB, der sich im a-ejb.jar befindet

%Vor%

AnotherCdiDependency ist ein weiterer Pojo in der shared.jar

%Vor%

Die folgende Klasse befindet sich in b-ejb.jar

%Vor%

beans.xml (CDI 1.1)

%Vor%

ejb-jar.xml

%Vor%

Stapelverfolgung

%Vor%

Forschung und Ergebnisse

  • Debugging Validator.validateInjectionPointForDeploymentProblems () I sah, dass der BeanManager von lib / shared.jar die Instanz von AEjb hatte in seiner EnterpriseBeans Sammlung. Zu keinem Zeitpunkt wird diese Sammlung zum Nachschlagen von Abhängigkeiten verwendet.
  • Die Injektion von Nicht-EJB-Klassen (wie AnotherCdiDependency) funktioniert gut in den Klassen von shared.jar
  • Das Einfügen von AEjb über @Inject in ein anderesCdiManagedBeanPojo, das sich in b-ejb.jar (gelesen: Toplevel / außerhalb von / lib) befindet, funktioniert auch gut

Meine Fragen

  • Meine erste Frage: Warum kann der BeanManager den EJB nicht sogar injizieren? wenn es davon weiß? Gibt es einen Standard, der gemeinsame libs sagt? kann nicht mit "globalen" EJBs injiziert werden? Wenn ja, wo finde ich es?

  • Was wäre der "einfachste" Ausweg? Wo einfach bedeutet, so wenig Code wie möglich zu ändern und keine große Unordnung zu erzeugen, werden wir später Probleme haben.

  • Bonus Frage: Was ist mit diesem Kommentar in BeanManagerImpl.getBeans (InjectionPoint injectionPoint) - wo ist diese FAQ?

      

    Wir cachen immer, wir nehmen an, dass Leute keine Inline-Annotation-Literal-Deklarationen verwenden, ein wenig riskant, aber FAQd

PS: Ich habe die folgenden und viele andere Dinge über Classloading, Kontext und cdi und das spezielle Verhalten verschiedener Anwendungsserver bezüglich dieser Themen gelesen - aber immer noch ...

Haftungsausschluss: Während meiner Recherchen wurde kein neues Produkt aufgerufen.

    
Benjamin Seiller 03.12.2015, 11:51
quelle

2 Antworten

2

Die Regeln für die Klassensichtbarkeit in EAR-Dateien sind in §8 der Java EE Specification, v7, dargelegt.

Zusammenfassend:

Jedes Modul in der EAR erhält effektiv seinen eigenen Klassenlader.

Die JAR-Dateien im EAR / lib-Verzeichnis werden zum Zweck der Klassensichtbarkeit in einem einzigen Modul zusammengefasst. Klassen im Klassenladeprogramm EAR / lib werden automatisch für alle anderen Module sichtbar gemacht (wie in §8.3 beschrieben).

Das Gegenteil ist nicht wahr. Auf Klassen in den anderen Modulen kann nicht automatisch auf die im Modul EAR / lib zugegriffen werden.

Einige Java EE-Implementierungen bieten Möglichkeiten, diese Einschränkungen zu umgehen (auf Kosten der Unportabilität Ihrer Anwendung).

Eine mögliche Lösung besteht darin, shared.jar in den Stamm der EAR zu verschieben und in jedem Jar manifeste Klassenpfad-Einträge zu verwenden, um den Zugriff sicherzustellen.

ie. Die META-INF / MANIFEST.MF in shared.jar würde dann enthalten:

%Vor%

Wenn Ihre ejb-jars Klassen in der verschobenen sample.jar sehen müssen, benötigen sie dann ihre eigenen Manifest-Klassenpfadeinträge.

Ich denke, das Glas muss verschoben werden, da meiner Erfahrung nach Folgendes nicht funktioniert.

%Vor%     
Steve C 11.12.2015, 05:37
quelle
0

Sie sollten das EJB mit der @ EJB-Annotation in die CDI-Bean injizieren.

%Vor%

Arbeitete für mich in Ihrer Testanwendung auf GitHub und wurde erfolgreich in Payara 4.1.154 implementiert.

    
leet java 07.01.2016 18:50
quelle

Tags und Links