Mon application est en cours de déploiement sur IBM WebSphere. J'ai un service simple et j'aimerais savoir comment fonctionne l'injection de dépendances dans ce cas.

// stateless EJB
@Stateless
public class UserService {

    private UserDAO userDAO;

    // btw, UserDAO is stateless EJB as well
    @Inject
    public UserService(UserDAO userDAO) {
        this.userDAO = userDAO;    
    }

    // biz methods ...
}

Il échoue avec l'erreur suivante:

[ERREUR] CWWKZ0002E: Une exception s'est produite lors du démarrage de l'application my-app. Le message d'exception était: com.ibm.ws.container.service.state.StateChangeException: com.ibm.ws.cdi.CDIException: com.ibm.wsspi.injectionengine.InjectionException: com.ibm.ejs.container.EJBConfigurationException: EJB La classe com.demo.app.UserService doit avoir un constructeur public qui ne prend aucun paramètre

Je me souviens qu'il y avait quelque chose dans la spécification EJB qui disait: the class must have a public constructor that takes no parameters et il est logique pour moi que l'instance de bean soit d'abord instanciée par le conteneur et ensuite l'injection de dépendances est effectuée .

D'un autre côté, j'ai trouvé ceci dans les documents WELD:

Tout d'abord, le conteneur appelle le constructeur du bean (le constructeur par défaut ou celui annoté @Inject), pour obtenir une instance du bean.

Et je suis un peu confus, pourquoi mon EJB ne peut pas être instancié.

Comment l'instance EJB est-elle créée et les dépendances injectées lorsque nous avons un point d'injection de constructeur?

Des idées? :)

2
ikos23 19 nov. 2018 à 17:27

3 réponses

Meilleure réponse

Par conséquent, vous ne remplissez pas les conditions requises pour l'initialisation des beans EJB.

La spécification CDI a quelques limitations sur les constructeurs - soit sans args, soit avec @Inject. Mais il y a aussi ce chapitre, qui précise que en EE, l'ensemble de règles est étendu par les besoins des beans session EJB.

Et maintenant, nous entrons dans la spécification EJB qui nécessite un constructeur sans argument sur un bean. Cela devrait être dans le chapitre Enterprise Bean Class où il indique

La classe doit définir un constructeur public qui n'accepte aucun argument.

Maintenant, passons enfin à la question de savoir si cela devrait fonctionner - par exemple pouvez-vous avoir un bean EJB en utilisant l'injection de constructeur CDI? Eh bien, jetons un coup d'œil à CDI TCK, un ensemble de tests que toutes les implémentations et tous les conteneurs doivent passer pour pouvoir prétendre implémenter CDI. Là, on peut voir ce bean et ce test en l'utilisant - alors oui, cela peut fonctionne, mais vous devez avoir les deux constructeurs.

3
Siliarus 20 nov. 2018 à 11:44

La création des beans session EJB est effectuée par le conteneur EJB mais il peut choisir d'utiliser CDI pour fournir une injection de ressources EE mais la résolution EJB est déléguée au conteneur

https: // docs. jboss.org/weld/reference/2.1.0.Final/en-US/html/ri-spi.html dit:

Alternativement, l'intégrateur peut choisir d'utiliser CDI pour fournir EE injection de ressources. Dans ce cas, l'environnement EE_INJECT doit être utilisé, et l'intégrateur doit implémenter la Section A.1.4, "EJB services ", Section A.1.7," Services de ressources "et Section A.1.5," JPA prestations de service". ....
Weld enregistre les points d'injection de ressources avec EjbInjectionServices, JpaInjectionServices, ResourceInjectionServices et les implémentations de JaxwsInjectionServices en amont (au démarrage). Cela permet de valider les points d'injection de ressources à l'heure de démarrage plutôt que l'exécution

Si vous êtes intéressé par la manière dont CDI et EJB sont intégrés. vous pouvez consulter le code du module weld-EJB et de l'intégration de soudure (code glassfish)

3
Mehran Mastcheshmi 20 nov. 2018 à 13:07

Les EJB sont enregistrés en tant que beans CDI. Mais ils doivent d'abord répondre aux exigences de la spécification EJB.

Je suppose que cela fonctionne simplement en fournissant le constructeur no-args.

3
Frito 19 nov. 2018 à 15:08