Académique Documents
Professionnel Documents
Culture Documents
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
[ Viewing Hints ] [ Revision History ] [ Report an Error ] [ 1st Edition ] [ Free Newsletter ] [ Seminars ] [ Seminars on CD ROM ] [ Consulting ]
Interfaces Remote
RMI utilise beaucoup d'interfaces. Lorsque l'on souhaite crer un objet distant, l'implmentation sous-jacente est masque en passant par une interface. Ainsi, lorsque qu'un client obtient une rfrence vers un objet distant, ce qu'il possde rellement est une rfrence intermdiaire, qui renvoie un bout de code local capable de communiquer travers le rseau. Mais nul besoin de se soucier de cela, il suffit de juste d'envoyer des messages par le biais de cette rfrence intermdiaire. La cration d'une interface distante doit respecter ces directives : 1. L'interface distante doit tre public (il ne peut y avoir accs package , autrement dit d'accs friendly). Sinon, le client recevra une erreur lorsqu'il tentera d'obtenir un objet distant qui implmente l'interface distante. 2. L'interface distante doit hriter de l'interface java.rmi.Remote. 3. Chaque mthode de l'interface distante doit dclarer java.rmi.RemoteException dans sa clause throws en plus des autres exceptions spcifiques l'application. 4. Un objet distant pass en argument ou en valeur de retour (soit directement ou inclus dans un objet local), doit tre dclar en tant qu'interface distante et non comme la classe d'implmentation. Voici une interface distante simple qui reprsente un service d'heure exacte :
1 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
//: c15:rmi:PerfectTimeI.java // L'interface distante PerfectTime. package c15.rmi; import java.rmi.*; interface PerfectTimeI extends Remote { long getPerfectTime() throws RemoteException; } ///:~ Cela ressemble n'importe quelle autre interface mis part qu'elle hrite de Remote et que toutes ses mthodes mettent RemoteException. Rappelez vous qu'une interface et toutes ses mthodes sont automatiquement publiques.
2 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
PerfectTime pt = new PerfectTime(); Naming.bind( "//peppy:2005/PerfectTime", pt); System.out.println("Ready to do time"); } catch(Exception e) { e.printStackTrace(); } } } ///:~ Ici, main( ) se charge de tous les dtails de mise en place du serveur. Une application qui met en service des objets RMI doit un moment : 1. Crer et installer un gestionnaire de scurit qui supporte RMI. Le seul disponible pour RMI fourni dans la distribution Java est RMISecurityManager. 2. Crer une ou plusieurs instances de l'objet distant. Ici, vous pouvez voir la cration de l'objet PerfectTime. 3. Enregistrer au moins un des objets distants grce au registre d'objets distants RMI pour des raisons d'amorage. Un objet distant peut avoir des mthodes qui retournent des rfrences vers les autres objets distants. En le mettant en place, le client ne doit s'adresser au registre qu'une seule fois pour obtenir ce premier objet distant. Mise en place du registre Ici, vous pouvez voir un appel la mthode statique Naming.bind( ). Toutefois, cet appel ncessite que le registre fonctionne dans un autre processus de l'ordinateur. Le nom du registre serveur est rmiregistry, et sous Windows 32-bit vous utiliserez : start rmiregistry
Comme beaucoup d'applications rseau, le rmiregistry est localis l'adresse IP de la machine qui l'a dmarr, mais il doit aussi couter un port. Si vous invoquez le rmiregistry comme ci-dessus, sans argument, le port cout par le registre sera par dfaut 1099. Si vous souhaitez que ce soit un autre port, vous devez ajouter un argument la ligne de commande pour le prciser. Dans cet exemple, le port sera 2005, ainsi le rmiregistry devra tre dmarr de cette manire sous Windows 32-bit : start rmiregistry 2005
L'information concernant le port doit aussi tre fourni la commande bind( ), ainsi que l'adresse IP de la machine o se trouve le registre. Mais il faut mentionner que cela peut tre un problme frustrant en cas de tests de programmes RMI en local (de la mme manire que les programmes rseau tests plus loin dans ce chapitre).
3 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
En effet dans le JDK version 1.1.1, il y a quelques problmes : [69] 1. localhost ne fonctionne pas avec RMI. Aussi, pour faire une exprience avec RMI sur une seule machine, vous devez fournir le nom de la machine. Pour dcouvrir le nom de votre machine sous Windows 32-bit, allez dans le Panneau de configuration et slectionnez Rseau. Slectionnez l'onglet Identification , vous verrez apparatre le nom de l'ordinateur. Dans mon cas, j'ai appel mon ordinateur Peppy . Il semble que la diffrence entre majuscules et minuscules soit ignore. 2. RMI ne fonctionnera pas moins que votre ordinateur ait une connexion TCP/IP active, mme si tous vos composants discutent entre eux sur la machine locale. Cela signifie que vous devez vous connecter Internet pour essayer de faire fonctionner le programme ou vous obtiendrez quelques messages d'exception obscurs. En ayant tout cela l'esprit, la commande bind( ) devient : Naming.bind("//peppy:2005/PerfectTime", pt);
Si vous utilisez le port par dfaut 1099, nul besoin de prciser le port, donc vous pouvez dire : Naming.bind("//peppy/PerfectTime", pt);
Vous devriez tre capable de raliser un test local en omettant l'adresse IP et en utilisant simplement l'identifiant : Naming.bind("PerfectTime", pt);
Le nom pour le service est arbitraire ; il se trouve que c'est PerfectTime ici, comme le nom de la classe, mais un tout autre nom conviendrait. L'important est que ce nom soit unique dans le registre, connu par le client pour qu'il puisse se procurer l'objet distant. Si le nom est dj utilis dans le registre, celui renvoie une AlreadyBoundException. Pour viter cela, il faut passer chaque fois par un appel rebind( ) la place de bind( ), en effet rebind( ) soit ajoute une nouvelle entre, soit remplace celle existant dj. Durant l'excution de main( ), l'objet a t cr et enregistr, il reste ainsi en activit dans le registre, attendant qu'un client arrive et fasse appel lui. Tant que rmiregistry fonctionne et que Naming.unbind( ) n'est pas appel avec le nom choisi, l'objet sera prsent. C'est pour cela que lors de la conception du code, il faut redmarrer rmiregistry aprs chaque compilation d'une nouvelle version de l'objet distant. rmiregistry n'est pas forcment dmarr en tant que processus externe. S'il est sr que l'application est la seule qui utilise le registre, celui peut tre mis en fonction l'intrieur mme du programme grce cette ligne : LocateRegistry.createRegistry(2005);
Comme auparavant, nous utilisons le numro de port 2005 dans cet exemple. C'est quivalent au fait de lancer rmiregistry 2005 depuis la ligne de commande, mais c'est souvent plus pratique lorsque l'on dveloppez son code RMI puisque cela limine les tapes supplmentaires qui consistent arrter et redmarrer le registre. Une fois cette instruction excute, la mthode bind( ) de la classe Naming peut tre utilise comme prcdemment.
4 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
Si l'on compile et excute PerfectTime.java, cela ne fonctionnera pas mme si rmiregistry a t correctement mis en route. Cela parce que la machinerie pour RMI n'est pas complte. Il faut d'abord crer les stubs et skeletons qui assurent les oprations de connexions rseaux et permettent de faire comme si l'objet distant tait juste un objet local sur de la machine. Ce qui se passe derrire la scne est complexe. Tous les objets envoys un objet distant ou reus de celui-ci doivent implmenter Serializable (pour passer des rfrences distantes plutt que les objets complets, les arguments peuvent implmenter Remote), ainsi on peut considrer que les stubs et les skeletons assurent automatiquement la srialisation et la dserialisation tout en grant l'acheminement des arguments et du rsultat au travers du rseau. Par chance, vous n'avez rien connatre de tout cela, mais vous devez avoir cr les stubs et les skeletons. C'est une procdure simple : on invoque l'outil rmic sur le code compil, et il cre les fichiers ncessaires. La seule chose obligatoire est donc d'ajouter cette tape la procdure de compilation. L'outil rmic est particulier en ce qui concerne les packages et les classpaths. PerfectTime.java est dans le package c15.rmi, et mme rmic est invoqu dans le mme rpertoire que celui o se trouve PerfectTime.class, rmic ne trouvera pas le fichier, puisqu'il se repre grce au classpath. Vous devez ainsi prciser la localisation du classpath, comme ceci : rmic c15.rmi.PerfectTime
La commande ne ncessite pas d'tre excute partir du rpertoire contenant PerfectTime.class, mais les rsultats seront placs dans le rpertoire courant. Lorsque rmic a t excut avec succs, deux nouvelles classes sont obtenues dans le rpertoire : PerfectTime_Stub.class PerfectTime_Skel.class correspondant au stub et au skeleton. Ds lors, vous tes prt faire communiquer le serveur et le client.
5 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
System.out.println("Perfect time = " + t.getPerfectTime()); } catch(Exception e) { e.printStackTrace(); } } } ///:~ L'identifiant alpha-numrique est le mme que celui utilis pour enregistrer l'objet avec Naming, et la premire partie reprsente l'adresse et le numro du port. Cette URL permet par exemple de dsigner une machine sur Internet. Ce qui est retourn par Naming.lookup( ) doit tre transtyp vers l'interface distante, pas vers la classe. Si l'utilisation de la classe la place renverrait une exception. Vous pouvez observer dans l'appel de la mthode t.getPerfectTime( )
qu'une fois la rfrence vers l'objet distant obtenue, la programmation avec celle-ci ou avec un object distant est identique (avec une diffrence : les mthodes distantes mettent RemoteException).
Introduction CORBA
Dans le cadre d'importantes applications distribues, vos besoins risquent de ne pas tre satisfaits par les approches prcdentes : comme par exemple, l'intgration de bases existantes, ou l'accs aux services d'un objet serveur sans se soucier de sa localisation physique. Ces situations ncessitent une certaine forme de Remote Procedure Call (RPC), et peut-tre une indpendance par rapport au langage. L, CORBA peut vous aider. CORBA n'est pas une fonctionnalit du langage ; c'est une technologie d'integration. C'est une spcification que les fabricants peuvent suivre pour implmenter des produits supportant une intgration CORBA. CORBA fait partie du travail ralis par OMG afin de dfinir une structure standard pour l'interoprabilit d'objets distribus et indpendants du langage. CORBA fournit la possibilit de faire des appels des procdures distantes dans des objets Java et des objets non-Java, et d'interfacer des systmes existants sans se soucier de leur emplacement. Java ajoute un support rseau et un langage orient-objet agrable pour construire des applications graphiques ou non. Le modle objet de l'OMG et celui de Java vont bien ensemble ; par exemple, Java et CORBA mettent tout deux en oeuvre le concept d'interface et le modle de rfrence objet.
6 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
sans rien connatre de leur emplacement physique. Cela signifie que ce qui ressemble un appel de mthode dans le code client est vraiment une opration complexe. D'abord, une connexion avec l'objet servant doit exister et pour crer cette connexion, l'ORB doit savoir o se trouve le code implmentant cette partie serveur. Une fois que la connexion est tablie, les arguments de la mthode doivent tre arrangs (marshaled), c'est dire convertis en un flux binaire pour tre envoys travers le rseau. Les autres informations qui doivent tre envoyes sont le nom de la machine serveur, le processus serveur et l'identit de l'objet servant au sein de ce processus. Finalement, l'information est envoye par l'intermdiaire d'un protocole bas-niveau, elle est dcode du ct du serveur, l'appel est excut. L'ORB masque tout de cette complexit au programmeur et rend l'opration presque aussi simple que l'appel d'une mthode d'un objet local. Cette spcification n'a pas pour but d'expliquer comment le coeur de l'ORB devrait tre implment, mais elle permet une compatibilit fondamentale entre les diffrents ORBs des fournisseurs, l'OMG dfinit un ensemble de services qui sont accessibles par l'intermdiaire d'interfaces standards. CORBA Interface Definition Language (IDL - Langage de Dfinition d'Interface) CORBA a t mis au point pour tre transparent vis--vis du langage : un objet client peut appeler des mthodes d'un objet serveur d'une classe diffrente, sans se proccuper du langage avec lequel elles sont implmentes. Bien sr, l'objet client doit connatre le nom et les prototypes des mthodes que l'objet servant met disposition. C'est l que l'IDL intervient. L'IDL de CORBA est un moyen indpendant du langage qui permet de prciser les types de donnes, les attributs, les oprations, les interfaces, et plus encore. La syntaxe de l'IDL est similaire celles du C++ ou de Java. La table qui suit montre la correspondance entre quelques uns des concepts communs au trois langages qui peuvent tre spcifis travers l'IDL de CORBA : CORBA IDL Module Interface Method Java Package C++ Namespace
Le concept d'hritage est galement support, en utilisant le sparateur deux-points comme en C++. Le programmeur crit en IDL la description des attributs, des mthodes et des interfaces qui seront implments et utiliss par le serveur et les clients. L'IDL est ensuite compil par un compilateur IDL/Java propre au fournisseur, qui lit le source IDL et gnre le code Java. Le compilateur IDL est un outil extrmement utile : il ne gnre pas juste le source Java quivalent l'IDL, il gnre aussi le code qui sera utilis pour runir les arguments des mthodes et pour raliser les appels distants. Ce code, appel le code stub et le code skeleton, est organis en plusieurs fichiers source Java et fait habituellement partie d'un mme package Java. Le service de nommage (naming service) Le service de nommage est l'un des services fondamentaux de CORBA. L'objet CORBA est accessible par l'intermdiaire d'une rfrence, une information qui n'a pas de sens pour un lecteur humain. Mais les rfrences peuvent tre des chanes de caractres dfinies par le programmeur. Cette opration est dsigne comme chanifier la rfrence, et l'un des composants de l'OMA, le service de nommage, est dvou la conversion nom-vers-objet et objet-vers-nom et gre ces correspondances. Puisque le service de nommage joue le rle d'un annuaire tlphonique que les serveurs et les clients peuvent consulter et manipuler, il fonctionne dans un processus spar. Crer une correspondance objet-vers-nom est appel lier (binding) un objet, et supprimer cette
7 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
correspondance est dit dlier (unbinding). Obtenir l'objet rfrence en passant la chane de caractres est appel rsoudre le nom. Par exemple, au dmarrage, une application serveur peut crer un objet servant, enregistrer l'objet auprs du service de nommage, et attendre que des clients fassent des requtes. Un client obtient d'abord une rfrence vers cet objet servant en rsolvant le nom et ensuite peut faire des appels auprs du serveur en utilisant cette rfrence. A nouveau, la spcification du service de nommage fait partie de CORBA, mais l'application qui l'implmente est mise disposition par le fournisseur de l'ORB. Le moyen d'accder ce service de nommage peut varier d'un fournisseur l'autre.
Un exemple
Le code montr ici ne sera pas trs labor car les diffrents ORBs ont des moyens d'accder aux services CORBA qui divergent, ainsi les exemples dpendent du fournisseur. L'exemple qui suit utilise JavaIDL, un produit gratuit de Sun, qui fournit un ORB basique, un service de nommage, et un compilateur IDL-vers-Java. De plus, comme Java est encore jeune et en constante volution, les diffrents produits CORBA pour Java n'incluent forcment toutes les fonctionnalits de CORBA. Nous voulons implmenter un serveur, fonctionnant sur une machine donne, qui soit capable de retourner l'heure exacte. Nous voulons aussi implmenter un client qui demande l'heure exacte. Dans notre cas, nous allons ralisons les deux programmes en Java, mais nous pourrions faire de mme avec deux langages diffrents (ce qui se produit souvent dans la ralit). crire le source IDL La premire tape consiste crire une description en IDL des services proposs. Ceci est gnralement ralis par le programmeur du serveur, qui est ensuite libre d'implmenter le serveur dans n'importe quel langage pour lequel un compilateur CORBA IDL existe. Le fichier IDL est communiqu au programme de la partie cliente et devient le pont entre les langages. L'exemple qui suit montre la description IDL de notre serveur ExactTime : //: c15:corba:ExactTime.idl //# Vous devez installer idltojava.exe de //# java.sun.com et ajuster le paramtrage pour utiliser //# votre prprocesseur C local pour compiler //# ce fichier. Voyez la documentation sur java.sun.com. module remotetime { interface ExactTime { string getTime(); }; }; ///:~ C'est donc la dclaration de l'interface ExactTime au sein de l'espace de nommage remotetime. L'interface est compose d'une seule mthode qui retourne l'heure actuelle dans une chane de caractres. Cration des stubs et des skeletons La deuxime tape consiste compiler l'IDL pour crer le code Java du stub et du skeleton que nous utiliserons pour implmenter le client et le serveur. L'outil fournit par le produit JavaIDL est idltojava :
8 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
idltojava remotetime.idl
Cela gnrera automatiquement la fois le code pour le stub et celui pour le skeleton. Idltojava gnre un package Java nomm selon le module IDL remotetime et les fichiers Java gnrs sont dposs dans ce sous-rpertoire remotetime. _ExactTimeImplBase.java est le skeleton que nous allons utiliser pour implmenter l'objet servant et _ExactTimeStub.java sera utilis pour le client. Il y a des reprsentations Java de l'interface IDL dans ExactTime.java et toute une srie d'autres fichiers de support utiliss, par exemple, pour faciliter l'accs aux fonctions du service de nommage. Implmentation du serveur et du client Ci-dessous, vous pouvez voir le code pour la partie serveur. L'implmentation de l'objet servant est dans la classe ExactTimeServer. RemoteTimeServer est l'application qui cr l'objet servant, l'enregistre auprs de l'ORB, donne un nom la rfrence vers l'objet, et qui ensuite s'assoit tranquillement en attendant les requtes des clients. //: c15:corba:RemoteTimeServer.java import remotetime.*; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; import java.util.*; import java.text.*; // Implmentation de l'objet servant class ExactTimeServer extends _ExactTimeImplBase { public String getTime(){ return DateFormat. getTimeInstance(DateFormat.FULL). format(new Date( System.currentTimeMillis())); } } // Implmentation de l'application distante public class RemoteTimeServer { public static void main(String[] args) { try { // Cre l'ORB et l'initialise: ORB orb = ORB.init(args, null); // Cre l'objet servant et l'enregistre : ExactTimeServer timeServerObjRef = new ExactTimeServer(); orb.connect(timeServerObjRef); // Obtient la racine du contexte de nommage : org.omg.CORBA.Object objRef = orb.resolve_initial_references( "NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); // Associe un nom // la rfrence de l'objet (binding): NameComponent nc =
9 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
new NameComponent("ExactTime", ""); NameComponent[] path = { nc }; ncRef.rebind(path, timeServerObjRef); // Attend les requtes des clients : java.lang.Object sync = new java.lang.Object(); synchronized(sync){ sync.wait(); } } catch (Exception e) { System.out.println( "Remote Time server error: " + e); e.printStackTrace(System.out); } } } ///:~ Comme vous pouvez le constater, implmenter l'objet servant est simple ; c'est une classe Java classique qui hrite du code du skeleton gnr par le compilateur IDL. Les choses se complexifient un peu lorsqu'on en vient interagir avec l'ORB et les autres services CORBA. Quelques services CORBA Voici une courte description de ce qui ralise le code relevant de JavaIDL (en vitant la partie de code CORBA qui dpend du fournisseur). La premire ligne dans le main( ) dmarre l'ORB parce que bien sr notre objet servant aura besoin d'interagir avec celui-ci. Juste aprs l'initialisation de l'ORB, l'objet servant est cr. En ralit, le terme correct serait un objet servant temporaire (transient) : un objet qui reoit les requtes provenant des clients, et dont la dure de vie est limite celle du processus qui l'a cr. Une fois l'objet servant temporaire cr, il est enregistr auprs de l'ORB, ce qui signifie alors que l'ORB connat son existence et peut rediriger les requtes vers lui. A partir de l, tout ce dont nous disposons est timeServerObjRef, une rfrence vers un objet qui n'est connu qu' l'intrieur du processeur serveur actuel. L'tape suivante va consister associer un nom alphanumrique cet objet servant ; les clients utiliseront ce nom pour localiser l'objet servant. Cette opration sera ralise grce l'aide du service de nommage. Tout d'abord, nous avons besoin d'une rfrence vers le service de nommage ; la mthode resolve_initial_references( ) utilise la rfrence objet chainifie du service de nommage qui s'appelle NameService dans JavaIDL, et retourne la rfrence vers l'objet. Celle-ci est transforme en une rfrence spcifique NamingContext au moyen de la mthode narrow( ). Nous pouvons maintenant utiliser les services de nommage. Pour associer l'objet servant avec une rfrence objet chainifie , nous crons d'abord un objet NameComponent, initialis avec la chane de caractres qui sera associe : ExactTime . Ensuite, en utilisant la mthode rebind( ), la rfrence alphanumrique est associe la rfrence vers l'objet. Nous utilisons rebind( ) pour mettre en place une rfrence, mme si celle-ci existe dj. Un nom est compos dans CORBA d'une squence de NameComponents (voil pourquoi nous utilisons un tableau pour associer le nom la rfrence). L'objet est enfin prt tre utilis par des clients. A ce moment-l, le serveur entre dans un tat d'attente. Encore une fois, ceci est ncessaire puisqu'il s'agit d'un serveur temporaire : sa dure de vie dpend du processus serveur. JavaIDL ne supporte pas actuellement les objets persistants, qui survivent aprs la fin de l'excution du processus qui les a crs.
10 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
Maintenant que nous avons une ide de ce que fait le code du serveur, regardons le code du client : //: c15:corba:RemoteTimeClient.java import remotetime.*; import org.omg.CosNaming.*; import org.omg.CORBA.*; public class RemoteTimeClient { public static void main(String[] args) { try { // Cration et initialisation de l'ORB : ORB orb = ORB.init(args, null); // Obtient la racine du contexte de nommage : org.omg.CORBA.Object objRef = orb.resolve_initial_references( "NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); // Rsout la rfrence alphanumrique // du serveur d'heure : NameComponent nc = new NameComponent("ExactTime", ""); NameComponent[] path = { nc }; ExactTime timeObjRef = ExactTimeHelper.narrow( ncRef.resolve(path)); // Effectue une requte auprs de l'objet servant : String exactTime = timeObjRef.getTime(); System.out.println(exactTime); } catch (Exception e) { System.out.println( "Remote Time server error: " + e); e.printStackTrace(System.out); } } } ///:~ Les premires lignes font la mme chose que ce qu'elles font dans le processus serveur : l'ORB est initialis et la rfrence vers le service de nommage est rsolue. Ensuite, nous avons besoin d'une rfrence objet pour l'objet servant, dont nous passons la rfrence alphanumrique la mthode resolve( ), et transformons le rsultat en une interface ExactTime en utilisant la mthode narrow( ). Enfin, nous appelons getTime( ). Activation du processus du service de nommage Nous avons enfin un serveur et un client prts interoprer. Nous avons pu voir que tous deux ont besoin du service de nommage pour associer et rsoudre les rfrences alphanumriques. Le processus du service de nommage doit tre dmarr avant de faire fonctionner aussi bien le serveur que le client. Dans JavaIDL, le service de nommage est une application Java fournie avec le produit, mais qui peut tre diffrente dans d'autres produits. Le service de nommage de JavaIDL fonctionne dans une JVM et coute par dfaut le port rseau 900. Activation du serveur et du client Vos applications serveur et client sont prtes dmarrer (dans cet ordre, puisque votre serveur est transient (temporaire)). Si tout est bien en place, vous obtiendrez une simple ligne de sortie dans la fentre console de
11 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
votre client, indiquant l'heure courante. Bien sr, cela ne semble pas trs excitant en soit, mais vous devriez prendre en compte une chose : mme si ils sont physiquement sur la mme machine, les applications client et serveur fonctionnent dans des machines virtuelles diffrents et peuvent communiquer travers une couche de l'intgration sous-jacente, l'ORB et le service de nommage. Ceci constitue un exemple simple, destin fonctionner sans rseau, mais un ORB est gnralement configur pour qu'il rende les localisations transparentes. Lorsque le serveur et le client sont sur des machines diffrentes, l'ORB peut rsoudre des rfrences alphanumriques en utilisant un composant dsign Implementation Repository. Bien que le Implementation Repository fasse partie de CORBA, il n'y a quasiment pas de spcification, et donc il est diffrent d'un fabricant l'autre. Ainsi que vous vous en doutez, CORBA reprsente davantage que ce qui est montr ici, mais ainsi vous aurez compris l'ide de base. Si vous souhaitez plus d'informations propos de CORBA, le premier endroit visiter est le site Web de l'OMG : http://www.omg.org. Vous y trouverez la documentation, les white papers et les rfrences vers les autres sources et produits pour CORBA.
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
[70] A partir de maintenant, vous avez t prsent CORBA et RMI. Mais pourriez-vous imaginer de tenter le dveloppement d'une application grande chelle en utilisant CORBA et/ou RMI ? Votre patron vous a demand de dvelopper une application multi-tiers pour consulter et mettre jour des enregistrements dans une base de donnes, le tout travers une interface Web. Vous vous assoyez et pensez ce que cela veut vraiment dire. Sr, vous pouvez crire une application qui utilise JDBC, une interface Web qui utilise JSP et des Servlets, et un systme distribu qui utilise CORBA/RMI. Mais quelles autres considrations devez-vous prendre en compte lorsque vous dveloppez un systme bas sur des objets distribus plutt qu'avec des APIs classiques ? Voici les problmes : Performance : Les nouveaux objets distribus que vous avez cr devront tre performants puisque ils devront potentiellement rpondre plusieurs clients en mme temps. Donc vous allez vouloir mettre en place des techniques d'optimisation comme l'utilisation de cache, la mise en commun des ressources (comme les connexions des bases de donnes par JDBC). Vous devrez aussi grer le cycle de vie de votre objet distribu. Adaptation la charge : Les objets distribus doivent aussi s'adapter l'augmentation de la charge. La scalabilit dans une application distribue signifie que le nombre d'instances de votre objet distribu peut augmenter et passer sur une autre machine sans la modification du moindre code. Prenez par exemple un systme que vous dveloppez en interne comme une petite recherche de clients dans votre organisation depuis une base de donnes. L'application fonctionne bien quand vous l'utilisez, mais votre patron l'a vue et a dit : "Robert, c'est un excellent systme, mettez a sur notre site Web public maintenant !!!". Est-ce que mon objet distribu est capable de supporter la charge d'une demande potentiellement illimite. Scurit : Mon objet distribu contrle-t-il l'accs des clients ? Puis-je ajouter de nouveaux utilisateurs et des rles sans tout recompiler ? Transactions distribues : Mon objet distribu peut-il utiliser de manire transparente des transactions distribues ? Puis-je mettre jour ma base de donnes Oracle et Sybase simultanment au sein de la mme transaction et les annuler ensemble si un certain critre n'est pas respect ? Rutilisation : Ai-je cr mon objet distribu de telle sorte que je puisse le passer d'une application serveur d'un fournisseur une autre ? Puis-je revendre mon objet distribu (composant) quelqu'un d'autre ? Puis-je acheter un composant de quelqu'un d'autre et l'utiliser sans avoir recompiler et tailler dans son code ? Disponibilit : Si l'une des machines de mon systme tombe en panne, mes clients sont-ils capables de basculer des copies de sauvegarde de mes objets fonctionnant sur d'autres machines ? Comme vous avez pu le voir ci-dessus, les considrations qu'un dveloppeur doit prendre en compte lorsqu'il dveloppe un systme distribu sont complexes, et nous n'avons mme pas parl de la solution du problme qui nous essayons de rsoudre l'origine ! Donc maintenant vous avez une liste de problmes supplmentaires que vous devez rsoudre. Alors comme allez-vous vous y prendre ? Quelqu'un l'a certainement dj fait ? Ne pourrais-je pas utiliser des modles de conception bien connus pour m'aider rsoudre ces problmes ? Soudain, une ide vous vient l'esprit... Je pourrais crer un framework qui prend en charge toutes ces contraintes et crire mes composants en m'appuyant sur ce framework ! ... C'est l que les Entreprise JavaBeans rentrent en jeu. Sun, avec d'autres fournisseurs d'objets distribus a compris que tt ou tard toute quipe de dveloppement serait en train de rinventer la roue. Ils ont donc cr la spcification des Entreprise JavaBeans (EJB). Les EJB sont une spcification d'un modle de composant ct serveur qui prend en compte toutes les considrations mentionnes plus haut utilisant une approche standard et dfinie qui permet aux dveloppeurs de crer des composants (qui sont appels des Entreprise JavaBeans), qui sont isols du code de la 'machinerie' bas-niveau et
13 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
focaliss seulement sur la mise en place de la logique mtier. Et puisque les EJBs sont dfinis sur un standard, ils peuvent tre utiliss sans tre dpendant d'un fournisseur.
Fournisseur d'Enterprise Bean Le dveloppeur qui est responsable de la cration des composants EJB rutilisa regroups dans un fichier jar spcial (fichier ejb-jar). Assembleur d'Application Dployeur Fournisseur de Conteneurs/Serveurs d'EJB Administrateur Systme Cre et assemble des applications partir d'une collection de fichiers ejb-jar. C d'applications mettant en oeuvre la collection d'EJB (comme des Servlets, JSP, Le rle du dployeur est de prendre la collection de fichiers ejb-jar de l'Assemb et de dployer ceux-ci dans un environnement d'excution (un ou plusieurs Con Fournit un environnement d'excution et les outils qui sont utiliss pour dploy fonctionner les composants EJB. Par dessus tout, le rle le plus important de l'ensemble du systme : mettre en p gestion d'une application distribue consiste ce que les composants et les serv interagissent ensemble correctement.
14 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
Composants EJB Les composants EJB sont de la logique mtier rutilisable. Les composants EJB suivent strictement les standards et les modles de conception dfinis dans la spcification des EJBs. Cela permet ces composants d'tre portables et aussi tous les autres services tels que la scurit, la mise en cache et les transactions distribues, d'tre mis en oeuvre sur ces composants eux-mmes. Un fournisseur d'Entreprise Bean est responsable du dveloppement des composants EJB. Les entrailles d'un composant EJB sont traits dans Qu'est-ce qui compose un composant EJB ?
Conteneur d'EJB
Le conteneur d'EJB est un environnement d'excution qui contient et fait fonctionner les composants EJB tout en leur fournissant un ensemble de services. Les responsabilits des conteneurs d'EJB sont dfinies prcisment par la spcification pour permettre une neutralit vis--vis du fournisseur. Les conteneurs d'EJB fournissent la machinerie bas-niveau des EJBs, incluant les transactions distribues, la scurit, la gestion du cycle de vie des beans, la mise en cache, la gestion de la concurrence et des sessions. Le fournisseur de conteneur d'EJB est responsable de la mise disposition d'un conteneur d'EJB.
Serveur EJB
Un serveur d'EJB est dfini comme un Serveur d'Applications et comporte un ou plusieurs conteneurs d'EJBs. Le fournisseur de serveur EJB est responsable de la mise disposition d'un serveur EJB. Vous pouvez gnralement considrer que le conteneur d'EJB et le serveur EJB sont une seule et mme chose.
Java Naming and Directory Interface (JNDI)
Java Naming and Directory Interface (JNDI) est utilis dans les Entreprise JavaBeans comme le service de nommage pour les composants EJB sur le rseau et pour les autres services du conteneur comme les transactions. JNDI ressemble fort aux autres standards de nommage et de rpertoires tels que CORBA CosNaming et peut tre implment comme un adaptateur de celui-ci.
Java Transaction API / Java Transaction Service (JTA/JTS)
JTA/JTS est utilis dans les Enterprise JavaBeans comme API transactionnelle. Un fournisseur d'Entreprise Bean peut utiliser le JTS pour crer un code transactionnel bien que le conteneur d'EJB implmente gnralement les transactions dans les EJBs sur les composants EJBs eux-mmes. Le dployeur peut dfinir les attributs transactionnels d'un composant EJB au moment du dploiement. Le conteneur d'EJB est responsable de la prise en charge de la transaction qu'elle soit locale ou distribue. La spcification du JTS est la version Java de CORBA OTS (Object Transaction Service).
CORBA et RMI/IIOP
La spcification des EJBs dfinit l'interoprabilit avec CORBA. La spcification 1.1 prcise que L'architecture des Entreprise JavaBeans sera compatible avec les protocoles CORBA. L'interoprabilit avec CORBA passe par l'adaptation des services EJB comme JTS et JNDI aux services CORBA et l'implmentation de RMI travers le protocole CORBA IIOP. L'utilisation de CORBA et de RMI/IIOP dans les Entreprise JavaBeans est implmente dans le conteneur EJB et est sous la responsabilit du fournisseur du conteneur d'EJB. L'utilisation de CORBA et de RMI/IIOP dans le conteneur EJB est invisible pour le composant EJB lui-mme. Cela signifie que le fournisseur d'Entreprise Bean peut crire ses composants EJBs et les dployer dans un conteneur EJB sans s'inquiter du protocole de
15 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
16 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
la cration d'un EJB travers l'interface Home, le conteneur d'EJB pourrait n'en crer qu'un seule et partager cet EJB entre les cinq clients. Ceci est ralis travers l'interface Remote, qui est aussi implmente par le conteneur d'EJB. L'objet implmentant Remote joue le rle d'objet proxy vers l'EJB. Tous les appels de l'EJB sont redirigs travers le conteneur d'EJB grce aux interfaces Home et Remote. Cette abstraction explique aussi pourquoi le conteneur d'EJB peut contrler la scurit et le comportement transactionnel.
Types d'EJBs
Il doit y avoir une question dans votre tte depuis le dernier paragraphe : partager le mme EJB entre les clients peut certainement augmenter les performances, mais qu'en est-il lorsque je souhaite conserver l'tat sur le serveur ? La spcification des Enterprise JavaBeans dfinissent diffrents types d'EJBs qui peuvent avoir diffrentes caractristiques et adopter un comportement diffrent. Deux catgories d'EJBs ont t dfinies dans cette spcification : les Session Beans et les Entity Beans, et chacune de ces catgories a des variantes.
Session Beans Les Session Beans sont utiliss pour reprsenter les cas d'utilisations ou des traitements spcifiques du client. Ils reprsentent les oprations sur les donnes persistantes, mais non les donnes persistantes elles-mmes. Il y a deux types de Session Beans : non-persistant (Stateless) and persistant (Stateful). Tous les Session Beans doivent implmenter l'interface javax.ejb.SessionBean. Le conteneur d'EJB contrle la vie d'un Session Bean.
Les Session Beans non-persistants
Les Session Beans non-persistants sont le type d'EJB le plus simple implmenter. Ils ne conservent aucun tat de leur conversation avec les clients entre les invocations de mthodes donc ils sont facilement rutilisables dans la partie serveur et puisqu'ils peuvent tre mis en cache, ils supportent bien les variations de la demande. Lors de l'utilisation de Session Beans non-persistants, tous les tats doivent tre stocks l'extrieur de l'EJB.
Les Session Beans persistants
Les Session Beans persistants conservent un tat entre l'invocation de leurs mthodes (comme vous l'aviez probablement compris). Ils ont une association 1-1 avec un client et sont capables de conserver leurs tats eux-mmes. Le conteneur d'EJBs a en charge le partage et la mise en cache des Session Beans persistants, ceux-ci passe par la Passivation et l'Activation. Entity Beans Les Entity Beans sont des composants qui reprsentent une donne persistante et le comportement de cette donne. Les Entity Beans peuvent tre partags par plusieurs clients, comme une donne d'une base. Le conteneur d'EJBs a en charge de mettre en cache les Entity Beans et de maintenir leur intgrit. La vie d'un Entity Bean est suprieur celle du conteneur d'EJBs, donc si un conteneur tombe en panne, l'Entity Bean est cens tre encore disponible lors que le conteneur le devient nouveau. Il y a deux types d'Entity Beans, ceux dont la persistence est assure par le Bean lui-mme et ceux dont la persistance est assure par le conteneur.
17 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
Un CMP Entity Bean a sa persistence assure par le conteneur d'EJBs. A travers les attributs spcifis dans le descripteur de dploiement, le conteneur d'EJBs fera correspondre les attributs de l'Entity Bean avec un stockage persistant (habituellement, mais pas toujours, une base de donnes). La gestion de la persistence par le conteneur rduit le temps de dveloppement et rduit considrablement le code ncessaire pour l'EJB.
Gestion de la persistence par le Bean (BMP - Bean Managed Persistence)
Un BMP Entity Bean a sa persistence implmente par le fournisseur de l'Entreprise Bean. Le fournisseur d'Entity Bean a en charge d'implmenter la logique ncessaire pour crer un nouvel EJB, mettre jour certains attributs des EJBs, supprimer un EJB et trouver un EJB dans le stockage persistence. Cela ncessite habituellement d'crire du code JDBC pour interagir avec une base de donnes ou un autre stockage persistant. Avec la gestion de persistence par le Bean (BMP), le dveloppeur a le contrle total de la manire dont la persistence de l'Entity Bean est ralise. Le principe de BMP apporte aussi de la flexibilit l o l'implmentation en CMP n'est pas possible, par exemple si vous souhaitez crer un EJB qui encapsule du code d'un systme mainframe existant, vous pouvez crire votre persistence en utilisant CORBA.
18 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
La seconde interface dfinie est l'interface Home de notre composant Enterprise JavaBeans. L'interface Home est la Factory du composant que vous allez crer. L'interface Home peut dfinir des mthodes de cration ou de recherche. Les mthodes de cration crent les instances des EJBs, les mthodes de recherche localisent les EJBs existants et sont utiliss pour les Entity Beans seulement. Lorsque vous crez votre interface Home d'un EJB, vous devez respecter ces quelques rgles : 1. L'interface Home doit tre public. 2. L'interface Home doit hriter de l'interface javax.ejb.EJBHome. 3. Chaque mthode de l'interface Home doit dclarer java.rmi.RemoteException dans sa section throws de mme que javax.ejb.CreateException 4. La valeur retourne par une mthode de cration doit tre une interface Remote. 5. La valeur retourne par une mthode de recherche (pour les Entity Beans uniquement) doit tre une interface Remote, java.util.Enumeration ou java.util.Collection. 6. Chaque objet pass en argument ou retourn par valeur (sous directement ou encapsul dans un objet local) doit tre un type de donne valide pour RMI-IIOP (ce qui inclut les autres objets EJB). La convention standard de nommage des interfaces Home consiste prendre le nom de l'interface Remote et d'y ajouter la fin Home . Voici l'interface Home de notre EJB PerfectTime : //: c15:ejb:PerfectTimeHome.java // Interface Home de PerfectTimeBean. import java.rmi.*; import javax.ejb.*; public interface PerfectTimeHome extends EJBHome { public PerfectTime create() throws CreateException, RemoteException; } ///:~ Maintenant que nous avons dfini les interfaces de notre composant, nous pouvons implmenter la logique mtier qu'il y a derrire. Lorsque vous crez la classe d'implmentation de votre EJB, vous devez suivre ces rgles (notez que vous pourrez trouver dans la spcification des EJBs la liste complte des rgles de dveloppement des Entreprise JavaBeans) : 1. La classe doit tre public. 2. La classe doit implmenter une interface (soit javax.ejb.SessionBean, soit javax.ejb.EntityBean). 3. La classe doit dfinir les mthodes correspondant aux mthodes de l'interface Remote. Notez que la classe n'implmente pas l'interface Remote, c'est le miroir des mthodes de l'interface Remote mais elle n'met pas java.rmi.RemoteException. 4. Dfinir une ou plusieurs mthodes ejbCreate( ) qui initialisent votre EJB. 5. La valeur retourne et les arguments de toutes les mthodes doivent tre des types de donnes compatibles avec RMI-IIOP. //: c15:ejb:PerfectTimeBean.java // Un Session Bean non-persistant // qui retourne l'heure systme courante. import java.rmi.*; import javax.ejb.*; public class PerfectTimeBean implements SessionBean { private SessionContext sessionContext; // retourne l'heure courante
19 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
public long getPerfectTime() { return System.currentTimeMillis(); } // mthodes EJB public void ejbCreate() throws CreateException {} public void ejbRemove() {} public void ejbActivate() {} public void ejbPassivate() {} public void setSessionContext(SessionContext ctx) { sessionContext = ctx; } }///:~ Notez que les mthodes EJB (ejbCreate( ), ejbRemove( ), ejbActivate( ), ejbPassivate( ) ) sont toutes vides. Ces mthodes sont appeles par le conteneur d'EJBs et sont utilises pour contrler l'tat de votre composant. Comme c'est un exemple simple, nous pouvons les laisser vide. La mthode setSessionContext( ) transmet un objet javax.ejb.SessionContext qui contient les informations concernant le contexte dans lequel se trouve le composant, telles que la transaction courante et des informations de scurit. Aprs que nous ayons cr notre Enterprise JavaBean, nous avons maintenant besoin de crer le descripteur de dploiement. Dans les EJBs 1.1, le descripteur de dploiement est un fichier XML qui dcrit le composant EJB. Le descripteur de dploiement doit tre stock dans un fichier appel ejb-jar.xml. <?xml version="1.0" encoding="Cp1252"?> <!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise Jav <ejb-jar> <description>Exemple pour le chapitre 15</description> <display-name></display-name> <small-icon></small-icon> <large-icon></large-icon> <enterprise-beans> <session> <ejb-name>PerfectTime</ejb-name> <home>PerfectTimeHome</home> <remote>PerfectTime</remote> <ejb-class>PerfectTimeBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> </session> </enterprise-beans> <ejb-client-jar></ejb-client-jar> </ejb-jar> Dans la balise <session> de votre descripteur de dploiement, vous pouvez voir que le composant, les interfaces Remote et Home sont dfinis en partie. Les descripteurs de dploiement peuvent facilement tre gnrs automatiquement grce des outils tels que JBuilder. Par l'intermdiaire de ce descripteur de dploiement standard ejb-jar.xml, la spcification des EJBs 1.1 institue que toutes balises spcifiques aux fournisseurs doivent tre stockes dans un fichier spar. Ceci a pour but d'assurer une compatibilit complte entre les composants et les conteneurs d'EJBs de diffrents marques.
20 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
Maintenant que nous avons cr notre composant et dfini sa composition dans le descripteur de dploiement, nous devons alors archiver les fichiers dans un fichier archive Java (JAR). Le descripteur de dploiement doit tre plac dans le sous rpertoire META-INF du fichier Jar. Une fois que nous avons dfini notre composant EJB dans le descripteur de dploiement, le dployeur doit maintenant dployer le composant EJB dans le conteneur d'EJB. A ce moment-l du dveloppement, le processus est plutt orient IHM et spcifique chaque conteneur d'EJBs. Nous avons donc dcid de ne pas documenter entirement le processus de dploiement dans cette prsentation. Chaque conteneur d'EJBs propose cependant un processus dtaill pour dployer un EJB. Puisqu'un composant EJB est un objet distribu, le processus de dploiement doit crer certains stubs clients pour appeler le composant EJB. Ces classes seront places dans le classpath de l'application cliente. Puisque les composants EJB sont implments par dessus RMI-IIOP (CORBA) ou RMI-JRMP, les stubs gnrs peuvent varier entre les conteneurs d'EJBs, nanmoins ce sont des classes gnres. Lorsqu'un programme client dsire invoquer un EJB, il doit rechercher le composant EJB dans JNDI et obtenir une rfrence vers l'interface Home du composant EJB. L'interface HOME peut alors tre invoque pour crer une instance de l'EJB, qui peut son tour tre invoque. Dans cet exemple le programme client est un simple programme Java, mais vous devez garder en mmoire qu'il pourrait s'agir aussi bien d'un Servlet, d'un JSP que d'un objet distribu CORBA ou RMI. Le code de PerfectTimeClient code est le suivant. //: c15:ejb:PerfectTimeClient.java // Programme Client pour PerfectTimeBean public class PerfectTimeClient { public static void main(String[] args) throws Exception { // Obtient un context JNDI utilisant le // service de nommage JNDI : javax.naming.Context context = new javax.naming.InitialContext(); // Recherche l'interface Home dans le // service de nommage JNDI : Object ref = context.lookup("perfectTime"); // Transforme l'objet distant en une interface Home : PerfectTimeHome home = (PerfectTimeHome) javax.rmi.PortableRemoteObject.narrow( ref, PerfectTimeHome.class); // Cre un objet distant depuis l'interface Home : PerfectTime pt = home.create(); // Invoque getPerfectTime() System.out.println( "Perfect Time EJB invoked, time is: " + pt.getPerfectTime() ); } } ///:~ Le droulement de cet exemple est expliqu dans les commentaires. Notez l'utilisation de la mthode narrow() pour raliser une sorte de transtypage de l'objet avant qu'un transtypage Java soit fait. Ceci est trs similaire ce qui se passe en CORBA. Notez aussi que l'objet Home devient une Factory pour les objets PerfectTimes.
21 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
En rsum
La spcification des Enterprise JavaBeans est un pas important vers la standardisation et la simplification de l'informatique distribue. C'est une pice majeure de Java 2, Enterprise Edition Platform et reoit en plus le concours la communaut travaillant sur les objets distribus. De nombreux outils sont actuellement disponibles ou le seront dans un futur proche pour acclrer le dveloppement de composants EJBs. Cette prsentation avait pour but de donner un bref aperu de ce que sont les EJBs. Pour plus d'informations propos de la spcification des Enterprise JavaBeans, vous pouvez vous reporter la page officielle des Enterprise JavaBeans l'adresse http://java.sun.com/products/ejb/. Vous pourrez y tlcharger la dernire spcification ainsi que Java 2, Enterprise Edition Reference Implementation, qui vous permettra de dvelopper et de dployer vos propres composants EJBs.
Contexte de Jini
Traditionnellement, les systmes d'exploitation sont conus dans l'hypothse qu'un ordinateur aura un processeur, un peu de mmoire et un disque. Lorsque vous dmarrez votre ordinateur, la premire chose qu'il fait est de chercher un disque. S'il ne le trouve pas, il ne peut assurer sa fonction d'ordinateur. Cependant de plus en plus les ordinateurs apparaissent sous diverses formes : comme des systmes embarqus qui possdent un processeur, un peu de mmoire et une connexion rseau mais pas de disque. La premire chose que fait, par exemple, un tlphone cellulaire lorsqu'il s'allume est de rechercher le rseau tlphonique. S'il ne le trouve pas, il ne peut assurer sa fonction de tlphone. Cette nouvelle mode dans l'environnement matriel, le passage d'un systme centr sur un disque un systme centr sur un rseau, va affecter la manire d'organiser notre logiciel. C'est l qu'intervient Jini. Jini est une manire de repenser l'architecture de l'ordinateur, tant donn l'importance croissante des rseaux et la prolifration des processeurs dans des systmes qui n'ont pas de disque dur. Ces systmes, qui proviennent de nombreux fabricants diffrents, vont avoir besoin d'interagir travers le rseau. Le rseau lui-mme sera trs dynamique : les systmes et les services seront ajouts et retirs rgulirement. Jini apporte les mcanismes permettant facilement l'ajout, la suppression et la recherche de systmes et de services sur le rseau. De plus, Jini propose un modle de programmation qui rend tout cela plus facile pour les programmeurs qui souhaitent voir leurs systmes discuter entre eux. S'appuyant sur Java, la srialisation objet et RMI (qui permet aux objets de bouger travers le rseau en passant d'une machine virtuelle une autre), Jini permet d'tendre les bnfices de la programmation oriente-objet au rseau. Au lieu de ncessiter un accord entre les diffrents fabricants sur un protocole rseau travers lequel les systmes peuvent interagir, Jini permet ces systmes de discuter ensemble par l'intermdiaire d'interfaces vers des objets.
22 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
compatible Jini pourra offrir un service d'impression. Une fdration de services est un ensemble de services, actuellement disponibles sur le rseau, que le client (ce qui signifie programme, service ou utilisateur) peut combiner pour s'aider atteindre son but. Pour raliser une tche, un client enchane les possibilits des services. Par exemple, un programme client peut charger des photographies d'un systme de stockage d'image d'un appareil numrique, envoyer les photos vers un service de stockage persistant offert par un disque dur, et transmettre une page contenant les vignettes de chaque image un service d'impression d'une imprimante couleur. Dans cet exemple, le programme client construit un systme distribu constitu de lui-mme, le service de stockage d'images, le service de stockage persistant et le service d'impression couleur. Le client et ces services de ce systme distribu collaborent pour raliser une tche : dcharger et stocker les images d'un appareil numrique et imprimer une page de vignettes. L'ide derrire le mot fdration est que la vision Jini d'un rseau n'instaure pas d'autorit de contrle centrale. Puisque aucun service n'est responsable, l'ensemble de tous les services disponible sur le rseau forme une fdration, un groupe compos de membres gaux. Au lieu d'une autorit centrale, l'infrastructure d'excution de Jini propose un moyen pour les clients et les services de se trouver mutuellement ( travers un service de recherche, qui stocke la liste des services disponibles moment donn). Aprs que les services se sont trouvs, ils sont indpendants. Le client et ces services mis contribution ralisent leurs tches indpendamment de l'infrastructure d'excution de Jini. Si le service de recherche Jini tombe, tous les systmes distribus mis en place par le service de recherche, avant qu'il ne plante, peuvent continuer les travaux. Jini incorpore mme un protocole rseau qui permet aux clients de trouver les services en l'absence d'un service de nommage.
Le processus de dcouverte
1. Le processus de dcouverte travaille ainsi : imaginez un disque supportant Jini et offrant un service de stockage persistant. Ds que le disque est connect au rseau, il diffuse une annonce de prsence en envoyant un paquet multicast sur un port dtermin. Dans l'annonce de prsence, sont inclus une adresse IP et un numro de port o le disque peut tre contact par le service de recherche. Les services de recherche scrutent sur le port dtermin les paquets d'annonce de prsence. Lorsqu'un service de recherche reoit une annonce de prsence, il l'ouvre et inspecte le paquet. Le paquet contient les informations qui permet au service de recherche de dterminer s'il doit ou non contacter l'expditeur de ce paquet. Si tel est le cas, il contacte directement l'expditeur en tablissant une connexion TCP l'adresse IP et sur le numro de port extraits du paquet. En utilisant RMI, le service de recherche envoie l'initiateur du paquet un objet appel un enregistreur de service (service registrar). L'objectif de cet enregistreur de service est de faciliter la communication future avec le service de recherche. Dans le cas d'un disque dur, le service de recherche attablirait une connexion TCP vers le disque dur et lui enverrait un enregistreur de service, grce auquel le
23 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
disque dur pourra faire enregistrer son service de stockage persistant par le processus de jonction.
Le processus de jonction
Ds lors qu'un fournisseur de service possde un enregistreur de service, le produit final du processus de dcouverte, il est prt entreprendre une jonction pour intgrer la fdration des services qui sont enregistrs auprs du service de recherche. Pour raliser une jonction, le fournisseur de service fait appel la mthode register( ) de l'enregistreur de service, passant en argument un objet appel lment de service (service item), un ensemble d'objets qui dcrit le service. La mthode register( ) envoie une copie de cet lment de service au service de recherche, o celui-ci sera stock. Lorsque ceci est achev, le fournisseur de service a fini le processus de jonction : son service est maintenant enregistr auprs du service de recherche. L'lment de service contient plusieurs objets, parmi lesquels un objet appel un objet service, que les clients utilisent pour interagir avec le service. L'lment de service peut aussi inclure une certain nombre d'attributs, qui peuvent tre n'importe quel objet. Certains de ces attributs sont des icnes, des classes qui fournissent des interfaces graphiques pour le service et des objets apportant plus de dtails sur le service. Les objects service implmentent gnralement une ou plusieurs interfaces travers lesquelles les clients interagissent avec le service. Par exemple, le service de recherche est un service Jini, et son objet service est un service de registre. La mthode register( ) appele par les fournisseurs de service durant la jonction est dclare dans l'interface ServiceRegistrar (un membre du package net.jini.core.lookup) que tous les services de registre implmentent. Les clients et les fournisseurs de registre discutent avec le service de recherche travers l'objet de service de registre en invoquant les mthodes dclares dans l'interface ServiceRegistrar. De la mme manire, le disque dur fournit un objet service qui implmente l'une des interfaces connues de service de stockage. Les clients peuvent rechercher le disque dur et interagir avec celui-ci par cette interface de service de stockage.
Le processus de recherche
Une fois qu'un service a t enregistr par un service de recherche grce au processus de jonction, ce service est utilisable par les clients qui le demandent au service de recherche. Pour construire un systme distribu de services qui collaborent pour raliser une tche, un client doit localiser ses services et s'aider de chacun d'eux. Pour trouver un service, les clients formulent des requtes auprs des services de recherche par l'intermdiaire d'un processus appel recherche. Pour raliser une recherche, un client fait appel la mthode lookup( ) d'un service de registre (comme un fournisseur de service, un client obtient un service de registre grce au processus de dcouverte dcrit prcdemment). Le client passe en argument un modle de service lookup( ), un objet utilis comme critre de recherche. Le modle de service peut inclure une rfrence un tableau d'objets Class. Ces objets Class indiquent au service de recherche le type Java (ou les types)) de l'objet service voulu par le client. Le modle de service peut aussi inclure un service ID, qui identifie de manire unique le service, ainsi que des attributs, qui doivent correspondre exactement aux attributs fournis par le fournisseur de service dans l'lment de service. Le modle de service peut aussi contenir des critres gnriques pour n'importe quel attribut. Par exemple, un critre gnrique dans le champ service ID correspondra n'importe quel service ID. La mthode lookup( ) envoie le modle de service au service de recherche, qui excute la requte et renvoie s'il y en a les objets services correspondants. Le client rcupre une rfrence vers ces objets services comme rsultat de la mthode lookup( ). En gnral, un client recherche un service selon le type Java, souvent une interface. Par exemple, si un client avait besoin d'utiliser une imprimante, il pourrait crer un modle de service qui comprend un objet Class d'une interface connue de services d'impression. Tous les services d'impression implmenteraient cette interface
24 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
connue. Le service de recherche retournerait un ou plusieurs objets services qui implmentent cette interface. Les attributs peuvent tre inclus dans le modle de service pour rduire le nombre de correspondances de ce genre de recherche par type. Le client pourrait utiliser le service d'impression en invoquant sur l'objet service les mthodes dfinies dans l'interface.
Le client communique avec le service travers une interface publique Diffrentes implmentations de la mme interface d'un service peuvent utiliser des approches et des protocoles rseau totalement diffrents. Un service peut utiliser un matriel spcialis pour rpondre aux requtes clientes, ou il peut tout raliser de manire logicielle. En fait, le choix d'implmentation d'un mme service peut voluer dans le temps. Le client peut tre sr qu'il possde l'objet service qui comprend l'implmentation actuelle de ce service, puisque le client reoit l'objet service (grce au service de recherche) du fournisseur du service lui-mme. Du point de vue du client, le service ressemble une interface publique, sans qu'il ait se soucier de l'implmentation du service.
Rsum
25 of 26
7/6/01 9:57 AM
file:///D|/Daniel/TIJ2FR/All/Chapter15_b.htm
Avec Jini pour des rseaux de systmes locaux, ce chapitre vous a prsent une partie (une partie seulement) des composants que Sun regroupe sous le terme de J2EE : the Java 2 Enterprise Edition. Le but de J2EE est de construire un ensemble d'outils qui permettent au dveloppeur Java de construire des applications serveurs beaucoup plus rapidement et indpendamment de la plate-forme. Construire de telles applications n'est pas seulement difficile et coteux en temps, mais il est particulirement dur de les construire en faisant en sorte qu'elles puissent tre facilement portes sur une autre plate-formes, et aussi que la logique mtier soit isole des dtails relevant de l'implmentation. J2EE met disposition une structure pour assister la cration d'applications serveurs ; ces applications sont trs demandes en ce moment, et cette demande semble grandir.
Exercices
1. Compiler et excuter les programmes JabberServer et JabberClient de ce chapitre. Maintenant diter les fichiers pour supprimer toute bufferisation sur l'entre et la sortie, ensuite les compiler et les lancer nouveau pour observer le rsultat. 2. Crer un serveur qui demande un mot de passe, puis qui ouvre un fichier et qui en envoie le contenu travers la connexion rseau. Crer le client qui se connecte ce serveur, qui donne le mot de passe appropri et qui capture et sauve le fichier. Tester ces deux programmes sur votre machine en utilisant localhost (l'adresse IP de la boucle locale 127.0.0.1 obtenue en appelant InetAddress.getByName(null)). 3. Modifier le serveur de l'exercice 2 pour qu'il utilise plusieurs threads pour rpondre plusieurs clients. 4. Modifier JabberClient pour que le flushing de la sortie ne se fasse pas et observer l'effet. 5. Modifier MultiJabberServer pour qu'il utilise un pool de threads. Au lieu d'abandonner un thread chaque fois qu'un client se dconnecte, le thread doit se poser lui-mme dans un pool de threads disponibles. Lorsqu'un nouveau client veut se connecter, le serveur se tournera vers ce pool pour rpondre la requte, et s'il n'y plus de thread disponible, il en crera un nouveau. De cette manire, le nombre de threads ncessaires grossira naturellement jusqu' atteindre la quantit requise. L'avantage du pool de threads est qu'il n'est pas ncessaire de crer et de dtruire un thread pour chaque client. 6. Construire partir de ShowHTML.java une applet qui soit un pont protg par un mot de passe vers une portion particulire de votre site Web. 7. (Plus difficile) Crer une paire de programmes client/serveur qui utilisent des datagrammes pour transmettre un fichier d'une machine l'autre (Regardez la description la fin de la section consacre au datagramme dans ce chapitre). 8. (Plus difficile) Prendre le programme VLookup.java et le modifier pour que lorsque vous cliquez sur le nom obtenu, il prenne automatiquement ce nom et le copie dans le presse-papier (ainsi vous pouvez simplement le copier dans votre courrier lectronique). Vous aurez besoin de retourner au chapitre sur les flux d'entre/sortie pour vous rappeler comment utiliser le presse-papier de Java 1.1.
[68] Ce qui reprsente un peu plus de 4 milliards de valeurs, ce qui sera vite puis. Le nouveau standard pour les adresses IP utilisera des nombres de 128 octets, qui devraient produire assez d'adresses IP pour le futur proche. [69] Beaucoup de neurones sont morts aprs une atroce agonie pour dcouvrir cette information. [70] Cette section a t ralise par Robert Castaneda, avec l'aide de Dave Bartlett. [71] Cette section a t ralise par Bill Venners (www.artima.com).
[ Previous Chapter ] [ Short TOC ] [ Table of Contents ] [ Index ] [ Next Chapter ]
Last Update:03/13/2000
26 of 26
7/6/01 9:57 AM