J'ai une application qui essaie d'utiliser l'annotation @EJB pour injecter des références distantes à des EJB dans mon fichier ejb.jar. Je reçois des résultats incohérents. Dans un cas, j'ai un écouteur dans le fichier web.xml qui est appelé et qui semble avoir injecté l'EJB correctement, puisque je peux le voir se connecter à l'EJB et appeler des méthodes dessus. Dans une autre classe (une action struts2) je reçois NPE quand il essaie d'accéder à la référence EJB. Pour autant que je sache, ce sont des appels identiques, dans des classes Java qui résident dans le même fichier .war. Pour contourner le problème, j'ai ajouté du code dans le constructeur pour rechercher les EJB par leurs noms JNDI globaux, et cela fonctionne très bien. Je n'arrive pas à comprendre pourquoi un @EJB fonctionne et pas un autre.Injection d'EJB dans Glassfish webapp
Répondre
Comment injecter des EJB dans les actions de Struts 2? Utilisez-vous CDI? Utilisez-vous le Struts2 CDI plugin?
Mise à jour: Le problème est que le conteneur ne crée pas les objets Struts, Struts est, de sorte que le conteneur n'a pas la possibilité d'injecter quoi que ce soit. Vous devrez utiliser le plugin for CDI mentionné pour activer l'injection dans vos actions.
Si vous voulez essayer, obtenir Struts 2 sources:
svn co http://svn.apache.org/repos/asf/struts/struts2/trunk/ struts2
Ensuite cd
dans le répertoire struts2
et exécutez la commande suivante (ce compilera les modules nécessaires à la struts-cdi-plugin
)
mvn install -pl plugins -am
obtenir ensuite les sources du cdi-plugin:
svn co https://svn.apache.org/repos/asf/struts/sandbox/trunk/struts2-cdi-plugin/
Et compiler:
mvn install
Maintenant, avec les dépendances suivantes dans mon pom.xml:
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-cdi-plugin</artifactId>
<version>2.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.8.0.GA</version>
</dependency>
Je suis en mesure d'obtenir un EJB injecté dans une action:
public class HelloWorld extends ActionSupport {
@Inject
HelloEJB helloEjb;
@Override
public String execute() throws Exception {
setMessage(helloEjb.getMessage());
return SUCCESS;
}
private String message;
public void setMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
Voir https://svn.apache.org/repos/asf/struts/sandbox/trunk/struts2-cdi-example/ pour un exemple.
Non, juste une simple annotation @EJB. – g051051
Merci pour l'explication. Cela explique parfaitement pourquoi mon écouteur (instancié par le conteneur d'une entrée web.xml) a fonctionné mais mes actions (instanciées par des entretoises) ne fonctionnaient pas. J'ai juste supposé que n'importe quelle classe annotée serait traitée par l'intermédiaire d'une sorte de voodoo de classloader. Est-ce que ce genre de chose est documenté n'importe où? – g051051
@ g051051 L'écouteur est un composant dit "géré" et l'injection fonctionne (depuis Java EE 5, voir http://java.sun.com/developer/technicalArticles/J2EE/intro_ee5/#injection par exemple). Java EE 6 va au-delà de cette limitation en rendant l'injection possible dans n'importe quel POJO en utilisant CDI (mais vous devez utiliser des frameworks "conscients" CDI ou CDI). –