Auteur    :    Stéphane TRAUMAT ( Ashita-studio )
Je veux �tre tenu au
courant des mises à jour
de ce tutorial
Date de dernière mise à jour    :    02/12/2002
Index du tutorial    :    http://www.ashita-studio.com/tutoriaux/ejb/index.php
Adresse du document    :    http://www.ashita-studio.com/tutoriaux/ejb/chapitre_03.php


Chapitre 03 : Notre premier EJB


  1. Introduction

    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.


  2. Ecriture du composant 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).

    1. Interface distante

      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.

    2. Interface locale

      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.

    3. L'Entreprise JavaBean

      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.



  3. Création des descripteurs de déploiement de notre EJB

    Pour un EJB, il y a deux descripteurs : Le descripteur standard de sun et le descripteur spécifique à JOnAS.

    1. Descripteur de déploiement standard

      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>





    2. Descripteur de déploiement spécifique à JOnAS

      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.


  4. Packaging de notre EJB

    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 ).



  5. Déploiement de l'EJB

    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.


  6. Création du client de l'EJB

    Voici ce que nous allons faire dans le code du client de notre EJB :

    1. Trouver l'interface locale.

      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);

    2. Créer une instance de HelloWorld.

      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();

    3. Invoquer la méthode sayHello().

      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



  7. Réalisation de la compilation, du packaging et du déploiement

    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.


  8. Test de notre EJB

    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é.


  9. Conclusion

    Nous avons vu dans ce chapitre les étapes de la rédaction d'un EJB :

    1. Ecriture du composant
      • Ecriture de l'interface distante
      • Ecriture de l'interface locale
      • Ecriture de l'Enterprise JavaBean
    2. Rédaction des descripteurs de déploiement
    3. Packaging de notre Enterprise JavaBean
    4. 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.



Auteur : Stéphane TRAUMAT
Société SCUB et Ashita-studio
Valid HTML 4.01! Valid CSS!