Glassfish 4.1 CDI WELD-001409:不明确的依赖

时间:2016-06-23 22:35:52

标签: java glassfish cdi java-ee-7

我正在使用 Glassfish 4.1 部署的项目。使用CDI进行依赖注入,我在尝试部署应用程序时遇到问题。我得到的错误是以下(通常我在代码中“翻译”我的类的名称,所以整个帖子使用相同的语言,我现在不会这样做,所以我可以复制/粘贴,避免一些翻译打字错误):

服务器日志

org.glassfish.deployment.common.DeploymentException: CDI deployment failure:Exception List with 3 exceptions:
Exception 0 :
org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type GestorUsuarios with qualifiers @Default
  at injection point [BackedAnnotatedField] @Inject private ar.edu.unt.sigea.servicios.impl.GestorPersonasImpl.gestorUsuarios
  at ar.edu.unt.sigea.servicios.impl.GestorPersonasImpl.gestorUsuarios(GestorPersonasImpl.java:0)
  Possible dependencies: 
  - Session bean [class ar.edu.unt.sigea.servicios.impl.GestorUsuariosImpl with qualifiers [@Any @Default]; local interfaces are [GestorUsuarios],
  - Managed Bean [class ar.edu.unt.sigea.servicios.impl.GestorUsuariosImpl] with qualifiers [@Any @Default]
        ...[Stack trace]...

Exception 0 :
org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type RepositorioMenu with qualifiers @Default
  at injection point [BackedAnnotatedField] @Inject private ar.edu.unt.sigea.servicios.impl.GestorUsuariosImpl.repositorioMenu
  at ar.edu.unt.sigea.servicios.impl.GestorUsuariosImpl.repositorioMenu(GestorUsuariosImpl.java:0)
  Possible dependencies: 
  - Managed Bean [class ar.edu.unt.sigea.repositorio.RepositorioMenu] with qualifiers [@Any @Default],
  - Session bean [class ar.edu.unt.sigea.repositorio.RepositorioMenu with qualifiers [@Any @Default]; local interfaces are [RepositorioMenu]
        ...[Stack trace]...

Exception 0 :
org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type RepositorioOperacion with qualifiers @Default
  at injection point [BackedAnnotatedField] @Inject ar.edu.unt.sigea.repositorio.RepositorioMenu.repositorioOperacion
  at ar.edu.unt.sigea.repositorio.RepositorioMenu.repositorioOperacion(RepositorioMenu.java:0)
  Possible dependencies: 
  - Managed Bean [class ar.edu.unt.sigea.repositorio.RepositorioOperacion] with qualifiers [@Any @Default],
  - Session bean [class ar.edu.unt.sigea.repositorio.RepositorioOperacion with qualifiers [@Any @Default]; local interfaces are [RepositorioOperacion]

(顺便说一句,我不知道为什么它会显示3 exceptions并且所有内容都显示为Exception 0

涉及的课程

@Stateless
public class GestorPersonasImpl implements GestorPersonas {

    @Inject
    private GestorUsuarios gestorUsuarios;

    public GestorUsuarios getGestorUsuarios() {return gestorUsuarios;}

    public void setGestorUsuarios(GestorUsuarios gestorUsuarios) {
        this.gestorUsuarios = gestorUsuarios;
    }
    // Other fields and methods
}

@Stateless
public class GestorUsuariosImpl implements GestorUsuarios {

    @Inject
    private RepositorioMenu repositorioMenu;

    public RepositorioMenu getRepositorioMenu() {return repositorioMenu;}

    public void setRepositorioMenu(RepositorioMenu repositorioMenu) {
        this.repositorioMenu = repositorioMenu;
    }
    // Other fields and methods
}

@Stateless
@LocalBean
public class RepositorioMenu extends RepositorioGenerico<Menu> {

    @Inject
    private RepositorioOperacion repositorioOperacion;

    public RepositorioOperacion getRepositorioOperacion() {return repositorioOperacion;}

    public void setRepositorioOperacion(RepositorioOperacion repositorioOperacion) {
        this.repositorioOperacion = repositorioOperacion;
    }
    // Other fields and methods
}

@Dependent
@Stateless
@LocalBean
public class RepositorioOperacion extends RepositorioGenerico<Operacion> {
    // This class doesn't have injection points
    // just put it here for the reference made in the error message
}

父类RepositorioGenerico<Menu>只是一个类,其中包含一些与数据库交互的通用方法,Menu是一个实体类。接口如下:

@Local
public interface GestorPersonas {
    // methods definitions, implemented by GestorPersonasImpl
}

@Local
public interface GestorUsuarios {
    // methods definitions, implemented by GestorUsuariosImpl
}

每个注射点只有一个注射类,所以我不明白注射失败的原因。我不知道是否需要有关我的代码的更多细节,所以请问我,我将编辑帖子;我只写了我认为需要的部分。

我见过另一篇文章,但是使用了@Produces注释,而AFAIK,我不需要这种情况。

感谢任何帮助或指南。提前感谢您的回答

编辑1

我在Antonio Goncalves中的Java Magazine文章中读到了CDI是通过属性(甚至私有),setter方法或构造函数创建的。考虑到这一点,我删除了每个注入属性的getter和setter,并确定了对这些属性的默认(包)的访问权限。

注入属性的getter / setter方法仅用于在单元测试中手动设置依赖项,因此生产中不需要它们。

在所有这些改变之后,错误仍然是......

更多信息

根据Java EE 7 official documentation,我的bean符合CDI Managed Bean定义,除了点

  

它没有使用EJB组件定义注释或在ejb-jar.xml中声明为EJB bean类。

根据javax.ejb javadoc EJB组件定义注释是以下之一:@MessageDriven@Stateful@Stateless或{{1} }。但我已经看到其他项目与CDI一起使用EJB(例如,@Singleton bean被注入其他地方)。另一方面,我一直在阅读Beginning Java EE 7 by Antonio Goncalves,并说(第2章 - 上下文和依赖注入):

  

CDI Bean剖析

     

根据CDI 1.1规范,容器将满足以下条件的任何类视为CDI Bean:

     
      
  • 它不是非静态的内部类,
  •   
  • 这是一个具体的类,或者注释为@Decorator,
  •   
  • 它有一个没有参数的默认构造函数,或者它声明了一个注释为@Inject的构造函数。
  •   
     

然后bean可以有一个可选的作用域,一个可选的EL名称,一组拦截器绑定和一个可选的生命周期管理。

我的bean符合该定义。我检查了Weld Documentation并在chapter 2中带来了CDI bean的定义,它更接近第一个定义(来自Java EE文档)。正如我所说的那样,我看到其他项目使用EJB Managed Beans(@Stateless或其他)进行依赖注入。

总之,我不知道该相信谁。有人可以在这件事上说清楚吗?

尝试失败

注意:在此次尝试之后,我在不同的地方遇到了同样的问题,因此服务器日志和涉及的类会从上述说明中更改,请检查差异。

首先,在预感之后,我将bean添加到了我需要注入其他地方的bean。

其次,我将 Glassfish服务器从4.1更新为4.1.1 。这个捆绑了@Stateless CDI实现(根据服务器日志消息WELD-2.2.13.Final)。

最后,我尝试部署我的项目,错误仍然存​​在一些变化。在显示更改之前,让我说它从未引起我的注意,但在部署时,JNDI为我的bean生成2个名称,因为当我尝试部署应用程序时,以下日志消息中的状态被抛出:

INFO:   WELD-000900: 2.2.13 (Final)

我不知道这是否会导致注射点出错,但听起来很可疑(我不知道如何更改)。它也出现在第一次尝试中,但正如我所说,它从未引起我的注意。现在是日志和类

服务器日志

INFO:   Portable JNDI names for EJB RepositorioUsuarioImpl: [java:global/sigea-ear-0.8-SNAPSHOT/sigea-model-0.8-SNAPSHOT/RepositorioUsuarioImpl, java:global/sigea-ear-0.8-SNAPSHOT/sigea-model-0.8-SNAPSHOT/RepositorioUsuarioImpl!ar.edu.unt.sigea.repositorio.RepositorioUsuario]
INFO:   Portable JNDI names for EJB RepositorioAlumnoImpl: [java:global/sigea-ear-0.8-SNAPSHOT/sigea-model-0.8-SNAPSHOT/RepositorioAlumnoImpl, java:global/sigea-ear-0.8-SNAPSHOT/sigea-model-0.8-SNAPSHOT/RepositorioAlumnoImpl!ar.edu.unt.sigea.repositorio.RepositorioAlumno]
INFO:   Portable JNDI names for EJB RepositorioMenuImpl: [java:global/sigea-ear-0.8-SNAPSHOT/sigea-model-0.8-SNAPSHOT/RepositorioMenuImpl, java:global/sigea-ear-0.8-SNAPSHOT/sigea-model-0.8-SNAPSHOT/RepositorioMenuImpl!ar.edu.unt.sigea.repositorio.RepositorioMenu]
INFO:   Portable JNDI names for EJB GestorUsuariosImpl: [java:global/sigea-ear-0.8-SNAPSHOT/sigea-model-0.8-SNAPSHOT/GestorUsuariosImpl, java:global/sigea-ear-0.8-SNAPSHOT/sigea-model-0.8-SNAPSHOT/GestorUsuariosImpl!ar.edu.unt.sigea.servicios.GestorUsuarios]
INFO:   Portable JNDI names for EJB GestorPersonasImpl: [java:global/sigea-ear-0.8-SNAPSHOT/sigea-model-0.8-SNAPSHOT/GestorPersonasImpl!ar.edu.unt.sigea.servicios.GestorPersonas, java:global/sigea-ear-0.8-SNAPSHOT/sigea-model-0.8-SNAPSHOT/GestorPersonasImpl]
INFO:   Portable JNDI names for EJB RepositorioPersonaImpl: [java:global/sigea-ear-0.8-SNAPSHOT/sigea-model-0.8-SNAPSHOT/RepositorioPersonaImpl, java:global/sigea-ear-0.8-SNAPSHOT/sigea-model-0.8-SNAPSHOT/RepositorioPersonaImpl!ar.edu.unt.sigea.repositorio.RepositorioPersona]
INFO:   Portable JNDI names for EJB RepositorioOperacionImpl: [java:global/sigea-ear-0.8-SNAPSHOT/sigea-model-0.8-SNAPSHOT/RepositorioOperacionImpl!ar.edu.unt.sigea.repositorio.RepositorioOperacion, java:global/sigea-ear-0.8-SNAPSHOT/sigea-model-0.8-SNAPSHOT/RepositorioOperacionImpl]

涉及的课程

Fatal:   Exception during lifecycle processing
org. glassfish.deployment.common.DeploymentException: CDI deployment failure:Exception List with 2 exceptions:
Exception 0 :
org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type GestorPersonas with qualifiers @Default
  at injection point [BackedAnnotatedField] @Inject ar.edu.unt.sigea.inicio.RegistroBean.gestorPersonas
  at ar.edu.unt.sigea.inicio.RegistroBean.gestorPersonas(RegistroBean.java:0)
  Possible dependencies: 
  - Session bean [class ar.edu.unt.sigea.servicios.impl.GestorPersonasImpl with qualifiers [@Any @Default]; local interfaces are [GestorPersonas],
  - Managed Bean [class ar.edu.unt.sigea.servicios.impl.GestorPersonasImpl] with qualifiers [@Any @Default]
    ...[Stack trace]...

Exception 0 :
org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type GestorUsuarios with qualifiers @Default
  at injection point [BackedAnnotatedField] @Inject ar.edu.unt.sigea.inicio.SesionUsuarioBean.gestorUsuarios
  at ar.edu.unt.sigea.inicio.SesionUsuarioBean.gestorUsuarios(SesionUsuarioBean.java:0)
  Possible dependencies: 
  - Session bean [class ar.edu.unt.sigea.servicios.impl.GestorUsuariosImpl with qualifiers [@Any @Default]; local interfaces are [GestorUsuarios],
  - Managed Bean [class ar.edu.unt.sigea.servicios.impl.GestorUsuariosImpl] with qualifiers [@Any @Default]
    ...[Stack trace]...

注入的字段显示在主要部分中。

您可以向我提供此新信息的任何帮助表示赞赏。如果您需要有关该应用程序的更多信息,请告诉我。

提前感谢您的回答。

3 个答案:

答案 0 :(得分:1)

在将互联网颠倒了两周之后,我终于尝试在 Wildfly 10.0.0 服务器上进行部署,现在我的应用程序部署没有问题。所以我必须得出结论,这是Glassfish的一个错误。皮蒂,因为我使用的是最新版本(4.1.1),它是基本的(我认为)作为CDI发现的东西。希望Payara解决这个问题,但我现在不会尝试。

我必须说:如果服务器被认为是&#34;符合Java EE 7&#34; ,则不应该发布此类错误。

如果有人知道讨论论坛或知道不同服务器的某些基准测试结果,请将其评论出来。 耻辱Glassfish

答案 1 :(得分:1)

在黑暗中有点射击,但我有一些类似的问题。我的解决方案是禁用Glassfish的隐式cdi功能(默认情况下在4.x中启用)。

部署时:

asadmin deploy --property implicitCdiEnabled=false  ...

或者作为服务器范围的配置:

asadmin set configs.config.server-config.cdi-service.enable-implicit-cdi=false

然后,再次停止使用Glassfish并使用像Wildfly这样的东西似乎是正确的方法(开始使用Jetty而不是我自己..)

答案 2 :(得分:0)

我在Payara遇到了同样的问题,我通过删除EAR模块中的依赖关系解决了这个问题。

所以之前,我的EAR模块依赖于EJB模块, 我的war模块也依赖于EJB模块。 因此,在构建时,我认为它们都生成了两次类,最终混淆了CDI。 因此,通过问题

解决了EAR对EJB模块的依赖性