Accéder à un EJB distant dans JBoss AS 7



Dans JBoss AS 7, beaucoup de choses ont changé, y compris la façon dont le registre JNDI est organisé et dont un client peut accéder à un EJB distant. Voici un résumé de la façon de procéder dans JBoss AS 7.1 (la première version à supporter pleinement le remoting).

Avant JBoss AS 7

Avec les versions précédentes de JBoss, pour accéder à un EJB distant on instanciait un contexte de nommage à qui on demandait de nous donner un proxy sur l'EJB.

namingContext = new InitialContext();
messageServiceEjb = (MessageService) namingContext.lookup("swmsg-app/MessageServiceBean/remote");
messageService.getMessage(id);

Pour que ceci fonctionne, on avait besoin d'un fichier jndi.properties dans le classpath du client.

#jndi.properties
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=jnp://localhost:1099
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

Pour que les communications passent entre le client et le serveur, il fallait que le serveur puisse recevoir des connexions sur les ports 1099, 1098 et 4446.

Avec le client EJB de JBoss AS 7

Dans JBoss AS 7, le fonctionnement a radicalement changé, même si le code ressemble beaucoup. En effet, on instancie toujours un contexte initial et on demande une référence à l'EJB distant.

namingContext = new InitialContext();
messageServiceEjb = (MessageService) namingContext.lookup("ejb:swmsg-app/swmsg-ejb3//MessageServiceBean!fr.sewatech.formation.appserv.service.MessageService");
messageService.getMessage(id);

En fait, seul le nom JNDI de l'EJB a changé. Il a même changé de façon assez radicale puisqu'on notera ce préfixe (ou namespace) "ejb:". Ce namespace n'existe pas en tant que tel dans le registre JNDI du serveur ; il sert au client JNDI à adresser sa demande au client EJB de JBoss. De ce fait, le fichier jndi.properties a bien changé, il n'y a plus besoin de NamingContextFactory, ni d'url du serveur.

#jndi.properties
java.naming.factory.url.pkgs=org.jboss.ejb.client.naming

Les informations sur le serveur sont à présent dans le fichier jboss-ejb-client.properties, lui aussi dans le classpath.

#jboss-ejb-client.properties
endpoint.name=client-endpoint
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false

remote.connections=default

remote.connection.default.host=127.0.0.1
remote.connection.default.port=4447
remote.connection.default.username=alexis
remote.connection.default.password=hassler

Le port 4447 est celui du composant remoting, c'est le seul utilisé pour la communication depuis le client. Et comme, dans JBoss AS 7.1, JNDI est sécurisé par défaut. Il faut donc ajouter un utilisateur de type Application, avec la commande add-user.

Ce fonctionnement est un hybride entre l'accès par JNDI et l'accès direct à l'EJB. En utilisant l'API de client EJB de JBoss, on pourrait même se passer de JNDI.

Comme avant, par JNDI

Le fonctionnement classique par JNDI a été conservé pour faciliter la transition vers JBoss AS 7. Il semble que ce mode classique pourrait ne pas être conservé dans l'avenir.

Dans ce mode, on utilise le nom JNDI exporté de l'EJB.

namingContext = new InitialContext();
messageServiceEjb = (MessageService) namingContext.lookup("swmsg-app/swmsg-ejb3/MessageServiceBean!fr.sewatech.formation.appserv.service.MessageService");
messageService.getMessage(id);

Ce nom exporté correspond au nom "java:jboss/exported/...".

Le fichier jndi.properties devient

#jndi.properties
java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory
java.naming.provider.url=remote://localhost:4447
java.naming.security.principal=alexis
java.naming.security.credentials=hassler
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false

Références

Il y a une page dédiée à ce sujet dans la documentation de JBoss AS 7.1.