Glassfish 4.1 CDI WELD-001409: Ambiguous dependencies

不打扰是莪最后的温柔 提交于 2020-07-07 12:58:28

问题


I'm working in a project deployed in Glassfish 4.1. Dependency injection is made using CDI and I'm having an issue when trying to deploy the application. The error I'm getting is the following (usually I "translate" the name of my classes in the code so the whole post is in the same language, I`ll not do that now so I can copy/paste and avoid some translate typing mistakes):

Server log

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]

(by the way, I don't know why it says 3 exceptions and all appear numbered as Exception 0)

Involved classes

@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
}

The parent class RepositorioGenerico<Menu> is just a class with some generic methods to interact with the DB and Menu is an entity class. The interfaces are as follow:

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

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

I have only one injectable class for each injection point so I don't understand why the injection fails. I don't know if more details about my code is needed, so ask me and I'll edit the post; I write only the parts I think it's needed.

I've seen another post but there the @Produces annotation is used and, AFAIK, I don't need that for this case.

Any help or guide is appreciated. Thanks in advance for your answers

EDIT 1

I read in an article by Antonio Goncalves in the Java Magazine that CDI is made via properties (even private), setter method or constructor. Taking that into account I removed getters and setters for every injected property and settled the access to default (package) for those properties.

The getter/setter method for injected properties were only used to set the dependencies manually in my unit tests, so there's no need for them in production.

After all this changes, the error remains...

Some more info

According to the Java EE 7 official documentation, my beans are compliant with the CDI Managed Bean definition, except for the point

It is not annotated with an EJB component-defining annotation or declared as an EJB bean class in ejb-jar.xml.

According to javax.ejb javadoc EJB component-defining annotation is one of the followings: @MessageDriven, @Stateful, @Stateless or @Singleton. But I've seen other projects with CDI working with EJB (e.g., @Stateless beans being injected somewhere else). On the other hand, I've been reading Beginning Java EE 7 by Antonio Goncalves and there says (Ch. 2 - Context and Dependency Injection):

Anatomy of a CDI Bean

According to the CDI 1.1 specification, the container treats any class that satisfies the following conditions as a CDI Bean:

  • It is not a non-static inner class,
  • It is a concrete class, or is annotated @Decorator, and
  • It has a default constructor with no parameters, or it declares a constructor annotated @Inject.

Then a bean can have an optional scope, an optional EL name, a set of interceptor bindings, and an optional life-cycle management.

And my beans are compliant with that definition. I checked the Weld Documentation and in chapter 2 brings the definition of a CDI bean, which is closer to the first definition (from the Java EE documentation). The thing is, as I said, that I've seen other projects making dependency injection with EJB Managed Beans (@Stateless or some other).

In conclusion, I don't know who to believe at. Can someone shed some light in this matter?

Failed Attempt

NOTE: After this attempt I have the same problem in a different place, so the server log and the involved classes are changed from the stated above, check the differences.

First, following a hunch, I added interfaces to the beans that I need to inject somewhere else.

Second, I updated my Glassfish Server from 4.1 to 4.1.1. This one has bundled the WELD-2.2.13.Final CDI implementation (according to the server log message INFO: WELD-000900: 2.2.13 (Final)).

Finally I tried to deploy my project and the error remains with some changes. Before showing the changes, let me say that it never caught my attention but at deployment time, JNDI generates 2 names for my beans, as states in the following log message thrown when I try to deploy the application:

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]

I don't know if that could be causing the error in the injection point but sounds suspicious (and I don't know how to change that). It appeared in the first attempt too but, as I said, it never caught my attention. Now the logs and the classes

Server log

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]...

Involved classes

@Named(value = "registroBean")
@ViewScoped
public class RegistroBean implements Serializable {

    private static final long serialVersionUID = 2181909526300424451L;

    @Inject
    GestorPersonas gestorPersonas;

    // fields, methods, etc
}

@Named(value = "sesionUsuarioBean")
@SessionScoped
public class SesionUsuarioBean implements Serializable {

    private static final long serialVersionUID = 2938631472102116238L;

    @Inject
    GestorUsuarios gestorUsuarios;

    // fields, methods, etc
}

The injected fields are shown in the main section.

Any help you can provide me with this new info is appreciated. If you need some more info about the application just let me know.

Thanks in advance for your answers.


回答1:


After turning the internet upside down for 2 weeks, I finally tried to deploy on a Wildfly 10.0.0 Server and now my application deploys with no problem. So I must conclude that it's a bug on Glassfish. Pitty, because I'm using the lastest version (4.1.1) and it's something basic (I think) as CDI discovery. Hope that Payara solves this issue, but I'll not be trying it right now.

I must say: if a server is suppose to be "Java EE 7 compliant", it should not be released with this kind of bugs.

If someone knows about a discussion forum or knows some benchmark results for the different servers, please comment it out. Shame on you Glassfish




回答2:


A bit of a shot in the dark, but I had some similar problems. My solution was to disable the implicit cdi feature of Glassfish (which was enabled by default in 4.x).

When deploying:

asadmin deploy --property implicitCdiEnabled=false  ...

Or as a server-wide configuratin:

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

Then again, discontinuing the use of Glassfish and using something like Wildfly instead seems like the right way to go (started using Jetty instead myself..)




回答3:


I had same issues in Payara and I solved it by removing a Dependency I had in the EAR module.

So before, my EAR module had a dependecy on the EJB module, and also my war module had a dependency on the EJB module. So when building, I think both of them generated the classes twice and ended up confusing the CDI. So removing the EAR's dependency on the EJB module solved by problem



来源:https://stackoverflow.com/questions/38003014/glassfish-4-1-cdi-weld-001409-ambiguous-dependencies

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!