-
Nous allons commencer par développer un petit EJB très simple qui va se contenter de nous renvoyer "Bonjour monde". Pour réaliser l'exemple de ce chapitre, créez, à la racine de "c:\java\dev", un répertoire "HelloWorld" dans lequel vous mettrez tous vos fichiers. Nous allons détailler toutes les étapes de la construction de notre Enterprise JavaBean et nous présenterons, à la fin, le script qui se chargera de la compilation, du packaging et déploiement de notre EJB.
-
Notre composant EJB se compose de 3 entités :
- L'interface distante qui contient les méthodes qu'un client de cet EJB peut appeler.
- L'interface locale qui définit les méthodes qu'un client peut invoquer pour créer, trouver ou supprimer l'EJB.
- L'Enterprise JavaBean qui est le composant.
Ces trois fichiers appartiendront au package sb (simple bean).
-
Cette interface va définir toutes les méthodes fonctionnelles ( business method ) qu'un client peut invoquer sur notre composant.
HelloWorld.java
|
1 2 3 4 5 6 7 8 9 10
|
package sb;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
public interface HelloWorld extends EJBObject {
public String sayHello() throws RemoteException;
}
|
|
Java2html
|
Il est très important de comprendre que cette interface spécifie l'ensemble des fonctions qu'un client peut appeler.
-
Cette interface définit les méthodes qu'un client peut invoquer pour créer, trouver ou supprimer un EJB.
HelloWorldHome.java
|
1 2 3 4 5 6 7 8 9 10
11 12
|
package sb;
import java.io.Serializable;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
public interface HelloWorldHome extends EJBHome {
HelloWorld create() throws RemoteException, CreateException;
}
|
|
Java2html
|
Lorsqu'un client veut utiliser un EJB, il se sert de JNDI pour obtenir une référence à un objet qui est une instance de l'interface locale. Comme vous pouvez le constater, la méthode create() qui est appelée retourne un objet de type HelloWorld ( type de notre interface distante ).
Le client va donc pouvoir utiliser cette instance du même type que l'interface distante pour invoquer les méthodes de l'EJB.
-
Nous allons maintenant coder notre EJB pour implémenter les fonctions que l'on a "promis" au client dans l'interface distante, c'est à dire la fonction sayHello().
HelloWorldBean.java
|
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
|
package sb;
import java.rmi.RemoteException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
public class HelloWorldBean implements SessionBean {
public String sayHello() {
return "Bonjour monde";
}
public void ejbCreate() {}
public void ejbRemove() {}
public void ejbActivate() {}
public void ejbPassivate() {}
public void setSessionContext(SessionContext sc) {}
}
|
|
Java2html
|
Notre EJB implémente l'interface SessionBean ce qui nous oblige à implémenter les interfaces suivantes :
- ejbActivate()
- ejbPassivate()
- ejbRemove()
- setSessionContext()
Ces méthodes sont invoquées par le conteneur pour notifier à votre EJB qu'un évènement s'est produit.
La méthode setSessionContext() est appelée immédiatement après l'instanciation du composant par le container. Elle reçoit un argument de type SessionContext que le composant peut utiliser pour faire appel aux services du conteneur.
Après setSessionContext() le container appelle la méthode ejbCreate().
Note : Pour chaque méthode create() définie dans son interface locale, le composant doit implémenter une méthode ejbCreate() correspondante, retournant void et contenant le même nombre et le même type d'arguments que la méthode create() source.
-
Pour un EJB, il y a deux descripteurs : Le descripteur standard de sun et le descripteur spécifique à JOnAS.
-
Le programmeur de l'EJB doit fournir avec son composant un descripteur de déploiement. Ce fichier décrit par exemple quelle classe est l'implémentation, l'interface locale et l'interface distante de l'EJB.
Ce fichier doit s'appeler ejb-jar.xml.
| ejb-jar.xml |
|
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
<description>Déscripteur de déploiement de HelloWorld</description>
<display-name>HelloWorld</display-name>
<enterprise-beans>
<session>
<description>Déscripteur de déploiement de HelloWorld</description>
<display-name>HelloWorld</display-name>
<ejb-name>HelloWorld</ejb-name>
<home>sb.HelloWorldHome</home>
<remote>sb.HelloWorld</remote>
<ejb-class>sb.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>
|
-
Certaines informations nécessaires au déploiement de l'EJB dans JOnAS ne sont pas dans la DTD précédente. Pour résoudre ce problème, il faut créer un autre descripteur de déploiement spécifique à JOnAS dont vous pourrez trouver la DTD à l'adresse suivante : http://www.objectweb.org/jonas/dtds/jonas-ejb-jar_2_4.dtd. Ce document devra s'appeler jonas-ejb-jar.xml.
| jonas-ejb-jar.xml |
|
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE jonas-ejb-jar PUBLIC "-//ObjectWeb//DTD JOnAS 2.4//EN" "http://www.objectweb.org/jonas/dtds/jonas-ejb-jar_2_4.dtd">
<jonas-ejb-jar>
<jonas-session>
<ejb-name>HelloWorld</ejb-name>
<jndi-name>MyHelloWorld</jndi-name>
</jonas-session>
</jonas-ejb-jar>
|
Le fichier ci-dessus spécifie le nom JNDI de l'objet qui est l'interface Home du bean. C'est ce nom JNDI que les clients de notre application vont appeler pour accéder à l'interface locale de notre EJB.
Note : Certains tags des deux fichiers précédents peuvent vous paraître obscurs, je ne me suis pas attardé dessus volontairement, nous explorerons ces fichiers durant les prochains chapitres.
-
Notre EJB doit être packagé dans une archive JAR qui devra contenir :
- Les classes de l'EJB.
- Les deux descripteurs de déploiements (
ejb-jar.xml et jonas-ejb-jar.xml ).
-
Pour déployer notre EJB sous JOnAS, notre fichier ejb-jar doit posséder les classes d'interposition interfacant notre Entreprise JavaBean avec les services offerts par notre Serveur d'EJB. Ces classes vont être crées à l'aide de l'utilitaire GenIC fourni avec JOnAS.
Ensuite, pour déployer notre EJB dans JOnAS, il suffira de copier le fichier .jar vers le répertoire "C:\java\plateforme\jonas\ejbjars" et de modifier la configuration de JOnAS.
-
Voici ce que nous allons faire dans le code du client de notre EJB :
-
Tout d'abord, nous allons récupérer un contexte de nom JNDI. Un contexte se définit par un ensemble de liaisons nom/objet, et contient des méthodes pour examiner et mettre à jour ces liens.
initialContext = new InitialContext();
A partir du nom JNDI que nous avons spécifié dans le fichier jonas-ejb-jar.xml, la ligne de code suivante retrouve l'objet associé à ce nom.
Object objref = initialContext.lookup("MyHelloWorld");
Puis, à l'aide de la méthode narrow() on vérifie qu'un objet correspondant à une interface distante ou abstraite peut être projeté vers un type voulu.
HelloWorldHome home = (HelloWorldHome)PortableRemoteObject.narrow(objref, HelloWorldHome.class);
-
La méthode create() retourne un objet de type HelloWorld ( C'est à dire ayant le même type que l'interface distante, l'interface qui décrit les méthodes qu'un client de cet EJB peut appeler ).
HelloWorld myHelloWorld = home.create();
-
Le client invoque la méthode sayHello() de l'interface distante qui va dire au container d'appeler la méthode correspondante de HelloWorldBean qui, lui, est sur le serveur JOnAS.
String message = myHelloWorld.sayHello();
System.out.println(message);
Note : Ce client devra être lancé avec l'utilitaire jclient qui est fourni avec JOnAS.
Voici le code complet de notre client EJB :
HelloWorldClient.java
|
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44
|
package sb;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.Context;
import javax.transaction.UserTransaction;
import javax.rmi.PortableRemoteObject;
public class HelloWorldClient {
public static void main(String args[]) {
// Récupération du contexte initial
Context initialContext = null;
try {
initialContext = new InitialContext();
} catch (Exception e) {
System.err.println("Impossible d'accéder au contexte JNDI : " + e);
System.exit(2);
}
// Récupération d'une référence à l'interface locale
HelloWorldHome home = null;
try {
home = (HelloWorldHome)PortableRemoteObject.narrow(initialContext.lookup("MyHelloWorld"), HelloWorldHome.class);
} catch (Exception e) {
System.err.println( "Impossible de trouver HelloWorldHome : " + e);
System.exit(2);
}
// Création d'un objet de même type que l'interafce distante
// et appel de la fonction sayHello()
HelloWorld myHelloWorld = null;
try {
myHelloWorld = home.create();
System.out.println(myHelloWorld.sayHello());
} catch (Exception e) {
System.err.println("Impossible de créer le bean : " + e);
System.exit(2);
}
}
}
|
|
Java2html
|
-
Pour réaliser la compilation, le packaging et le déploiement, nous allons utiliser un script que nous placerons dans le répertoire "C:\java\dev\HelloWorld".
Voici le source du fichier :
build.bat
|
@Echo off
REM Spécifie que les SET qui seront faits dans ce fichier ne seront valable que pendant l'éxecution de ce fichier
setlocal
echo ************************************************************************************
echo Compilation de l'Enterprise JavaBeans HelloWorld
echo ************************************************************************************
echo.
echo.
echo ************************************************************************************
echo Mets en place les variables d'environnement
call %JONAS_ROOT%\bin\nt\setenv.bat
Set BUILD_DIR=C:\java\dev\build
echo ************************************************************************************
echo.
echo ************************************************************************************
echo Modifie le classpath
set CLASSPATH=%CLASSPATH%;%BUILD_DIR%
set CLASSPATH=%CLASSPATH%;%J2EE_HOME%\lib\j2ee.jar
set CLASSPATH=%CLASSPATH%;%JONAS_ROOT%\lib\common\j2ee\ejb.jar
echo ************************************************************************************
echo.
echo ************************************************************************************
echo Compile les fichiers sources de l'EJB et les mets dans le répertoire de construction
%JAVAC% -d %BUILD_DIR% HelloWorld.java HelloWorldHome.java HelloWorldBean.java
echo ************************************************************************************
echo.
echo ************************************************************************************
echo Compile le Client de l'EJB et le mets dans le répertoire de construction
%JAVAC% -d %BUILD_DIR% HelloWorldClient.java
echo ************************************************************************************
echo.
echo ************************************************************************************
echo Construit l'EJB
copy ejb-jar.xml %BUILD_DIR%\META-INF\ejb-jar.xml
copy jonas-ejb-jar.xml %BUILD_DIR%\META-INF\jonas-ejb-jar.xml
cd %BUILD_DIR%
jar cvf sb\HelloWorld.jar META-INF\ejb-jar.xml META-INF\jonas-ejb-jar.xml sb\HelloWorld.class sb\HelloWorldBean.class sb\HelloWorldHome.class
del META-INF\ejb-jar.xml META-INF\jonas-ejb-jar.xml
echo ************************************************************************************
echo.
echo ************************************************************************************
echo Génère les classes d'interposition avec GenIC
call %JONAS_ROOT%\bin\nt\GenIC.bat -classpath C:\java\dev\build -d %BUILD_DIR% -keepgenerated %BUILD_DIR%\sb\HelloWorld.jar
echo ************************************************************************************
echo.
echo ************************************************************************************
echo Installation notre EJB
copy %BUILD_DIR%\sb\HelloWorld.jar %JONAS_ROOT%\ejbjars\HelloWorld.jar
echo ************************************************************************************
echo.
cd C:\java\dev\HelloWorld
|
Le fichier précédent effectuera la compilation, le packaging et le déploiement de notre ejb ainsi que la compilation de notre client.
Vous devrez ensuite éditer le fichier jonas.properties qui se trouve "C:\java\plateforme\jonas\config" pour modifier la ligne jonas.service.ejb.descriptors et y ajouter HelloWorld.jar.
note : Les noms des différents fichiers jar à charger dans JOnAS doivent être spécifiés les uns à la suite des autres séparé d'une virgule sur la ligne jonas.service.ejb.descriptors.
-
Afin de tester notre application, nous allons lancer notre HelloWorldClient et voir s'il réussit à récupérer le message que notre EJB doit lui renvoyer. Pour cela faites :
- cd C:\java\dev\HelloWorld
- build
- jonas start
- cd C:\java\dev\build
- jclient -cp sb.HelloWorld.jar sb.HelloWorldClient
Vous devriez voir s'afficher à l'écran "Bonjour le Monde!". Si c'est le cas, félicitations, vous venez de réaliser votre premier EJB qui marche :)
note : Vous devez vous demander comment notre client a trouvé le serveur d'application non ? C'est très simple, le client utilise JNDI et si vous regardez le fichier jndi.properties, vous y verrez que tout y est spécifié.
-
Nous avons vu dans ce chapitre les étapes de la rédaction d'un EJB :
- Ecriture du composant
- Ecriture de l'interface distante
- Ecriture de l'interface locale
- Ecriture de l'Enterprise JavaBean
- Rédaction des descripteurs de déploiement
- Packaging de notre Enterprise JavaBean
- Déploiement dans le conteneur
Cela peut paraître un peu compliqué et un peu long mais vous verrez dans les prochains chapitres que ce processus n'est pas si complexe et qu'il permet une grande souplesse et une réutilisation aisée des composants développés.
|
|