La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

RMI Remote Method Invocation

Présentations similaires


Présentation au sujet: "RMI Remote Method Invocation"— Transcription de la présentation:

1 RMI Remote Method Invocation
RMI Remote Method Invocation Didier DONSEZ Université Joseph Fourier (Grenoble 1) IMA – LSR/ADELE Hafid Bourzoufi Université de Valenciennes - ISTV

2 Sommaire Rappel et Limites des RPC (Remote Procedure Call)
Principe des RMI Etapes de développement et d ’exécution Paramètres des méthodes Objet Activable Personnalisation de la couche de transport Ramasse-Miette distribuée Autour des RMI CORBA, IIOP, EJB RMI - H. Bourzoufi, D. Donsez,

3 Rappel des RPC RPC (Remote Procedure Call) modèle client/serveur
appel de procédures à distances entre un client et un serveur le client appelle une procédure le serveur exécute la procédure et renvoie le résultat Outil rpcgen génère la souche d ’invocation et le squelette du serveur (en C, C++, Fortran, …) la souche et le squelette ouvre un socket et encode/décode les paramètres Couche de présentation XDR (eXchange Data Representation) format pivot de représentation des données de types primitifs et structurés (tableau de longueur variable, structures) quelque soit l ’architecture (Little Endian/Big Endian, IEEE, …) le langage (ordre ligne/colonne dans les tableaux C et les tableaux Fortran) ou le système (ASCII, IBM ’ECDCII, ...) RMI - H. Bourzoufi, D. Donsez,

4 Limites des RPC Limitations Evolutions
paramêtres et valeur de retour sont des types primitifs programmation procédurale dépendance à la localisation du serveur pas d ’objet pas de « référence distante » Evolutions CORBA Multilangage, multi-plateforme (architecture+OS), MuliVendeurs Java RMI mono-langage : Java, multiplateforme : de JVM à JVM DCOM / Object RPC / .NET Remoting multi-langages, plateforme Win32 principalement, il existe des implémentations (non MicroSoft) pour Unix, Propriétaire .NET Remoting multi-langages (CLR), plateforme Win32 principalement Normalisé à l’ECMA et à l’ISO SOAP (Simple Access Object Protocol) multi-langages, multi-plateforme Réponse et requête en XML (DTD SOAP), Transport sur HTTP, IETF RMI - H. Bourzoufi, D. Donsez,

5 Principes des RMI RPC à la Java Outils
invoquer de façon simple des méthodes sur des objets distribués. Outils pour la génération des stub/skeleton, l ’enregistrement par le nom, l ’activation Tous les détails ( connexion, transfert de données ..) sont transparents pour le développeur grâce au stub/skeleton généré Mono-langage et Multiplateforme. Java : de JVM à JVM (les données et objets ont la même représentation qqs la JVM) Orienté Objet Les RMIs utilisent le mécanisme standard de sérialisation de JAVA pour l ’envoi d ’objets. Dynamique Les classes des Stubs et des paramêtres peuvent être chargées dynamiquement via HTTP ( ou NFS (file:/) Sécurité un SecurityManager vérifie si certaines opérations sont autorisés par le serveur RMI - H. Bourzoufi, D. Donsez,

6 Structure des couches RMI (i) l ’architecture logique
Client RMI (Application / Applet / Servlet) HelloClient,HelloApplet Serveur RMI HelloServer, rmid Invocation de méthodes sayHello(...) Interface Distante Hello Implémentation Distante HelloImpl Souche ou Stub HelloImpl_Stub Squelette ou Skeleton HelloImpl_Skel Couche de Référence java.rmi.Naming Couche de Référence java.rmi.Naming Couche de Transport java.net.Socket pour TCP Couche de Transport java.net.SocketServer pour TCP RMI - H. Bourzoufi, D. Donsez, Réseau (IP)

7 Structure des couches RMI (ii)
Souche ou Stub (sur le client) représentant local de l’objet distant qui implémente les méthodes “exportées” de l ’objet distant “marshalise” les arguments de la méthode distante et les envoie en un flot de données au serveur “démarshalise” la valeur ou l ’objet retournés par la méthode distante la classe xx_Stub peut être chargée dynamiquement par le client (Applet) Squelette ou Skeleton (sur le serveur) “démarshalise” les paramètres des méthodes fait un appel à la méthode de l’objet local au serveur “marshalise” la valeur ou l ’objet renvoyé par la méthode RMI - H. Bourzoufi, D. Donsez,

8 Structure des couches RMI (ii)
Couche des références distantes traduit la référence locale au stub en une référence à l’objet distant elle est servie par un processus tier : rmiregistry Couche de transport écoute les appels entrants établit et gère les connexions avec les sites distants java.rmi.UnicastRemoteObject utilise les classes Socket et SocketServer (TCP) cependant d ’autres classes peuvent être utilisées par la couche transport (Compression sur TCP, SSL sur TCP, UDP) RMI - H. Bourzoufi, D. Donsez,

9 La configuration Client HelloClient rmiregistry ... ... ... ... ...
hostcli hostreg Client HelloClient rmiregistry ... ... ... ... ... ... hostwww httpd hostser Socket Serveur HelloServer RMI - H. Bourzoufi, D. Donsez, http ou nfs Impl Stub Skel .class : Instance :

10 L ’enregistrement de l ’objet
hostcli hostreg Client HelloClient rmiregistry "HelloObject" ... ... hostwww httpd 2- le serveur enregistre l’objet distant : il communique une instance de Stub hostser Socket Serveur HelloServer RMI - H. Bourzoufi, D. Donsez, http ou nfs Impl Stub Skel 1- le serveur charge les classes Stub et Skel d ’après java.rmi.server.codebase .class : Instance :

11 La récupération du Stub
hostcli hostreg Client HelloClient 3- le client réclame le Stub associé à "HelloObject" rmiregistry "HelloObject" 4- rmiregistry retourne le Stub ... ... hostwww httpd 5- le client charge la classe Stub d ’après java.rmi.server.codebase hostser Socket Serveur HelloServer RMI - H. Bourzoufi, D. Donsez, http ou nfs Impl Stub Skel .class : Instance :

12 Invocation d ’une méthode
hostcli hostreg Client HelloClient rmiregistry "HelloObject" 6- le client invoque une méthode sur le Stub ... ... hostwww httpd 9- le Stub « demashalle » le résultat de la méthode 7- le Stub « mashalle » les paramêtres de la méthode et les envoie au serveur hostser Socket Serveur HelloServer RMI - H. Bourzoufi, D. Donsez, appel méthode Impl Stub Skel 8- le Skel « demashalle » les paramètres de la méthode et invoque la méthode sur l ’objet retourne le résultat marshallé .class : Instance :

13 Création et manipulation d'objets distants
5 Packages java.rmi : pour accéder à des objets distants java.rmi.server : pour créer des objets distants java.rmi.registry : lié à la localisation et au nommage d’objets distants java.rmi.dgc : ramasse-miettes pour les objets distants java.rmi.activation : support pour l ’activation d ’objets distants. Etapes du développement 1- Spécifier et écrire l'interface de l'objet distant. 2- Ecrire l'implémentation de cette interface. 3- Générer les Stub/Skeleton correspondants. (outil rmic) Etapes de l ’exécution 4- Ecrire le serveur qui instancie l'objet implémentant l'interface, exporte son Stub puis attend les requêtes via le Skeleton. 5- Ecrire le client qui réclame l ’objet distant, importe le Stub et invoque une méthode de l'objet distant via le Stub. RMI - H. Bourzoufi, D. Donsez,

14 1- Spécifier l ’interface d'un objet distant
Format l ’interface étend java.rmi.Remote les méthodes doivent pouvoir lever java.rmi.RemoteException Exemple package examples.hello; public interface Hello extends java.rmi.Remote{ public static final int EN=0; // English public static final int FR=1; // French public static final int ES=2; // Spanish String sayHello() throws java.rmi.RemoteException; String sayHello(String name) throws java.rmi.RemoteException; String sayHello(String name, int lang) throws java.rmi.RemoteException; } RMI - H. Bourzoufi, D. Donsez,

15 Implémentation de l ’objet distant
La classe HelloImpl doit implémenter l ’interface distante Hello et étendre une des sous-classes de java.rmi.server.RemoteServer comme java.rmi.server.UnicastRemoteObject java.rmi.server.UnicastRemoteObject sous classe le plus souvent utilisée offre toutes les fonctionnalités des classes distantes appelle la classe squelette pour la (dé)marshalisation utilise TCP/IP pour la couche transport RMI - H. Bourzoufi, D. Donsez,

16 Implémentation de l ’objet distant
package examples.hello; public class HelloImpl extends java.rmi.server.UnicastRemoteObject implements Hello { private int defaultlang; public HelloImpl(int defaultlang) throws java.rmi.RemoteException{ super(); this.defaultlang=defaultlang; } public String sayHello() { return sayHello(null, defaultlang); } public String sayHello(String name) { return sayHello(name, defaultlang); } public String sayHello(String name, int lang) { switch(lang) { case Hello.EN : break; case Hello.FR : break; case Hello.ES : break; default : lang=Hello.EN; } case Hello.EN : return "Hello " +((name==null) ? "World" : name) + " !"; case Hello.FR : return "Bonjour " +((name==null) ? "tout le monde" : name) + " !"; case Hello.ES : return "Hola " +((name==null) ? "todo el mundo" : name) + " !"; default : return null; } } // method String sayHello(String name, int lang) } // class HelloImpl RMI - H. Bourzoufi, D. Donsez,

17 La génération des Stub et Skeleton
L ’outil rmic génère la classe souche examples.hello.HelloImpl_Stub la classe squelette examples.hello.HelloImpl_Skel à partir de l ’implémentation examples.hello.HelloImpl Exemple (sous Win32) set CLASSPATH=%CLASSPATH%;./myclasses javac -d .\myclasses Hello.java javac -d .\myclasses HelloImpl.java rmic -keepgenerated -d ./myclasses examples.hello.HelloImpl Remarque: -keepgenerated à conserve les sources des Stub et Skeleton RMI - H. Bourzoufi, D. Donsez,

18 Implémentation du serveur de l ’objet distant
Crée un ou plusieurs objets distants (une ou plusieurs classes) Naming.bind() : les enregistre auprès du serveur de liaison rmiregistry Exemple package examples.hello; public class HelloServer { public static void main(String args[]) { // argument : l ’hôte/port du rmiregistry // Crée et Installe un Security Manager if (System.getSecurityManager() == null) { System.setSecurityManager(new java.rmi.RMISecurityManager()); } try { // instancie l ’objet HelloImpl obj = new HelloImpl(Hello.EN); // Enregistre l ’objet sous le nom "HelloObject" auprès de rmiregistry java.rmi.Naming.bind("//"+args[0]+"/HelloObject", obj); } catch (Exception e) { e.printStackTrace(); } } } javac -d .\myclasses HelloServer.java RMI - H. Bourzoufi, D. Donsez,

19 Implémentation du serveur de l ’objet distant
Remarques L ’objet distant servi peut être d ’une sous classe de HelloImpl public class HelloESImpl extends HelloImpl { public HelloESImpl() throws java.rmi.RemoteException{ super(HelloES); } } // et dans HelloServer java.rmi.Naming.rebind("//"+args[0]+"/HelloObject", new HelloESImpl()); Le serveur peut crée et enregistré plusieurs objets appartenant à une ou plusieurs classes l ’enregistrement peut se faire auprès des plusieurs rmiregistry RMI - H. Bourzoufi, D. Donsez,

20 Implémentation du serveur de l ’objet distant
Remarques il faut prévoir une procédure d ’arrêt (shutdown) du serveur Demande d ’arrêt Unix : kill SIGQUIT 12345 Win32 : ?? Arrêt des objets UnicastRemoteObject public static void Naming.unbind(String name) public static boolean UnicastRemoteObject.unexportObject(Remote, boolean force) Dans les exemples et tutoriels, le serveur est constitué par la méthode main(String args[]) de l ’implémentation HelloImpl RMI - H. Bourzoufi, D. Donsez,

21 Implémentation d ’un client invoquant l ’objet distant
Demande un stub auprès du serveur de liaison rmiregistry invoque des méthodes sur le stub chargé Exemple (Application) package examples.client; public class HelloClient { public static void main(String args[]) { String message = "blank"; try { // récupère le stub de l ’objet enregistré au nom de « HelloObject » Hello obj = (Hello) java.rmi.Naming.lookup("//" + args[0] + "/HelloObject"); // invocation des 3 méthodes message = obj.sayHello(); System.out.println(message); message = obj.sayHello(args[1]); System.err.println(message); System.err.println( obj.sayHello(args[1], Integer.parseInt(args[2]))); } catch (Exception e) { e.printStackTrace(); } } } javac -d .\myclasses HelloClient.java RMI - H. Bourzoufi, D. Donsez,

22 Implémentation d ’un client invoquant l ’objet distant
Exemple (Applet) import java.rmi.Naming; public class HelloApplet extends java.applet.Applet{ String message = "blank"; public void init() { try { // récupère le stub de l ’objet enregistré au nom de « HelloObject » // Remarque : rmiregistry et le serveur Web doit être sur la même machine (même #IP) Hello obj = (Hello)Naming.lookup("//" + getCodeBase().getHost() + "/HelloObject"); // invocation d ’une des 3 méthodes message = obj.sayHello(); } catch (Exception e) { // sortie d ’erreur sur la console System.out.println("HelloApplet exception:" + e.getMessage()); e.printStackTrace(); } public void paint(java.awt.Graphics g) { g.drawString(message, 25, 50); } javac -d .\myclasses HelloApplet.java RMI - H. Bourzoufi, D. Donsez,

23 L ’exécution Coté Serveur
Le serveur de liaison rmiregistry expose un objet distant serveur de liaisons (de noms) le port de liaison par défaut est le port TCP 1099 hostreg> rmiregistry ^C hostreg> rmiregistry 2001 hostreg> rmiregistry 1099 cet objet fait la correspondance entre nom et instance de Stub enregistré par le(s) serveur(s) avec Naming.bind() RMI - H. Bourzoufi, D. Donsez,

24 L ’exécution Coté Serveur L ’accès au serveur de liaison
La classe Naming encaspule le dialogue avec plusieurs objets serveur de liaison URL de liaison rmi://hostreg:2001/Hello/World rmi://:2001/Hello/World //:2001/Hello/World /Hello/World Méthodes Statiques bind(String url, Remote r), rebind(String url, Remote r), unbind(String url) enregistre/désenregistre un objet auprès du serveur Remote lookup(String url) retourne un stub String[] list() liste les noms enregistrés RMI - H. Bourzoufi, D. Donsez,

25 L ’exécution Coté Serveur L implantation du serveur de liaison
Les objets serveur de liaison réalise la correspondance nom avec stub Interface d ’un objet serveur de liaison sun.rmi.registry.Registry (extends java.rmi.Remote) Implémentation par défaut de l ’objet serveur de liaison sun.rmi.registry.RegistryImpl Méthodes non statiques bind(),rebind(),unbind(),lookup(),list() La classe LocateRegistry localise ou active un objet serveur de liaison Méthodes Statiques Registry createRegistry(int port) crée un objet serveur de liaison sur le port spécifié Registry getRegistry(int port) récupère l ’objet serveur de liaison qui a été crée RMI - H. Bourzoufi, D. Donsez,

26 L ’exécution Coté Serveur
Le serveur d ’objets distants le Stub doit être dans le CLASSPATH ou chargeable via FS ou HTTP hello.policy autorise l ’usage du accept et du connect sur les Sockets hostser> java -Djava.security.policy=./hello.policy -Djava.rmi.server.codebase= examples.hello.HelloServer hostreg:1099 Mais aussi -Djava.rmi.server.codebase=file://dev/hello/myclasses/ Unix -Djava.rmi.server.codebase=file:/c:\dev\hello\myclasses/ Win32 ./hello.policy grant { permission java.net.SocketPermission "*: ","connect,accept"; permission java.net.SocketPermission "*:80", "connect"; // permission java.security.AllPermission; /* ou autorise tout */ }; RMI - H. Bourzoufi, D. Donsez,

27 L ’exécution Coté Client
L ’application le Stub doit être dans le CLASSPATH ou chargeable via FS ou HTTP hello.policy autorise l ’usage du connect sur les Sockets hostcli> java -Djava.security.policy=./client.policy -Djava.rmi.server.codebase= examples.client.HelloClient hostreg:1099 ./client.policy grant { permission java.net.SocketPermission "*: ","connect"; permission java.net.SocketPermission "*:80", "connect"; }; RMI - H. Bourzoufi, D. Donsez,

28 L ’exécution Coté Client
L  ’applet l ’élément HTML applet doit spécifier le codebase <HTML><title>Hello World</title><center> <h1>Hello World</h1> </center> The message from the HelloServer is:<br> <applet codebase="myclasses/" code="examples.client.HelloApplet" width=500 height=120> </applet> </HTML> seuls les sockets vers hostwww sont autorisés par la sandbox donc hostreg = hostser = hostwww hostcli> appletviewer RMI - H. Bourzoufi, D. Donsez,

29 Principales Exceptions
Under Construction En Construction Client java.net.MalformedURLException java.rmi.RemoteException java.rmi.NotBoundException java.rmi.StubNotFoundException Serveur RMI - H. Bourzoufi, D. Donsez,

30 Le passage de paramètres
Les paramêtres des méthodes invoquées sur un objet distant sont soit: une valeur de type Primitif La valeur est passée un objet d ’une classe qui implemente l ’interface Serialisable (ou l ’interface Externalizable) l ’objet est sérialisé et envoyé à l ’objet distant : le paramétre est alors déserialisé pour l ’objet d istant l ’utilse un objet d ’une classe qui implémente l ’interface Remote c ’est l ’objet Stub qui est sérialisé et envoyé à l ’objet distant : quand l ’objet distant invoque un méthode sur le paramêtre, l ’invocation est distante. Une exception est levée si un paramêtre ne rentre pas dans ces trois cas. RMI - H. Bourzoufi, D. Donsez,

31 Le passage de paramètres
Un exemple plus complexe package examples.order; public class OrderLine implements java.io.Serializable { // une classe sérialisable public String productname; public int quantity; } import java.util.Vector; // une classe sérialisable public interface Order extends java.rmi.Remote { // l ’interface distante public float price(String productname, int quantity) throws java.rmi.RemoteException; public float price(Vector orderlines) throws java.rmi.RemoteException; public float price(OrderLine[] orderlines) throws java.rmi.RemoteException; public Vector priceInDetail(Vector orderlines) throws java.rmi.RemoteException; public Vector priceInDetail(OrderLine[] orderlines) throws java.rmi.RemoteException; RMI - H. Bourzoufi, D. Donsez,

32 Le passage de paramètres
Un exemple plus complexe package examples.order; public class OrderException extends Exception { // exception applicative ou java.rmi.RemoteException private String unknownproductname; public OrderException(String productname) { this.unknownproductname=productname; } public String toString() { return "Unknown Product Name : " + unknownproductname; } public interface Order extends java.rmi.Remote { // l ’interface distante public float price(String productname, int quantity) throws java.rmi.RemoteException, OrderException; ... RMI - H. Bourzoufi, D. Donsez,

33 Passage d ’un paramètre de classe inconnue du serveur
La sous classe d’un paramètre est inconnue du serveur le serveur charge la classe du sous-type inconnu à partir du java.rmi.server.codebase du client à défaut du CLASSPATH Voir : jdk1.2.2/docs/guide/rmi/codebase.htm RMI - H. Bourzoufi, D. Donsez,

34 Passage d ’un paramètre de classe inconnue du serveur (i)
Socket appel méthode hostcli Impl Client HelloClient 6- le client invoque une méthode avec un paramêtre inconnu du serveur Param.class : Instance : 7- le Stub sérialise l’instance du paramêtre et l’envoie au serveur hostser Serveur HelloServer RMI - H. Bourzoufi, D. Donsez, hostwww2 8- le serveur charge la classe d ’après java.rmi.server.codebase du client httpd

35 Passage d ’un paramètre de classe inconnue du serveur (ii)
Socket appel méthode hostcli Impl Client HelloClient Param.class : Instance : 9 - l ’objet est déserialisé 10- la méthode est invoquée hostser Serveur HelloServer 12- le Stub « démashalle » le résultat de la méthode 11- le Skel retourne le résultat marshallé RMI - H. Bourzoufi, D. Donsez, hostwww2 httpd

36 Passage d ’un paramêtre de classe inconnue du serveur - Exemple
package examples.bank; // l ’interface du 1er paramêtre de la méthode credit() public interface Account extends Serializable { float getBalance(); void setBalance(float amount); } // l ’interface de l ’objet distant public interface Bank implements Remote { void credit(Account acc, float amount); } // une sous-classe de Account inconnue du serveur public class CheckingAccount implements examples.bank.Account { private String name; private float balance; public CheckingAccount(String name, float initamount) { this.name=name; this.balance= initamount; } public float getBalance(return balance;) public void setBalance(float amount) { balance=amount; } } // un client examples.bank.Bank mybank = (Bank) java.rmi.Naming.lookup("//hostreg/MyBank"); examples.bank.Account accjohn = new CheckingAccount("john",1000.0); mybank.credit(accjohn,2000.0); RMI - H. Bourzoufi, D. Donsez,

37 Le passage de paramètres
Le passage en paramêtre d ’un Stub (cas 3) l ’objet Stub est du type de la déclaration l ’objet Stub est d ’un sous type inconnu le java.rmi.server.codebase du client est utilisé par le serveur à défaut du CLASSPATH pour charger la classe du sous-type Voir : jdk1.2.2/docs/guide/rmi/codebase.htm RMI - H. Bourzoufi, D. Donsez,

38 Le passage de paramètres Exemple
Le passage en paramêtre d ’un Stub (cas 3) interface Account implements Remote { float getBalance(); void setBalance(float amount); } interface Bank implements Remote { void credit(Account acc, float amount); } Bank ban1 = (Bank) java.rmi.Naming.lookup("//regb/CA"); Account acc1 = (Account) java.rmi.Naming.lookup("//reg1/Account1"); ban1.debit(acc1,2000.0); Account acc2=new CheckingAccount("john",1000.0) java.rmi.Naming.rebind("//reg2/Account2",acc2); ban1.credit(acc2,2000.0); RMI - H. Bourzoufi, D. Donsez,

39 Passage d ’un Stub en paramêtre
Méthode 1 Le Stub est celui d ’un objet distant déjà servi Méthode 2 : Objet Distant Temporaire But: L ’objet distant est local au client et n ’est utilisé que pour la durée d ’une ou plusieurs invocations distantes depuis le client Solution exporter l ’objet avec la méthode UnicastRemoteObject.exportObjet() l ’objet doit implémenter l ’interface Unreferenced pour être ramassé par le GC RMI est basé sur le paradigme des invocations methodes synchrones Tant que la méthode distance n'est pas terminée, l'appelant est bloqué Solution : fournir, côté client, un OD temporaire pour la récéption des résultats voir cours Olivier Dedieu sur les RMI L'OD temporaire est construit de la même façon que les autres OD • Il est exporté de la même façon • Il n'est pas nécessaire de le référencer dans Naming • Il doit implementer Unreferenced pour se terminer correctement RMI - H. Bourzoufi, D. Donsez,

40 Objet Distant Temporaire Le client
public class AsyncHelloClient { public static void main( String[] args) { Hello hello = (Hello) Naming. lookup("//hostreg/HelloObject"); Person person = new PersonImpl("Didier","Donsez"); UnicastRemoteObject.exportObject(person); String hellomessage = hello.sayHello(person, Hello.EN); person = null; // force le GC local et le GC reparti System.println.out(hellomessage); ... } public class Client { public static void main( String[] args) { Server server =( Server) Naming. lookup("// falconet/ Server"); TmpServer tmpServer = new TmpServerImpl(); UnicastRemoteObject. exportObject( tmpServer); server. call(" Hello", tmpServer); tmpServer = null; } RMI - H. Bourzoufi, D. Donsez,

41 Objet Distant Temporaire Le serveur temporaire
public interface Person extends Remote { String getFirstname() throws RemoteException; String getLastname() throws RemoteException; } public class PersonImpl implements Person, Unreferenced { private String lastname; private String firstname; PersonImpl(String lastname, String firstname) { this.lastname=lastname,this.firstname=firstname; String getFirstname() throws RemoteException { return firstname; } String getLastname() throws RemoteException { return lastname; } void unreferenced() { ThreadGroup tg = Thread.currentThread().getThreadGroup(); tg. stop() Le serveur temporaire : public interface TmpServer extends Remote { void returnString( String text) throws RemoteException; } public class TmpServerImpl implements TmpServer, Unreferenced { void returnString( String text) throws RemoteException { System. out. println( text); void unreferenced() { ThreadGroup g = Thread. currentThread(). getThreadGroup(); g. stop() RMI - H. Bourzoufi, D. Donsez,

42 Objet Distant Temporaire L ’objet distant et son serveur
public interface Hello extends Remote { String sayHello(Person person, int lang) throws RemoteException; String sayHello(String name, int lang) throws RemoteException; } public class HelloImpl extends java.rmi.server.UnicastRemoteObject implements Hello { String sayHello(Person person, int lang) throws RemoteException { String firstname= person.getFirstname(); // invocation distante sur le Stub String lastname= person.getLastname(); // invocation distante sur le Stub return sayHello(firstname + " " + lastname, lang); } … } public class HelloServer { public static void main(String args[]) { if (System.getSecurityManager() == null) { System.setSecurityManager(new java.rmi.RMISecurityManager()); } try { HelloImpl obj = new HelloImpl(Hello.EN); java.rmi.Naming.rebind("//hostreg/HelloObject", obj); } catch (Exception e) { e.printStackTrace(); } } } L’objet distant :public interface Server extends Remote { void call( String, TmpServer tmpServer) throws RemoteException } public class ServerImp implements Remote { void call( String text, TmpServer tmpServer) { tmpServer. returnString( text. toUpperCase()); tmpServer= null; System. gc(); public static void main( String[] args) { Server server = new Server(); UnicastRemoteObject. exportObject( server); Naming. rebind("// falconet/ Server", server); RMI - H. Bourzoufi, D. Donsez,

43 Objet Distant Temporaire Déroulement de l ’exécution
hostcli hostser JVM AsyncHelloClient JVM HelloServer main thread hello unicastobject thread person thread(s) création de person attente d ’une invocation de méthode export de person invocation de hello.sayHello(person,Hello.EN) exécution de hello.sayHello(person,Hello.EN) attente d ’une méthode attente du résultat invocation de person.getFirstname() exécution de person.getFirstname() invocation de person.getLastname() exécution de person.getLastname() RMI - H. Bourzoufi, D. Donsez, réception du résultat attente d ’une invocation de méthode DGC réception et exécution de unreferenced()

44 Le détail du Stub généré
Under Construction En Construction // Stub class generated by rmic, do not edit. // Contents subject to change without notice. package examples.hello; public final class HelloImpl_Stub extends java.rmi.server.RemoteStub implements examples.hello.Hello, java.rmi.Remote { private static final java.rmi.server.Operation[] operations = { new java.rmi.server.Operation("java.lang.String sayHello()"), new java.rmi.server.Operation("java.lang.String sayHello(java.lang.String)"), new java.rmi.server.Operation("java.lang.String sayHello(java.lang.String, int)") }; private static final long interfaceHash = L; private static final long serialVersionUID = 2; private static boolean useNewInvoke; private static java.lang.reflect.Method $method_sayHello_0; private static java.lang.reflect.Method $method_sayHello_1; private static java.lang.reflect.Method $method_sayHello_2; static { try { java.rmi.server.RemoteRef.class.getMethod("invoke", new java.lang.Class[] { java.rmi.Remote.class, java.lang.reflect.Method.class, java.lang.Object[].class, long.class }); useNewInvoke = true; $method_sayHello_0 = examples.hello.Hello.class.getMethod("sayHello", new java.lang.Class[] {}); $method_sayHello_1 = examples.hello.Hello.class.getMethod("sayHello", new java.lang.Class[] {java.lang.String.class}); $method_sayHello_2 = examples.hello.Hello.class.getMethod("sayHello", new java.lang.Class[] {java.lang.String.class, int.class}); } catch (java.lang.NoSuchMethodException e) { useNewInvoke = false; } // constructors public HelloImpl_Stub() { super(); public HelloImpl_Stub(java.rmi.server.RemoteRef ref) { super(ref); // methods from remote interfaces // implementation of sayHello() public java.lang.String sayHello() throws java.rmi.RemoteException if (useNewInvoke) { Object $result = ref.invoke(this, $method_sayHello_0, null, L); return ((java.lang.String) $result); } else { java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); ref.invoke(call); java.lang.String $result; java.io.ObjectInput in = call.getInputStream(); $result = (java.lang.String) in.readObject(); } catch (java.io.IOException e) { throw new java.rmi.UnmarshalException("error unmarshalling return", e); } catch (java.lang.ClassNotFoundException e) { } finally { ref.done(call); return $result; } catch (java.lang.RuntimeException e) { throw e; } catch (java.rmi.RemoteException e) { } catch (java.lang.Exception e) { throw new java.rmi.UnexpectedException("undeclared checked exception", e); // implementation of sayHello(String) public java.lang.String sayHello(java.lang.String $param_String_1) Object $result = ref.invoke(this, $method_sayHello_1, new java.lang.Object[] {$param_String_1}, L); java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash); java.io.ObjectOutput out = call.getOutputStream(); out.writeObject($param_String_1); throw new java.rmi.MarshalException("error marshalling arguments", e); // implementation of sayHello(String, int) public java.lang.String sayHello(java.lang.String $param_String_1, int $param_int_2) Object $result = ref.invoke(this, $method_sayHello_2, new java.lang.Object[] {$param_String_1, new java.lang.Integer($param_int_2)}, L); java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 2, interfaceHash); out.writeInt($param_int_2); RMI - H. Bourzoufi, D. Donsez,

45 Le détail du Skeleton généré
Under Construction En Construction // Skeleton class generated by rmic, do not edit. // Contents subject to change without notice. package examples.hello; public final class HelloImpl_Skel implements java.rmi.server.Skeleton { private static final java.rmi.server.Operation[] operations = { new java.rmi.server.Operation("java.lang.String sayHello()"), new java.rmi.server.Operation("java.lang.String sayHello(java.lang.String)"), new java.rmi.server.Operation("java.lang.String sayHello(java.lang.String, int)") }; private static final long interfaceHash = L; public java.rmi.server.Operation[] getOperations() { return (java.rmi.server.Operation[]) operations.clone(); } public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall call, int opnum, long hash) throws java.lang.Exception if (opnum < 0) { if (hash == L) { opnum = 0; } else if (hash == L) { opnum = 1; } else if (hash == L) { opnum = 2; } else { throw new java.rmi.UnmarshalException("invalid method hash"); if (hash != interfaceHash) throw new java.rmi.server.SkeletonMismatchException("interface hash mismatch"); examples.hello.HelloImpl server = (examples.hello.HelloImpl) obj; switch (opnum) { case 0: // sayHello() call.releaseInputStream(); java.lang.String $result = server.sayHello(); try { java.io.ObjectOutput out = call.getResultStream(true); out.writeObject($result); } catch (java.io.IOException e) { throw new java.rmi.MarshalException("error marshalling return", e); break; case 1: // sayHello(String) java.lang.String $param_String_1; java.io.ObjectInput in = call.getInputStream(); $param_String_1 = (java.lang.String) in.readObject(); throw new java.rmi.UnmarshalException("error unmarshalling arguments", e); } catch (java.lang.ClassNotFoundException e) { } finally { java.lang.String $result = server.sayHello($param_String_1); case 2: // sayHello(String, int) int $param_int_2; $param_int_2 = in.readInt(); java.lang.String $result = server.sayHello($param_String_1, $param_int_2); default: throw new java.rmi.UnmarshalException("invalid method number"); RMI - H. Bourzoufi, D. Donsez,

46 L ’activation d ’objets distants
Rappel (JDK1.1) l ’objet distant est actif au démarrage du serveur RMI Motivation principe du démon inetd d ’Unix Le démon rmid démarre une JVM qui sert l ’objet distant seulement au moment de l ’invocation d ’une méthode (à la demande) ou au reboot. JDK1.2 introduit un nouveau package java.rmi.activation un objet activable doit dériver de la classe Activatable un démon RMI rmid qui active les objets à la demande ou au reboot de la machine Info : jdk1.2.2\docs\guide\rmi\activation.html Remarque : l’activition est très utilisée par JINI ! RMI - H. Bourzoufi, D. Donsez,

47 Créer une implémentation activable
La classe doit étendre java.rmi.activation.Activable et implémenter l ’interface distante La classe doit déclarer un constructeur avec 2 arguments java.rmi.activation.ActivationID, java.rmi.MarshalledObject public class HelloActivatableImpl extends java.rmi.activation.Activatable implements Hello { private int defaultlang; public ActivatableImplementation(ActivationID id, MarshalledObject data) throws java.rmi.RemoteException { super(id, 0); this.defaultlang=((Integer)data.get()).intValue(); } // implémentation des méthodes public String sayHello() throws java.rmi.RemoteException { … } ... RMI - H. Bourzoufi, D. Donsez,

48 Créer le programme d ’enregistrement (Setup)
passer l ’information nécessaire à l ’activation de l ’objet activable au démon rmid puis enregistrer l ’objet auprès de rmiregistry Descripteur ActivationDesc : description des informations nécessaires à rmid Groupes d’objets activables rmid active une JVM par groupe Les objets du même groupe partagent la même JVM ActivationGroup : représente un groupe d ’objets activables ActivationGroupDesc : description d ’un groupe ActivationGroupID : identifiant d ’un groupe RMI - H. Bourzoufi, D. Donsez,

49 Créer le programme d ’enregistrement Exemple (partie 1)
import java.rmi.*; import java.rmi.activation.*; import java.util.Properties; public class SetupActivHello { public static void main(String[] args) throws Exception { System.setSecurityManager(new RMISecurityManager()); // création d ’un groupe d ’objets activables Properties props = new Properties(); props.put("java.security.policy", "./helloactiv.policy"); ActivationGroupDesc.CommandEnvironment ace = null; // descripteur du groupe ActivationGroupDesc agroupdesc = new ActivationGroupDesc(props, ace); // ActivationSystem asystem = ActivationGroup.getSystem(); ActivationGroupID agi = asystem.registerGroup(agroupdesc); // enregistrement du groupe ActivationGroup.createGroup(agi, agroupdesc , 0); RMI - H. Bourzoufi, D. Donsez,

50 Créer le programme d ’enregistrement Exemple (partie 2)
// le descripteur doit contenir le codebase pour chercher les classes String classeslocation = " // le descripteur peut contenir un objet sérialisable pour l ’initialisation de l ’objet ; data peut être null MarshalledObject data = new MarshalledObject (new Integer(Home.ES)); // création d ’un descripteur pour l ’objet activable ActivationDesc adesc = new ActivationDesc (agi, "examples.hello.HelloActivatableImpl", classeslocation, data ); // enregistrement de l ’objet auprès du démon rmid : récupération d ’un stub Hello obj = (Hello)Activatable.register(adesc); // enregistrement du stub auprès du rmiregistry Naming.rebind("//hostreg/HelloActiv", obj); System.exit(0); } RMI - H. Bourzoufi, D. Donsez,

51 Personnaliser la couche Transport des RMI
Rappel Par défaut, TCP est utilisé par la couche de transport RMISocketFactory (classes java.net.Socket et java.net.SocketServer) cependant dans les cas de Firewall/proxies, elle invoque les méthodes en utilisant la méthode POST de HTTP. La propriété java.rmi.server.disableHttp=true désactive le tunneling HTTP Motivation utiliser d ’autres classes (que Socket et SocketServer) basées sur TCP pour de la compression, du chiffrage, … Remarque : RMI over SSL utilise cette technique (voir l ’exemple) ou non (UDP) Info : jdk1.2.2\docs\guide\rmi\rmisocketfactory.doc.html RMI - H. Bourzoufi, D. Donsez,

52 Personnaliser la couche Transport des RMI
Etape 1 Écrire 2 sous classes de java.rmi.RMIClientSocketFactory, java.rmi. RMIServerSocketFactory qui utilisent 2 autres classes de transport que java.net.Socket java.net.SocketServer (voir cours Socket) RMI - H. Bourzoufi, D. Donsez,

53 Personnaliser la couche Transport des RMI
package examples.rmisocfac; import java.io.*; import java.net.*; import java.rmi.server.*; public class CompressionClientSocketFactory implements RMIClientSocketFactory, Serializable { public Socket createSocket(String host, int port) throws IOException { return new CompressionSocket(host, port); } } public class CompressionServerSocketFactory implements RMIServerSocketFactory, Serializable { public ServerSocket createServerSocket(int port) throws IOException { return new CompressionServerSocket(port); RMI - H. Bourzoufi, D. Donsez,

54 Personnaliser la couche Transport des RMI
Etape 2 Spécifier les factories dans le constructeur de l ’objet distant qui hérite de la classe UnicastRemoteObject protected UnicastRemoteObject( int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) Exemple: public AccountImpl() throws RemoteException { super( 0, new CompressionClientSocketFactory(), new CompressionServerSocketFactory() ); … } RMI - H. Bourzoufi, D. Donsez,

55 RMI et SSL Couche de transport custom voir
SSLClientSocketFactory, SSLServerSocketFactory utilisent SSLSocket, SSLServerSocket ( voir jdk1.2.2\docs\guide\rmi\SSLInfo.html jdk1.2.2\docs\guide\rmi\PhaosExample.html RMI - H. Bourzoufi, D. Donsez,

56 RMI over SSL RMIClientSocketFactory et RMIServerSocketFactory
package examples.rmissl; import java.io.*; import java.net.*; import java.rmi.server.*; import crypsec.SSL.*; // importe des classes de SSL ( public class SSLClientSocketFactory implements RMIClientSocketFactory, Serializable { public Socket createSocket(String host, int port) throws IOException { return ((Socket) new SSLSocket(host, port, new SSLParams())); } } public class SSLServerSocketFactory implements RMIServerSocketFactory, Serializable { transient protected SSLParams params; public SSLServerSocketFactory() { this(new SSLParams()); } public SSLServerSocketFactory(SSLParams p) { params = p; } public ServerSocket createServerSocket(int port) throws IOException { return new SSLServerSocket(port); RMI - H. Bourzoufi, D. Donsez,

57 RMI over SSL l ’objet distant
package examples.rmissl; import java.io.*; import java.net.*; import java.rmi.*; import java.rmi.server.*; public class SSLHelloImpl extends UnicastRemoteObject implements Hello { private int defaultlang ; public SSLHelloImpl(SSLServerSocketFactory ssf, int defaultlang) throws RemoteException { super(0, new SSLClientSocketFactory(), ssf); this.defaultlang = defaultlang ; } public String sayHello() throws RemoteException { ... } ... RMI - H. Bourzoufi, D. Donsez,

58 RMI over SSL le serveur package examples.rmissl;
import java.io.*; import java.net.*; import java.rmi.*; import java.rmi.server.*; public class SSLHelloServer { public static void main(String args[]) { try { // initialize server certificate SSLCertificate cert = new SSLCertificate(); cert.certificateList = new Vector(); cert.certificateList.addElement(new X509(new File("server-cert.der"))); cert.certificateList.addElement(new X509(new File("ca-cert.der"))); SSLParams params = new SSLParams(); // initialize SSL context object params.setServerCert(cert); params.setRequestClientCert(true); // require client authentication System.setSecurityManager(new RMISecurityManager()); // secure server socket factory to use in remote objects SSLServerSocketFactory ssf = new SSLServerSocketFactory(params); // create a secure rmiregistry Registry registry = LocateRegistry.createRegistry(1099,new SSLClientSocketFactory(), ssf); // create a remote object that will use a secure client/server socket pair SSLHelloImpl o = new SSLHelloImpl(ssf, Hello.FR); registry.rebind("/SSLHelloObject", o); } catch (Exception e) { System.err.println(e.getMessage()); e.printStackTrace(); } } } RMI - H. Bourzoufi, D. Donsez,

59 RMI over SSL le client package examples.rmissl;
import java.io.*; import java.net.*; import java.rmi.*; import java.rmi.server.*; public class SSLHelloClient { public static void main(String args[]) { try { if (args.length < 1) { System.err.println("Usage: <hostName>"); System.exit(1); } System.setSecurityManager(new RMISecurityManager()); // Create a secure rmiregistry Registry registry = LocateRegistry. getRegistry(args[0], 1099, new SSLClientSocketFactory()); // Obtain a reference to the HelloObject Hello hello = (Hello) registry.lookup("/SSLHelloObject"); System.out.println("Message: " + hello.sayHello()); } catch (Exception e) { e.printStackTrace(); } RMI - H. Bourzoufi, D. Donsez,

60 Le glaneur de cellules distibué des RMI java.rmi.dgc
Motivation pour un GC réparti ramasser les objets distants qui ne sont plus référencés (i.e. plus de stub sur des clients) Principe basé sur le comptage de références interagit avec les GCs locaux de toutes les JVM maintient des weaks references pour éviter le ramassage par le GC local Remarque: en cas de partition du réseau, les objets peuvent être prématurément ramassés RMI - H. Bourzoufi, D. Donsez,

61 Le glaneur de cellules distibué des RMI java.rmi.dgc
Interface java.rmi.server.Unreferenced package java.rmi.server; public interface Unreferenced { public void unreferenced(); } Un objet distant peut être notifié quand il n ’est plus référencé il doit implémenter l ’interface java.rmi.server.Unreferenced la méthode void unreferenced() est appelée par le DGC quand il n ’y a plus de référence. RMI - H. Bourzoufi, D. Donsez,

62 Le glaneur de cellules distibué des RMI java.rmi.dgc
Under Construction En Construction Etapes du GC Lorsqu'un OD est passé en paramètre à un autre OD ® ref_count++ Lorsqu'un stub n'est plus référencé ® weak reference Lorsque le GC du client libère le stub, sa méthode finalize est appellée et informe le DGC ® ref_count­­ Lorsque le nombre de références d'un OD = 0 ® weak reference Le GC du serveur peut alors libérer l'OD Le client doit régulierement renouveller son bail au pres du DGC. Si référence à un OD libéré ® RemoteException 3 Garbage Collection of Remote Objects In a distributed system, just as in the local system, it is desirable to automatically delete those remote objects that are no longer referenced by any client. This frees the programmer from needing to keep track of the remote objects clients so that it can terminate appropriately. RMI uses a reference-counting garbage collection algorithm similar to Modula-3's Network Objects. (See "Network Objects" by Birrell, Nelson, and Owicki, Digital Equipment Corporation Systems Research Center Technical Report 115, 1994.) To accomplish reference-counting garbage collection, the RMI runtime keeps track of all live references within each Java virtual machine. When a live reference enters a Java virtual machine, its reference count is incremented. The first reference to an object sends a "referenced" message to the server for the object. As live references are found to be unreferenced in the local virtual machine, the count is decremented. When the last reference has been discarded, an unreferenced message is sent to the server. Many subtleties exist in the protocol; most of these are related to maintaining the ordering of referenced and unreferenced messages in order to ensure that the object is not prematurely collected. When a remote object is not referenced by any client, the RMI runtime refers to it using a weak reference. The weak reference allows the Java virtual machine's garbage collector to discard the object if no other local references to the object exist. The distributed garbage collection algorithm interacts with the local Java virtual machine's garbage collector in the usual ways by holding normal or weak references to objects. As long as a local reference to a remote object exists, it cannot be garbage- collected and it can be passed in remote calls or returned to clients. Passing a remote object adds the identifier for the virtual machine to which it was passed to the referenced set. A remote object needing unreferenced notification must implement the java.rmi.server.Unreferenced interface. When those references no longer exist, the unreferenced method will be invoked. unreferenced is called when the set of references is found to be empty so it might be called more than once. Remote objects are only collected when no more references, either local or remote, still exist. Note that if a network partition exists between a client and a remote server object, it is possible that premature collection of the remote object will occur (since the transport might believe that the client crashed). Because of the possibility of premature collection, remote references cannot guarantee referential integrity; in other words, it is always possible that a remote reference may in fact not refer to an existing object. An attempt to use such a reference will generate a RemoteException which must be handled by the application. RMI - H. Bourzoufi, D. Donsez,

63 Détail d ’implantation
Under Construction En Construction Coté serveur Une thread par appel d ’un client + la thread d ’écoute des nouveaux appels sur le socket L ’appel concurrent aux méthodes n ’est pas synchronisé La synchronisation est à la charge du développeur Un couple <hôte,port> pour tous les objets par une JVM Java RMI Internals The RMI Server creates an instance of the 'Server Object' which extends UnicastRemoteObject The constructor for UnicastRemoteObject "exports" the Server Object - basically making it available to service incoming RMI calls. A TCP socket which is bound to an arbitrary port number is created and a thread is also created that listens for connections on that socket. The server registers the server object with the registry. This operation actually hands the registry (Note: The RMI Registry is an RMI server itself) the client-side "stub" for that server object. This stub contains the information needed to "call back" to the server when it is invoked (such as the hostname/port of the server listening socket). A client obtains this stub by calling the registry, which hands it the stub directly. (This is also where the "codebase" comes in: If the server specified a "codebase" to use for clients to obtain the classfile for the stub, this will be passed along to the client via the registry. The client can then use the codebase to resolve the stub class - that is, to load the stub classfile itself). That is all that the RMIRegistry really does: It holds onto remote object stubs which it can hand off to clients when requested. When the client issues a remote method invocation to the server, the stub class creates a "RemoteCall" which basically (a) opens a socket to the server on the port specified in the stub itself, and (b) Sends the RMI header information as described in the RMI spec. The stub class marshalls the arguments over the connection by using methods on RemoteCall to obtain the output stream which basically returns a subclass of ObjectOutputStream which knows how to deal with passing objects which extend java.rmi.Remote, which serializes Java objects over the socket The stub class calls RemoteCall.executeCall which causes the RMI to happen. On the server side, when a client connects to the server socket, a new thread is forked to deal with the incoming call. The original thread can continue listening to the original socket so that additional calls from other clients can be made. The server reads the header information and creates a RemoteCall of its own to deal with unmarshalling the RMI arguments from the socket. The server calls the "dispatch" method of the skeleton class (the server-side "stub" generated by rmic), which calls the appropriate method on the object and pushes the result back down the wire (using the same 'RemoteCall' interface which the client used to marshall the arguments). If the server object threw an exception then the server catches this and marshalls that down the wire instead of the return value. Back on the client side, the return value of the RMI is unmarshalled (using the RemoteCall created in step 5 above) and returned from the stub back to the client code itself. If an exception was thrown from the server that's unmarshalled and re-thrown from the stub. Now, it should be obvious how multiple clients call the same server object: They all get stubs which contain the same hostname/port number as the server-side socket which is listening for calls on the object. When a client connects, the server forks a new thread to deal with the incoming request, but keeps listening to that original socket (in another thread) so that other calls can be made. There doesn't appear to be any synchronization within the server side components - if multiple clients simultaneously call into the server object they can all manipulate the server object state at the same time. You can of course make methods in your server object "synchronized" to synchronize access to them. Now, the RMI specification defines both a "single op" and a "stream" protocol for RMI calls. The former allows a single RMI call to be made on a socket which is then closed; the latter allows multiple RMI calls to be issued on the same socket one after the other. Sun's RMI implementation appears to be using this latter mechanism which means that a single client-side stub object will open a single socket to the server for all of its communication. Multiple stubs within the same JVM or different JVMs on the same host will each have their own socket to the server (which might all dispatch calls to the same server-side object). The net result is that each time you obtain a stub (from the registry) for a particular server-side object, you will eventually create a new socket to talk to the server. So basically: ON THE SERVER: A single 'UnicastRemoteObject' which ends up creating multiple threads to listen for calls on this single object - one thread per socket (basically meaning one thread per client) ON THE CLIENT: One socket to the server per stub, meaning that if the client has multiple stubs pointing to the same server object it will have multiple sockets open to that server. RMI - H. Bourzoufi, D. Donsez,

64 Under Construction En Construction
RMI over IIOP Under Construction En Construction Couche de transport : IIOP ( RMI - H. Bourzoufi, D. Donsez,

65 Under Construction En Construction
RMI et EJB Under Construction En Construction RMI - H. Bourzoufi, D. Donsez,

66 Under Construction En Construction
RMI et EJB Under Construction En Construction Encapsulation des RMI dans 2 interfaces EJBHome EJBObject Nommage avec JNDI RMI - H. Bourzoufi, D. Donsez,

67 RMI et JINI JINI mécanisme discovery-join-lookup
Nommage tolérant aux pannes (redondance) Recherche par rapport à l’interface du service à des attributs qualifiants (Entry) à des groupes Le client récupère la liste des objets distants (stub RMI) potentiellement actifs ou activables offrant ce service RMI - H. Bourzoufi, D. Donsez,

68 Ajout du J2SE 1.4 java.rmi.server.RMIClassLoaderSpi
Délégation du chargement dynamique des classes Support du POA (Portable Object Adapter) pour rmic rmic -iiop -poa … Certain static methods of java.rmi.server.RMIClassLoader now delegate their behavior to an instance of a new service provider interface, java.rmi.server.RMIClassLoaderSpi. This service provider object can be configured to augment RMI's dynamic class loading behavior for a given application. By default, the service provider implements the standard behavior of all of the static methods in RMIClassLoader. See the class documentation of RMIClassLoader and RMIClassLoaderSpi for more details. The rmic compiler has a new option to enable Portable Object Adapter, or POA support for Remote Method Invocation. The POA enables portability among vendor ORBs, among other uses. To lea rn more about the POA, follow the link. To enable POA support with the rmic compiler, use the arguments rmic -iiop -poa. RMI - H. Bourzoufi, D. Donsez,

69 Comparaison RPC RMI CORBA SOAP Qui SUN/OSF SUN OMG W3C Plate-formes
.NET Remoting SOAP Qui SUN/OSF SUN OMG MicroSoft/ECMA W3C Plate-formes Multi Multi Multi Win32, FreeBSD, Linux Multi Langages de Programmation C, C++, … Java Multi C#, VB, J#, … Multi Langages de Définition de Service RPCGEN Java IDL CLR XML Réseau TCP, UDP TCP, HTTP, IIOP customisable GIOP, IIOP, Pluggable Transport Layer TCP,HTTP, IIOP RPC,HTTP Marshalling Sérialisation Java Représentation IIOP Formatteurs Binaire, SOAP SOAP RMI - H. Bourzoufi, D. Donsez, Nommage IP+Port RMI, JNDI,JINI CosNaming IP+Nom IP+Port, URL Intercepteur Non depuis 1.4 Oui Oui CallContext Extension applicative dans le header Extra Chargement dynamique des classes Services Communs Services Sectoriels Pas de Chargement dynamique des classes

70 Comparaison RMI RPC DCOM CORBA SOAP Qui SUN SUN/OSF MicroSoft OMG W3C
Plate-formes Multi Multi Win32 Multi Multi Langages de Programmation Java C, C++, … C++, VB, VJ, OPascal, … Multi Multi Langages de Définition de Service Java RPCGEN ODL IDL XML Réseau TCP, HTTP, IIOP customisable TCP, UDP IP/IPX GIOP, IIOP, Pluggable Transport Layer RPC,HTTP Firewall Tunneling HTTP HTTP RMI - H. Bourzoufi, D. Donsez, Nommage RMI, JNDI,JINI IP+Port IP+Nom Nom IP+Port, URL Transaction Non Non MTS OTS, XA Extension applicative dans le header Extra Chargement dynamique des classes Services Communs Services Sectoriels

71 Bibliographie Spécification des RMI Guide de la doc du JDK
java.sun.com et jdk1.2.2/docs/guide/rmi/spec Guide de la doc du JDK jdk1.2.2/docs/guide/rmi Tutorial Java Trail sur les RMI et sur JINI (Objet activables) Online Training Autres Jeremie : une implémentation OpenSource des RMI RMI - H. Bourzoufi, D. Donsez,

72 Bibliographie Gilles Roussel, Étienne Duris, "Java et Internet, Concepts et programmation", Ed Vuibert, 01/2000, ISBN : le chapitre 11 détaille bien les RMI du JDK1.2 et notamment les objets activables Elliotte Rusty Harold, "Programmation Réseau avec Java", Ed O Reilly, 1997, ISBN date un peu Java Distributed Computing, Ed Oreilly existe en français Robert Orfali, Dan Harkey, “ Client/Server Programming with Java and Corba ”, 2ème édition, 1998, Ed Wiley, ISBN X. survol rapide comparaison intéressante avec les autres techniques (DCOM, CORBA, …) RMI - H. Bourzoufi, D. Donsez,


Télécharger ppt "RMI Remote Method Invocation"

Présentations similaires


Annonces Google