2016-04-11 10 views
2

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) 
+0

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

+1

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). –

+0

@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

Antwort

0

Ich habe das jetzt herausgefunden.

Es war, als Steve C darauf hingewiesen:

Das Projekt der Bean in Frage kommenden zusammen mit den beiden Webprojekte verpackt wurde.

Die einfache Lösung bestand darin, den Maven-Bereich "Abhängigkeiten" in den Webprojekten zu ändern und ihn dann als Bibliothek im EAR bereitzustellen.

Also meine Frage zu beantworten:

Ja, es gibt eine bekannte Strategie mit dieser Art von Problem zu lösen, indem sichergestellt wird, das Projekt, um Ihren gemeinsamen Beans für das größere Bild enthält, aber nie Packen Sie das Projekt neben Ihrer Ziel-EAR auch mit jedem anderen Projekt.

Dank Steve C, für Wegbeschreibung

Mit freundlichen Grüßen,

J. gebenAdam