Objectif : installer un EJB dans le serveur d'applications JOnAS et faire un appel via la console DOS.
JOnAS permet de mettre sur le réseau RMI (CORBA) des objets, accessibles par des applications J2EE hébergées, mais aussi d'autres application, pas forcément J2EE, et pas forcément en JAVA. Dans cet exemple, l'objet est accédé par un programme DOS (en JAVA), un client de JOnAS.
Coté serveur :
- Interface de l'objet EJB : "HelloWorld.java"
- Bean, objet métier, définissant les méthodes qui seront appelées par un client : "HelloWorldBean.java"
- Iterface de fabrique de Bean : "HelloWorldHome.java"
- Description de l'objet permettant son déploiement : "ejb-jar.xml"
- Description de l'accès au Bean (par un nom unique dans le serveur) : "jonas-ejb-jar.xml"
- Accessoirement, le fichier de compilation de l'EJB : "build.xml"
- Le programme client : "HelloClient.java"
- Une copie (ou extraction de certaines classes) du JAR déployé sur le serveur : "FirstEJB.jar"
- Accessoirement, un batch de test : "test.bat"
Fichiers à destination du serveur
"HelloWorld.java" | ||
---|---|---|
package helloWorld; import java.rmi.RemoteException; import javax.ejb.EJBObject; public interface HelloWorld extends EJBObject { public String sayHello() throws RemoteException; } |
||
Cette interface permet de spécifier quelles méthodes sont utilisables avec l'objet partagé. Dans notre cas, une seule méthode "sayHello()" sera le point d'entrée du l'objet.
"HelloWorldBean.java" | ||
---|---|---|
package helloWorld; import java.rmi.RemoteException; import javax.ejb.EJBException; import javax.ejb.SessionBean; import javax.ejb.SessionContext; public class HelloWorldBean implements SessionBean { protected SessionContext ctx; private static final long serialVersionUID = 1L; public String sayHello() { return "Hello, world !"; } public void ejbCreate() {} public void ejbActivate() throws EJBException, RemoteException {} public void ejbPassivate() throws EJBException, RemoteException {} public void ejbRemove() throws EJBException, RemoteException {} public void setSessionContext(SessionContext arg0) throws EJBException, RemoteException { ctx = arg0; } } |
||
Notre Bean sera pourvu d'un numéro de série (unique dans le serveur qui l'héberge). Pour notre cas, peut importe.
Il implémente la péthode déclarée dans son interface : "sayHello()".
Il impémente aussi les autres méthodes
de
SessionBean :
"ejbCreate()" : appel lors de la création du Bean
en session
"ejbActivate()" : appel lors de l'activation du Bean
(après sa création, avant son utilisation)
"ejbPassivate()" : appel lors de la desactivation du Bean
(après la fin de son utilisation)
"ejbRemove()" : appel lors de la suppression du bean en session
- Question : Quel lien y a-t-il entre l'EJBObject et le SessionBean ?
- Réponse : ??
- Question : Faut-il implémenter toutes les méthodes ?
- Réponse : non, il est seulement necessaire d'implémenter "ejbActivate()", "ejbPassivate()", "ejbPassivate()", "ejbRemove()" et "setSessionContext()".
"HelloWorldHome.java" | ||
---|---|---|
package helloWorld; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome; public interface HelloWorldHome extends EJBHome { public HelloWorld create() throws CreateException, RemoteException; } |
||
Cette surcharge permet uniquement de préciser que l'objet retourné par la méthode "create()" est de la classe "HelloWorld".
"ejb-jar.xml" | ||
---|---|---|
<?xml version="1.0" encoding="ISO-8859-1"?> <ejb-jar> <description>HelloWorld deployment descriptor</description> <display-name>HelloWorld</display-name> <enterprise-beans> <session> <description>HelloWorld deployment descriptor</description> <display-name>HelloWorld</display-name> <ejb-name>HelloWorld</ejb-name> <home>helloWorld.HelloWorldHome</home> <remote>helloWorld.HelloWorld</remote> <ejb-class>helloWorld.HelloWorldBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> </session> </enterprise-beans> <assembly-descriptor> <container-transaction> <method> <ejb-name>HelloWorld</ejb-name> <method-name>*</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> </assembly-descriptor> </ejb-jar> |
||
Dans la description de l'EJB, on retrouve toutes les classes définies précédemment, avec leur package.
"jonas-ejb-jar.xml" | ||
---|---|---|
<?xml version="1.0" encoding="ISO-8859-1"?> <jonas-ejb-jar> <jonas-session> <ejb-name>HelloWorld</ejb-name> <jndi-name>myHelloWorld</jndi-name> </jonas-session> </jonas-ejb-jar> |
||
L'EJB "HelloWorld" est accessible sur le réseau par l'identifiant "myHelloWorld". Coté client, cette information est primordiale,en plus des classes et interfaces.
Fichiers à destination du client
"HelloClient.java" | ||
---|---|---|
package client; import helloWorld.HelloWorld; import helloWorld.HelloWorldHome; import javax.naming.InitialContext; import javax.naming.Context; import javax.rmi.PortableRemoteObject; public class HelloClient { public static void main(String[] args) { Context initialContext = null; try { initialContext = new InitialContext(); } catch (Exception e) { System.err.println("Cannot get initial context for JNDI: " + e); System.exit(2); } try { Object objref = initialContext.lookup("myHelloWorld"); HelloWorldHome home = (HelloWorldHome)PortableRemoteObject.narrow( objref, HelloWorldHome.class); HelloWorld myHelloWorld = home.create(); String message = myHelloWorld.sayHello(); System.out.println(message); } catch (Exception e) { System.err.println(" Erreur : " + e); System.exit(2); } } } |
||
Le code client se décompose en :
- Récupérer du contexte : "initialContext"
- Rechercher l'objet référencé par "myHelloWorld"
- Récupérer la fabrique
- Créer une instance de "HelloWorld" via la fabrique
- Appel de la méthode "sayHello()"
- Affichage du message
- Question : Sur quel contexte est-on placé ? Comment changer de contexte ?
- Reponse : ???
Compilation
"build.xml" | ||
---|---|---|
<?xml version="1.0" encoding="ISO-8859-1"?> |
||
Le fichier "build.xml" permet d'automatiser la compilation et la génération du JAR à déployer.
Execution du test
Une fois le JAR généré, il faut le déployer dans JOnAS, en utilisant par exemple l'interface d'administrationWEB.
Le JAR est ensuite copié, modifié et stocké dans le répertoire JONAS_DIR/ejbjars/. C'est ce JAR qu'il faut utiliser pour le client. Le JAR formé avec le "build.xml" ne contient pas les classes STUB ni SKEL de l'EJB.
Il faut copier le fichier JONAS_DIR/ejbjars/FirstEJB.jar dans un répertoire de test et lancer la commande suivante :
jclient -cp C:\home\j_co\apps\JOnAS-4.7.7\ejbjars\FirstEJB.jar client.HelloClient
Conclusion
Ce petit exemple ne montre qu'un des quatre types d'EJB...
Personnellement, je trouve ce cas (minimal) asser complexe
: les
configurations par défaut (rien n'est
spécifié),
l'astuce de prendre un autre JAR que celui qu'on a
créé.
Contrairement à CORBA, on ne peut pas changer de langage
pour developper son application.
L'utilisation des EJB est possible lorsque l'option "base de
données" n'est pas envisageable et que l'autre recours est
le
"fichier" pour communiquer entre les applications. On peut aussi penser
à un serveur HTTP (ou d'un autre protocole) qui
reçoit
des messages en XML, mais la spécification et le respect des
règles de formatage est certainement plus complexe
à
mettre en oeuvre et à faire respecter.
Autre piste : "Hibernate". Ce principe revient à mettre sous
forme de table SQL un objet que l'on voudrait sauvegarder en base.
Lorsqu'on se place dans un environnement JAVA, on ne quitte plus ce langage d'une application à une autre. Tous le developpeurs ont la contrainte de respecter la même syntaxe (appel de méthodes), de lire les mêmes spécifications (fichiers "ejb-jar.xml").
Page accedée 1 fois.