Ich habe ein Setup von mehreren Maven-Projekt, letztlich als EAR-Archiv verpackt. Diese Projekte sind vom Typ jar, ejb oder war.Bekannte Strategie zur Vermeidung mehrdeutiger Abhängigkeiten in mehreren Projektumgebungen
Jetzt habe ich ein javax.enterprise.context.SessionScoped
CDI Bean, annotaded als javax.enterprise.inject.Default
, Informationen über den aktuellen Benutzer tragen (vor allem aus Shiro-Rahmen abgerufen). Ich habe auch zwei autonome Web-Anwendungen, die diese Bean verwenden soll, also habe ich die Bean in ein Projekt, referenziert von beiden Projekten
Mein Problem ist jetzt, dass ich eine Ausnahme während der Bereitstellung bekomme, mir das zu sagen Die Bean konnte nicht injiziert werden, da es zwei mögliche Abhängigkeiten gibt, die sich auf die exakt gleiche Klasse beziehen. Ich vermute, das liegt daran, dass das Projekt, das das Bean (Jar Project) enthält, an beide Web-Projekte angehängt ist und die Bean dafür mehrfach entdeckt wird.
Also hier ist meine Frage: Gibt es eine bekannte Strategie, um mit dieser Art von Problem umzugehen, oder einige Mittel, um die Application Server/CDI-Implementierung (Glassfish 4.x in meinem Fall verwendet Weld Framework) zu signalisieren, nur einmal lesen?
Ich habe festgestellt, dass es eine Möglichkeit gibt mit javax.enterprise.inject.Instance
, aber ich möchte das nicht verwenden, weil es für die Anwendung entscheidend ist, die Möglichkeit der Variierung von Snapshots des aktuellen Benutzers zu ermöglichen. Ich dachte auch über den Ansatz nach, diese Bean über eine API und ein Implementierungsprojekt bereitzustellen, die nur die API als Abhängigkeit referenzieren, aber das würde einen riesigen Aufwand verursachen, da diese Projekte momentan nur jeweils eine Klasse enthalten würden.
Dies ist meine Bohnen Klasse Rubrik:
package omega1001.mediaserver.domainmodel.web;
import ...;
@SessionScoped
@Default
public class OmegaMediaServerSubject implements Serializable {
Dies ist, wie ich versuche, mein Bean zu injizieren:
@Inject
private OmegaMediaServerSubject subject;
Dies ist die Ausnahme, die ich auf Deployment erhalten:
org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type OmegaMediaServerSubject with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject private omega1001.mediaserver.servlet.messageProcessor.DefaultMessageProcessor.subject
at omega1001.mediaserver.servlet.messageProcessor.DefaultMessageProcessor.subject(DefaultMessageProcessor.java:0)
Possible dependencies:
- Managed Bean [class omega1001.mediaserver.domainmodel.web.OmegaMediaServerSubject] with qualifiers [@Default @Any],
- Managed Bean [class omega1001.mediaserver.domainmodel.web.OmegaMediaServerSubject] with qualifiers [@Default @Any]
at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:367)
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:281)
at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134)
at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:155)
at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:518)
at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:504)
at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:479)
at org.jboss.weld.bootstrap.WeldStartup.validateBeans(WeldStartup.java:443)
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:483)
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:144)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:309)
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:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:292)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1139)
at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:375)
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:206)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
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:283)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
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:591)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
at java.lang.Thread.run(Thread.java:745)
Meiner Meinung nach ist es keine gute Idee CDI Bohnen über verschiedene Projekte zu teilen. Ich würde eher die Benutzerinformationen in ein separates Projekt umgestalten, z. UserService, das eine übersichtliche Schnittstelle (z. B. JAX-RS) bereitstellt und von beiden Webanwendungen verwendet werden kann. Sie werden weniger Probleme haben, wenn die Webanwendungen unabhängig von Abhängigkeiten zu freigegebenen Bibliotheken sind. – simdevmon
Das riecht sehr nach einem Jar mit der Bean "OmegaMediaServerSubject", der sowohl im Verzeichnis EAR als auch im Verzeichnis WEB-INF/lib einer oder beider WAR-Dateien erstellt wurde. Sie müssen sicherstellen, dass Sie das maven-ear-plugin so konfiguriert haben, dass es [mager wars] erstellt (https://maven.apache.org/plugins/maven-ear-plugin/examples/skinny-wars.html). –
@simdevmon Ihre Idee ähnelt meinem API/Impl-Ansatz. Aber wie ich bereits erwähnte, wäre das "ein enormer Aufwand, da diese Projekte derzeit nur jeweils eine Klasse enthalten". Außerdem ist es nur Zufall, dass es um die Bereitstellung von Benutzerinformationen geht. Also ich denke, das ist ein gültiger Ansatz im Allgemeinen, aber nicht genau das, was ich suche. Vielen Dank trotzdem – Omega1001