在多项目环境中避免模糊依赖关系的众所周知的策略



我设置了多个Maven项目,最终打包为EAR归档。这些项目属于jar、ejb或war类型。

现在我有了一个javax.enterprise.context.SessionScoped CDI Bean,称为CCD_ 2,携带关于当前用户的信息(主要从Shiro Framework中检索)。我还有两个自主的Web应用程序,它们应该使用这个Bean,所以我把Bean放在一个项目中,由两个项目引用

我现在的问题是,我在部署期间收到一个异常,告诉我Bean不能被注入,因为有两个可能的依赖项,引用的是完全相同的类。我想这是因为包含Bean的项目(Jar项目)被附加到两个Web项目上,因此Bean被多次发现。

我的问题是:有没有一种众所周知的策略来处理这类问题,或者用某种方式向ApplicationServer/CDI实现发出信号(在我的案例中,Glassfish 4.x使用Weld Framework),只读一次?

我确实注意到使用javax.enterprise.inject.Instance是有可能的,但我不想使用它,因为允许更改当前操作用户的快照对应用程序至关重要。我还考虑了通过API和实现项目提供这些Bean的方法,只引用API作为依赖项,但这将产生巨大的开销,因为这些项目目前每个项目只包含一个Class。

这是我的Beans类标题:

package omega1001.mediaserver.domainmodel.web;
import ...;

@SessionScoped
@Default
public class OmegaMediaServerSubject implements Serializable {

这就是我尝试注入Bean的方式:

@Inject
    private OmegaMediaServerSubject subject;

这是我在部署中遇到的异常:

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)

我现在已经弄清楚了。

正如Steve C所指出的:

包含有问题的Bean的项目与这两个Web项目一起打包。

简单的解决方案是将Dependencies Maven作用域更改为在Web项目中提供,然后在EAR中将其作为库提供。

因此,为了回答我的问题:

是的,有一个众所周知的策略来处理这种问题,通过确保提供包含共享Bean的项目来获得更大的利益,但永远不要将项目与除目标EAR之外的任何其他项目打包。

感谢Steve C,他给出了方向

致问候,

J.Adam

最新更新