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):
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
)
The involved classes are as follows:
@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?
Aucun commentaire:
Enregistrer un commentaire