You are on page 1of 50

Intergiciels Objets Rpartis : Java Remote Method Invocation (RMI) ou les invocations de mthodes Java distantes

Samia Bouzefrane Matre de Confrences Laboratoire CEDRIC Conservatoire National des Arts et Mtiers 292 rue Saint Martin 75141 Paris Cdex 03 samia.bouzefrane@cnam.fr http://cedric.cnam.fr/~bouzefra

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

Rappel : Appel local (interface et objet)


public interface ReverseInterface { String reverseString(String chaine); }

public class Reverse implements ReverseInterface { public String reverseString (String ChaineOrigine){ int longueur=ChaineOrigine.length(); StringBuffer temp=new StringBuffer(longueur); for (int i=longueur; i>0; i--) { temp.append(ChaineOrigine.substring(i-1, i));} return temp.toString(); } }

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

Rappel : Appel local (programme appelant )


import ReverseInterface; public class ReverseClient { public static void main (String [] args) { Reverse rev = new Reverse(); String result = rev.reverseString (args [0]); System.out.println ("L'inverse de "+args[0]+" est "+result); } } $javac *.java $java ReverseClient Alice Linverse de Alice est ecilA $
CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

Quattend t-on dun objet distribu ?


Un objet distribu doit pouvoir tre vu comme un objet normal . Soit la dclaration suivante : ObjetDistribue monObjetDistribue;

On doit pouvoir invoquer une mthode de cet objet situ sur une autre machine de la mme faon quun objet local : monObjetDisribue.uneMethodeDeLOD();
CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

On doit pouvoir utiliser cet objet distribu sans connatre sa localisation. On utilise pour cela un service sorte dannuaire, qui doit nous renvoyer son adresse.
monObjetDistribue= ServiceDeNoms.recherche(myDistributedObject);

On doit pouvoir utiliser un objet distribu comme paramtre dune mthode locale ou distante.

x=monObjetLocal.uneMethodeDeLOL(monObjetDistribue); x= monObjetDistribue.uneMethodeDeLOD(autreObjetDistribue);
CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

On doit pouvoir rcuprer le rsultat dun appel de mthode sous la forme dun objet distribu.

monObjetDistribue=autreObjetDistribue.uneMethodeDeLOD(); monObjetDistribue=monObjetLocal.uneMethodeDeLOL();

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

Java RMI Remote Method Invocation


permet la communication entre machines virtuelles Java (JVM) qui peuvent se trouver physiquement sur la mme machine ou sur deux machines distinctes.

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

Prsentation

RMI est un systme dobjets distribus constitu uniquement dobjets java ; RMI est une Application Programming Interface (intgre au JDK 1.1 et plus) ; Dvelopp par JavaSoft ;

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

Mcanisme qui permet lappel de mthodes entre objets Java qui sexcutent ventuellement sur des JVM distinctes ; L appel peut se faire sur la mme machine ou bien sur des machines connectes sur un rseau ; Utilise les sockets ; Les changes respectent un protocole propritaire : Remote Method Protocol ; RMI repose sur les classes de srialisation.

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

Architecture
Invocation de la mthode distante Objet distant Application

Stub

Squelette

Prsentation

Couche rfrences distantes

Couche rfrences distantes

Session

TCP/IP

TCP/IP

Transport/rseau

Interface Hard

Interface Hard

Liaison de donnes /Physique

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

10

Appel local versus Appel distance


Client interface Objet

Appel local

mthode+ arguments

Client

interface

Stub

Skeleton

interface

Objet

retour + exception

Appel distant
Rseau CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

11

Les amorces (Stub/Skeleton) Elles assurent le rle dadaptateurs pour le transport des appels distants Elles ralisent les appels sur la couche rseau Elles ralisent lassemblage et le dsassemblage des paramtres (marshalling, unmarshalling) Une rfrence dobjets distribu correspond une rfrence damorce Les amorces sont cres par le gnrateur rmic.
CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

12

Les Stubs
Reprsentants locaux de lobjet distribu ; Initient une connexion avec la JVM distante en transmettant linvocation distante la couche des rfrences dobjets ; Assemblent les paramtres pour leur transfert la JVM distante ; Attendent les rsultats de linvocation distante ; Dsassemblent la valeur ou lexception renvoye ; Renvoient la valeur lappelant ; Sappuient sur la srialisation.
CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

13

Les squelettes

Dsassemblent les paramtres pour la mthode distante ; Font appel la mthode demande ; Assemblage du rsultat (valeur renvoye ou exception) destination de lappelant.

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

14

La couche des rfrences dobjets Remote Reference Layer


Permet dobtenir une rfrence dobjet distribu partir de la rfrence locale au stub ; Cette fonction est assure grce un service de noms rmiregister (qui possde une table de hachage dont les cls sont des noms et les valeurs sont des objets distants) ; Un unique rmiregister par JVM ; rmiregister sexcute sur chaque machine hbergeant des objets distants ; rmiregister accepte des demandes de service sur le port 1099;
CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

15

La couche transport
ralise les connexions rseau bases sur les flux entre les JVM emploie un protocole de communication propritaire (JRMP: Java Remote Method Invocation) bas sur TCP/IP Le protocole JRMP a t modifi afin de supprimer la ncessit des squelettes car depuis la version 1.2 de Java, une mme classe skeleton gnrique est partage par tous les objets distants.

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

16

Etapes dun appel de mthode distante

Client Serveur de noms

Serveur

3. Interroger

2. Publier

Application Cliente

1. Exposer 4. Rcuprer Serveur dobjets

Objet distant

7. Appel mthode
Skeleton

5. Appel de mthode Stub 10. Retour

6. Arguments srialisation

8. Retour

9. Rsultat

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

17

Dvelopper une application avec RMI : Mise en uvre


1. Dfinir une interface distante (Xyy.java) ; 2. Crer une classe implmentant cette interface (XyyImpl.java) ; 3. Compiler cette classe (javac XyyImpl.java) ; 4. Crer une application serveur (XyyServer.java) ; 5. Compiler lapplication serveur ; 6. Crer les classes stub et skeleton laide de rmic XyyImpl_Stub.java et XyyImpl_Skel.java (Skel nexiste pas pour les versions >1.2) ; 7. Dmarrage du registre avec rmiregistry ; 8. Lancer le serveur pour la cration dobjets et leur enregistrement dans rmiregistry; 9. Crer une classe cliente qui appelle des mthodes distantes de lobjet distribu (XyyClient.java) ; 10. Compiler cette classe et la lancer.
CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

18

Inversion dune chane de caractres laide dun objet distribu


Invocation distante de la mthode reverseString() dun objet distribu qui inverse une chane de caractres fournie par lappelant.

On dfinit : ReverseInterface.java : interface qui dcrit lobjet distribu Reverse.java : qui implmente lobjet distribu ReverseServer.java : le serveur RMI ReverseClient.java : le client qui utilise lobjet distribu
19

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

Fichiers ncessaires

Ct Client

Ct Serveur

- linterface : ReverseInterface - le client : ReverseClient

- linterface : ReverseInterface - lobjet : Reverse - le serveur dobjets : ReverseServer

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

20

Interface de lobjet distribu


- Elle est partage par le client et le serveur ; - Elle dcrit les caractristiques de lobjet ; - Elle tend linterface Remote dfinie dans java.rmi. Toutes les mthodes de cette interface peuvent dclencher une exception du type RemoteException. Cette exception est leve : - si connexion refuse lhte distant - ou bien si lobjet nexiste plus, - ou encore sil y a un problme lors de lassemblage ou le dsassemblage.
Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

CNAM - Laboratoire CEDRIC

21

Interface de la classe distante

import java.rmi.Remote; import java.rmi.RemoteException; public interface ReverseInterface extends Remote { String reverseString(String chaine) throws RemoteException; }

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

22

Implmentation de lobjet distribu


Limplmentation doit tendre la classe RemoteServer de java.rmi.server RemoteServer est une classe abstraite UnicastRemoteObject tend RemoteServer - cest une classe concrte - une instance de cette classe rside sur un serveur et est disponible via le protocole TCP/IP

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

23

Implmentation de lobjet distribu


import java.rmi.*; import java.rmi.server.*; public class Reverse extends UnicastRemoteObject implements ReverseInterface { public Reverse() throws RemoteException { super(); } public String reverseString (String ChaineOrigine) throws RemoteException { int longueur=ChaineOrigine.length(); StringBuffer temp=new StringBuffer(longueur); for (int i=longueur; i>0; i--) { temp.append(ChaineOrigine.substring(i-1, i)); } return temp.toString(); } }
CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

24

Le serveur
Programme lcoute des clients ; Enregistre lobjet distribu dans rmiregistry
Naming.rebind("rmi://hote.cnam.fr:1099/MyReverse", rev);

On installe un gestionnaire de scurit si le serveur est amen charger des classes (inutile si les classes ne sont pas charges
dynamiquement) System.setSecurityManager(new RMISecurityManager());

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

25

Le serveur
import java.rmi.*; import java.rmi.server.*; public class ReverseServer { public static void main(String[] args) { try { System.out.println( "Serveur : Construction de limplmentation "); Reverse rev= new Reverse(); System.out.println("Objet Reverse li dans le RMIregistry"); Naming.rebind("rmi://sinus.cnam.fr:1099/MyReverse", rev); System.out.println("Attente des invocations des clients "); } catch (Exception e) { System.out.println("Erreur de liaison de l'objet Reverse"); System.out.println(e.toString()); } } // fin du main } // fin de la classe

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

26

Le Client
Le client obtient un stub pour accder lobjet par une URL RMI
ReverseInterface ri = (ReverseInterface) Naming.lookup ("rmi://sinus.cnam.fr:1099/MyReverse");

Une URL RMI commence par rmi://, le nom de machine, un numro de port optionnel et le nom de lobjet distant. rmi://hote:2110/nomObjet Par dfaut, le numro de port est 1099 dfini (ou dfinir) dans /etc/services : rmi 1099/tcp
CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

27

Le Client
Installe un gestionnaire de scurit pour contrler les stubs chargs dynamiquement :
System.setSecurityManager(new RMISecurityManager());

Obtient une rfrence dobjet distribu :


ReverseInterface ri = (ReverseInterface) Naming.lookup
("rmi://sinus.cnam.fr:1099/MyReverse");

Excute une mthode de lobjet :


String result = ri.reverseString ("Terre");
CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

28

Le Client
import java.rmi.*; import ReverseInterface; public class ReverseClient { public static void main (String [] args) { System.setSecurityManager(new RMISecurityManager()); try{ ReverseInterface rev = (ReverseInterface) Naming.lookup ("rmi://sinus.cnam.fr:1099/MyReverse"); String result = rev.reverseString (args [0]); System.out.println ("L'inverse de "+args[0]+" est "+result); } catch (Exception e) { System.out.println ("Erreur d'accs l'objet distant."); System.out.println (e.toString()); } } }
CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

29

Le Client
Pour que le client puisse se connecter rmiregistry, il faut lui fournir un fichier de rgles de scurit client.policy.
$more client.policy grant { permission java.net.SocketPermission ":1024-65535", "connect" ; permission java.net.SocketPermission ":80", "connect"; }; $more client1.policy
grant { permission java.security.AllPermission; };
CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

30

Compilation et Excution
- Compiler les sources (interface, implmentation de lobjet, le serveur et le client ) :
sinus> javac *.java

- Lancer rmic sur la classe dimplmentation :


sinus>rmic -v1.2 Reverse sinus>transfrer *Stub.class et ReverseInterface.class vers la machine cosinus

- Dmarrer rmiregistry :
sinus>rmiregistry -J-Djava.security.policy=client1.policy&
CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

31

- Lancer le serveur :
sinus>java ReverseServer & Serveur :Construction de limplmentation Objet Reverse li dans le RMIregistry Attente des invocations des clients

- Excuter le client :
cosinus>java -Djava.security.policy=client1.policy ReverseClient Alice L'inverse de Alice est ecilA

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

32

Charger des classes de manire dynamique - Les dfinitions de classe sont hberges sur un serveur Web ; - Les paramtres, les stubs sont envoys au client via une connexion au serveur Web; - Pour fonctionner, une application doit tlcharger les fichiers de classe. Chargement dynamique - vite de disposer localement de toutes les dfinitions de classe ; - les mmes fichiers de classe (mme version) sont partags par tous les clients - charge une classe au besoin.
CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

33

Fichiers ncessaires si pas de chargement dynamique

Ct Client

Ct Serveur

- linterface : ReverseInterface - le stub : Reverse_Stub - le client : ReverseClient

- linterface : ReverseInterface - lobjet : Reverse - le serveur dobjets : ReverseServer

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

34

Fichiers ncessaires si chargement dynamique Ct Client Ct Serveur

le client : ReverseClient

le serveur dobjets : ReverseServer

Rcuprer les fichiers de classe partir du serveur Web

Serveur Web

- Interface : ReverseInterface - Stub : Reverse_Stub - lobjet : Reverse


Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

CNAM - Laboratoire CEDRIC

35

Le client peut tre lui mme dynamique Ct Client Ct Serveur

le client : DynamicClient

le serveur dobjets : ReverseServer

Rcuprer les fichiers de classe partir du serveur Web

Serveur Web

- Interface : ReverseInterface -lobjet : Reverse - Stub : Reverse_Stub - le client : ReverseClient


Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

CNAM - Laboratoire CEDRIC

36

Le client peut tre lui mme dynamique Ct Client Le client : DynamicClient


-Chargement dynamique du client et de linterface partir dun rpertoire local. Si non disponibles localement, ils sont recherchs sur le serveur Web spcifi. -Lexcution de ReverseClient permet dobtenir la rfrence de lobjet Reverse et lappel distant de sa mthode.

Ct Serveur Le serveur dobjets : ReverseServer


-Chargement dynamique de lobjet Reverse partir du serveur Web - Enregistrement de lobjet dans RMIregistry (bind) - Attente de requtes des clients

Serveur Web
CNAM - Laboratoire CEDRIC

- Interface : ReverseInterface -lobjet : Reverse -Stub : Reverse_Stub - le client : ReverseClient


Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

37

Deux proprits systmes dans RMI

java.rmi.server.codebase : spcifie l URL (file://, ftp://,

http://) o peuvent se trouver les classes. Lorsque RMI srialise lobjet (envoy comme paramtre ou reu comme rsultat), il rajoute lURL spcifie par codebase.
java.rmi.server.useCodebaseOnly : informe le client que le

chargement de classes est fait uniquement partir du rpertoire du codebase.

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

38

Principe du chargement dynamique A lenregistrement (dans rmiregistry) de l objet distant, le codebase est spcifi par java.rmi.server.codebase. A lappel de bind(), le registre utilise ce codebase pour trouver les fichiers de classe associs lobjet. Le client recherche la dfinition de classe du stub dans son classpath. Sil ne la trouve pas, il essayera de la rcuprer partir du codebase. Une fois que toutes les dfinitions de classe sont disponibles, la mthode proxy du stub appelle les objets sur le serveur.

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

39

Scurit lors dun chargement dynamique

- Les classes java.rmi.RMISecurityManager et java.rmi.server.RMIClassLoader vrifient le contexte de scurit avant de charger des classes partir demplacements distants. - La mthode LoadClass de RMIClassLoader charge la classe partir du codebase spcifi.

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

40

Les diffrentes tapes dun chargement dynamique


-crire les classes correspondant respectivement linterface et lobjet. -Les compiler. -Gnrer le Stub correspondant lobjet. -Installer tous les fichiers de classe sur un serveur Web. -crire le serveur dynamique. -Installer rmiregistry au niveau de la machine du serveur. -Lancer le serveur en lui prcisant lURL des fichiers de classe afin quil puisse charger dynamiquement le fichier de classe correspondant lobjet, linstancier (le crer) et lenregistrer auprs de rmiregistry.

-Sur la machine du client, crire le code du client. -Compiler le client statique et linstaller ventuellement sur le site Web. -Compiler le client dynamique et le lancer en prcisant lURL des fichiers de classe.
Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

CNAM - Laboratoire CEDRIC

41

Exemple avec chargement dynamique

// linterface import java.rmi.Remote; import java.rmi.RemoteException; public interface ReverseInterface extends Remote { String reverseString(String chaine) throws RemoteException; }

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

42

Lobjet Reverse :
import java.rmi.*; import java.rmi.server.*; public class Reverse extends UnicastRemoteObject implements ReverseInterface { public Reverse() throws RemoteException { super(); } public String reverseString (String ChaineOrigine) throws RemoteException { int longueur=ChaineOrigine.length(); StringBuffer temp=new StringBuffer(longueur); for (int i=longueur; i>0; i--) { temp.append(ChaineOrigine.substring(i-1, i)); } return temp.toString(); } }
CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

43

Le serveur dynamique :
import import import import import java.rmi.Naming; java.rmi.Remote; java.rmi.RMISecurityManager; java.rmi.server.RMIClassLoader; java.util.Properties;

public class DynamicServer { public static void main(String[] args) { System.setSecurityManager(new RMISecurityManager()); try { Properties p= System.getProperties(); String url=p.getProperty("java.rmi.server.codebase"); Class ClasseServeur = RMIClassLoader.loadClass(url, "Reverse"); Naming.rebind("rmi://sinus.cnam.fr:1099/MyReverse", (Remote)ClasseServeur.newInstance());
CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

44

Suite du serveur dynamique :


System.out.println("Objet Reverse li dans le RMIregistry"); System.out.println("Attente des invocations des clients "); } catch (Exception e) { System.out.println("Erreur de liaison de l'objet Reverse"); System.out.println(e.toString()); } } // fin du main } // fin de la classe

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

45

Le client :
import java.rmi.*; public class ReverseClient { public ReverseClient () { String mot="Alice"; try{ ReverseInterface rev = (ReverseInterface) Naming.lookup ("rmi://sinus.cnam.fr:1099/MyReverse"); String result = rev.reverseString(args[0]); System.out.println ("L'inverse de " + mot + " est "+result); } catch (Exception e) { System.out.println ("Erreur d'accs l'objet distant "); System.out.println (e.toString()); } } }
CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

46

Le client dynamique :
import java.rmi.RMISecurityManager; import java.rmi.server.RMIClassLoader; import java.util.Properties; public class DynamicClient { public DynamicClient (String [] args) throws Exception { Properties p = System.getProperties(); String url = p.getProperty("java.rmi.server.codebase"); Class ClasseClient = RMIClassLoader.loadClass(url, "ReverseClient"); // lancer le client Constructor [] C = ClasseClient.getConstructors(); C[0].newInstance(new Object[]{args}); } // vrifier le passage de paramtres
CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

47

Suite du client dynamique :

public static void main (String [] args) { System.setSecurityManager(new RMISecurityManager()); try{ DynamicClient cli = new DynamicClient() ; } catch (Exception e) { System.out.println (e.toString()); } } }

CNAM - Laboratoire CEDRIC

Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

48

sinus> ls Reverse.java ReverseInterface.java DynamicServer.java sinus> javac *.java sinus> rmic -v1.2 Reverse sinus> mv Reverse*.class /var/www/html/samia/rmi Le rpertoire destination des fichiers de classe doit tre accessible par http. sinus> ls *.class DynamicServer.class sinus>rmiregistry -J-Djava.security.policy=client1.policy & sinus>java -Djava.security.policy=client1.policy -Djava.rmi.server.codebase= http://sinus.cnam.fr/samia/rmi DynamicServer Objet li Attente des invocations des clients ---------------------------------cosinus>ls *.java ReverseClient.java DynamicClient.java cosinus>javac *.java cosinus>java -Djava.security.policy=client1.policy -Djava.rmi.server.codebase= http://sinus.cnam.fr/samia/rmi DynamicClient Linverse de Alice est ecilA cosinus> Le chargement de ReverseClient se fera partir du rpertoire local alors que ReverseInterface et Reverse_Stub seront chargs partir du serveur Web spcifi dans la commande.
CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

49

Rfrences bibliographiques (RMI)

Java & Internet de Gilles Roussel et Etienne Duris, Ed Vuibert, 2000. Mastering RMI, Rickard berg, Ed. Willey, 2001. J2EE, Ed. Wrox, 2001. Cours RMI, D. Olivier & S. Bouzefrane, DESS SOR, universit du Havre, 2001/2002 Tutorial de Java RMI de Sun : http://java.sun.com/docs/books/tutorial/rmi/index.html
CNAM - Laboratoire CEDRIC Samia BOUZEFRANE (samia.bouzefrane@cnam.fr)

50

You might also like