vendredi 7 décembre 2007

Injection EJB avec JSF1.1 solution 2

Nouvelle solution plus propre (ca fera plaisir à Alexandre) et plus performante pour effectuer une injection @EJB dans un managed bean (ou back bean) JSF. L'utilisation d'un lookup local tout simplement (bien que sur Workshop ce soit pas du gâteau).

Une petite classe donc qui, avec sa simple méthode à appeller dans le contructeur de votre back bean vous permettra par réflexion d'effectuer un context lookup vers votre ejb (Champs @EJB public uniquement). Toujours en attendant l'injection @EJB dans le nouveau WorkShop.

télécharger la classe java

Pour cerain il peut se produire une erreur de lookup du style :

javax.naming.NameNotFoundException: While trying to look up comp/env/Addition/Local in /app/webapp/TEST_JSF_EBJ/12227708.; remaining name 'comp/env/Addition/Local'


Pour résoudre ce problème j'ai simplement ajouté un ServletContextListener à mon application web dans laquelle je référence mes ejb . Après le lookup local dans les back beans fonctionne a merveille...

public class testListener implements ServletContextListener {

@EJB(name = "Addition/Local")

public AdditionRemote ar;

public void contextDestroyed(ServletContextEvent arg0) { }

public void contextInitialized(ServletContextEvent arg0) { }

}




Exemple d'utilisation :


@EJB(name = "Addition/Local")

public AdditionRemote ar; // is va être injecté dans le constructeur

public testBackBean() {

fr.sihm.common.ejblocator.EJBLocator.injecterMesEJB(this);

}

public String getResultEJB() // on teste

{

if (ar == null) {

return "NOT BOUND";

} else {

return "Bouded , result = " + ar.additionner(5, 5);

}

}

mercredi 5 décembre 2007

Injection d’un EJB dans un back bean JSF 1.1

Dans sa version 10.1, BEA workshop studio propose de base de faire du JSF 1.1. Or, dans la spécification JSF 1.1, l’injection d’EJB n’est pas possible dans les back-beans.

En attendant la nouvelle version de workshop qui devrait permettre d’utiliser JSF 1.2 facilement (oui c’est déjà possible mais galère) et donc l’injection dans les back beans, je vous propose un petit « hack » maison pour permettre de ne pas trop salir vos managed beans tout en ayant un semblant d’injection (Le canada dry de l'injection EJB).

Le fonctionnement est simple, on crée un servlet listener qui possède une référence vers tous les ejb que vous utiliserez dans l’application. La norme JSF 1.1 permettant l’injection dans les servletfilters, ces références seront peuplées lors de l’exécution. Dès lors, notre tâche consistera à copier les références dans le servletcontext pour que nos back beans aient accès aux valeurs injectées.

Je vous fourni donc une classe qui par réflexion va analyser tous les champs public qui contiennent l’annotation @EJB et qui écrira (pour le listener) ou lira (pour le back bean) la valeur dans le ServletContext.

Utilisation :

Notre Listener comportra une réference vers tous les EJB utilisés (un seul dans mon exemple), et l'implémentation de la méthode contextInitialized sera toute simple :

public class testEJBInjectionListener implements ServletContextListener {

@EJB(name = "Addition/Local")

public AdditionRemote ar;

public void contextDestroyed(ServletContextEvent arg0) {

// TODO Auto-generated method stub

}

public void contextInitialized(ServletContextEvent arg0) {

tools.EJB_Initialiser.saveMyEJBs(arg0.getServletContext(),this);

}

}




Du coté du back bean, rien de plus compliqué. On fait une référence vers les EJB que l'on souhaite utiliser en conservant l'injection :

public class testBackBean {

@EJB(name = "Addition/Local")

public AdditionRemote ar;

public testBackBean()

{

tools.EJB_Initialiser.injecterMesEJB(this);

}

}


La classe utilitaire InitialiserEJB fesant le reste : télécharger la classe.

Au niveau des performances ce n'est pas terrible du tout car cela effectue un lock sur l'instance des l'EJB coté serveur (car une seule instance dans le contexte application), aucun accès concurant ne sera donc possible et il faudra attendre gentiment son tour pour accéder au bean session. A utiliser donc en attendant JSF 1.2 !