Beim Versuch, ein Ohr zu entfalten, erhalten wir das berüchtigte WELD-001408 (siehe unten für StackTrace).Warum gibt es einen WELD-001408, auch wenn der BeanManager den EJB kennt?
Problem: Es scheint, dass WELD eine 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 auch eine ejb-jar.xml an der betreffenden Stelle hatte ...
UPDATE2: habe ich eine minimale versin auf github
Zuerst das Setup - mein Forschung/Ergebnisse und detailliertere Fragen am Ende:
Wir verwenden derzeit Glassfish 4.1 => Weld 2.2.2.Final, aber der Fehler ist die gleiche Payara mit 4.1.1.154 => Weld 2.2.16.Final, auch Java EE 7
Aufbau des Ohres
sample.ear
├── a-ejb.jar (contains AEjb.java + beans.xml + ejb-jar.xml)
├── b-ejb.jar (contains AnotherCdiIManagedBeanPojo.java + DummyEjb.java + beans.xml)
├── lib
| └── shared.jar (contains ACdiManagedBeanPojo.java, AnotherCdiDependency.java + beans.xml)
└── META-INF
└── application.xml (...)
Im shared.jar ist es
public class ACdiManagedBeanPojo {
@Inject
private AEjb aEjb;
@Inject
private AnotherCdiDependency anotherCdiDependency;
}
AEjb ist ein EJB wohnhaft in der a-ejb.jar
@javax.ejb.Singleton
@javax.ejb.LocalBean
@javax.enterprise.context.ApplicationScoped
public class AEjb {}
AnotherCdiDependency ist eine weitere Pojo im shared.jar
public class AnotherCdiDependency {}
Die folgenden Klasse besteht in b-ejb.jar
public class AnotherCdiManagedBeanPojo {
@Inject
private AEjb aEjb;
}
beans.xml (CDI 1,1)
<beans bean-discovery-mode="all"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd">
</beans>
ejb-jar.xml
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd"
version="3.1">
<enterprise-beans>
<session>
<ejb-name>AEjb</ejb-name>
<ejb-class>com.xxx.ejb.AEjb</ejb-class>
<session-type>Singleton</session-type>
</session>
</enterprise-beans>
</ejb-jar>
stacktrace
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type AEjb with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject @Default private com.managed.pojo.ACdiManagedBeanPojo.aEjb
at com.managed.pojo.ACdiManagedBeanPojo.aEjb(ACdiManagedBeanPojo.java:0)
at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:370)
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:291)
at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134)
at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:165)
at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:529)
at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:515)
at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:490)
at org.jboss.weld.bootstrap.WeldStartup.validateBeans(WeldStartup.java:419)
at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:90)
at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:225)
at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:131)
at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:328)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:496)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:219)
at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:491)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:539)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:535)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:360)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:534)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:565)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:557)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:360)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:556)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1464)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1300(CommandRunnerImpl.java:109)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1846)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1722)
at org.glassfish.admin.rest.utils.ResourceUtil.runCommand(ResourceUtil.java:253)
at org.glassfish.admin.rest.utils.ResourceUtil.runCommand(ResourceUtil.java:231)
at org.glassfish.admin.rest.utils.ResourceUtil.runCommand(ResourceUtil.java:275)
at org.glassfish.admin.rest.resources.TemplateListOfResource.createResource(TemplateListOfResource.java:133)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:151)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:171)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:152)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:104)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:387)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:331)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:103)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:297)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:254)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1028)
at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:365)
at org.glassfish.admin.rest.adapter.RestAdapter$2.service(RestAdapter.java:316)
at org.glassfish.admin.rest.adapter.RestAdapter.service(RestAdapter.java:179)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
at java.lang.Thread.run(Thread.java:745)
]]
Forschung und Erkenntnisse
- Debuggen Validator.validateInjectionPointForDeploymentProblems() Ich sah, dass die BeanManager von lib/shared.jar die Instanz von AEjb hatte in seiner Enterprise Beans Kollektion. Zu keinem Zeitpunkt wird diese Sammlung zum Nachschlagen von Abhängigkeiten verwendet.
- Die Injektion von keiner EJB-Klassen (wie AnotherCdiDependency) arbeitet in den Klassen der shared.jar
- Injizieren AEjb über @Inject in AnotherCdiManagedBeanPojo feinen, die in B-EJB befindet.jar (sprich: Toplevel/außerhalb/lib) funktioniert auch gut
Meine erste Frage Meine Fragen: Warum kann injizieren die BeanManager die EJB auch , wenn es weiß, darüber? Gibt es einen Standard, der besagt, dass gemeinsame Bibliotheken nicht mit "globalen" EJBs injiziert werden können? 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 Schwierigkeiten haben.
Bonus Frage: Was ist mit diesem Kommentar in BeanManagerImpl.getBeans (InjectionPoint injectionPoint) - wo ist das FAQ?
Wir immer Cache, gehen wir davon aus, dass die Menschen wörtliche Inline-Annotation Erklärungen nicht verwenden, ein wenig riskant, aber FAQd
PS: Ich habe die folgenden und viele andere Sachen lesen über classloading, Kontext und cdi und das besondere Verhalten der verschiedenen Anwendungsservern diese Themen rund - aber immer noch ...
- https://struberg.wordpress.com/2015/02/18/cdi-in-ears/
- http://balusc.omnifaces.org/2013/10/cdi-behaved-unexpectedly-in-ear-so.html
Haftungsausschluss: Keine neue während meiner Forschung genannt wurde.
haben Sie versucht, eine ejb-jar.xml Descriptor an die ejb Gläser hinzufügen? – StefanHeimberg
@StefanHeimberg: Ja, versuchte das auch - immer noch das gleiche Problem - Ich werde die Frage mit dieser Information aktualisieren - danke für den Vorschlag –
Ich habe ein bisschen herum gespielt ... können Sie https://github.com/ klonen StefanHeimberg/stackoverflow-34065368, erstellen und deploy "Eltern/sample-app/target/sample-app-1.0-SNAPSHOT.ear" auf Ihrem Glassfish? und dann schauen Sie sich die Ausgabe an. Können Sie überprüfen, ob alles funktioniert? AStartupEJB -> BApplicationCDIBean -> BEJB – StefanHeimberg