Upload
marrok-guyard
View
109
Download
2
Embed Size (px)
Citation preview
Des sockets à RMI
Pourquoi ?
Maturation de la technologie orientée objet ADA, Modula Smalltalk , C++, Java
Maturation des communications Client-Serveur sockets RPC couches OSI
L’héritage de la programmation Client Serveur
Importance du marshallingDes serveurs accessibles simultanément par plusieurs clientsEnregistrement des serveurs dans des annuaires de nomsCommunication connectée ou par message…..
Appel de procédures à distance
Circulation de messages et machines hétérogènes
Couche de services Annuaires Sécurité Protocole
d’applications
Couche de transport TCP UDP
Infrastructure informatique de distribution
Exemple
CLIENT EPUNSAfun SERVEUR de Surnoms
oter
infrastructure
Protocole d’application ?
Communication client serveur
CLIENT SERVEUR
Préparation de la requêteEnvoi de la requêteAttente du résultat….
Analyse du résultat reçu
Connexion au serveur Attente de requêtes
Analyse de la requête…..Exécution….Préparation de la réponseEnvoi de la réponse
Exemple : annuaire des surnoms
EssiFun SERVEUR de Surnoms
enregistrer(« paul »,
«bug »)
marshalling
marshalling
unmarshalling
unmarshalling
0111000101000..
101..
enregistrer(« paul »,
«bug ») = TRUE
TRUE
1:Paul:bug ou ENR/nPaul/n/bug/n ou Objet Requête Seriablizable
Différence entre un transport TCP et UDP pour le codage des données ?
L’héritage de la programmation par objets
Communication par envoi de messagesEncapsulation et InterfaceHéritage et Composition
Objets = briques logicielles
Assembler des briques élémentairesRéduire la complexité des systèmes
d’information
Séparation entre interface et implémentation
Représentation et types de données
Mécanismes d’abstraction
Séparation entre interface et implémentation
séparation de la définition et de l’implémentation : encapsulation
interface : partie visible de l’objetimplémentation : partie privée inaccessible
depuis d’autres objetsinterface = contrat entre l’objet et le monde
extérieur
Séparation entre interface et implémentation
Assemblage des objets dépend uniquement des interfaces, le changement local d’un objet ne perturbe pas l’ensemble de l’application.
Importance de la nomenclature des objetssubstitution logique liée à la substitution physique
Représentation et Types de données
Définition de nouveaux typesChoix d’un type pour une donnée (ex.
montant) devient une contrainte sur la conception.
Types de données Abstraits
considérés comme des types de base
Mécanismes d’abstraction
Abstraction des données : essence du procédé de construction de systèmes d ’information à base d ’objets distribués
par Héritage et/ou Composition
Des mises en œuvre différentes selon les cas
Que peut on automatiser ?
A partir du protocole d’applications
Au minimum, la phase de marshalling/unmarshalling(hétérogéneité des langages, des systèmes, etc)
Selon les cas, le squelette du serveur les appels distants du client
Interaction Client/server :socket TCP
Serveur Client
wait for incomingconnection requestconnectionSocket =welcomeSocket.accept()
create socket,port=x, forincoming request:welcomeSocket =
ServerSocket()
create socket,connect to hostid, port=xclientSocket =
Socket()
closeconnectionSocket
read reply fromclientSocket
closeclientSocket
send request usingclientSocketread request from
connectionSocket
write reply toconnectionSocket
TCP connection setup
Client/server socket interaction: UDP
closeclientSocket
Serveur
read reply fromclientSocket
create socket,clientSocket = DatagramSocket()
Create, address (hostid, port=x,send datagram request using clientSocket
create socket,port=x, forincoming request:serverSocket = DatagramSocket()
read request fromserverSocket
write reply toserverSocketspecifying clienthost address,port umber
Client
Exemple : annuaire des surnoms
boolean enregistrer(Personne p, Surnom sn)ListOfPersonne lister()boolean oter(Surnom surnom) listePersonnes
Enregistrer(AnneMarie,AM)lister()
Client
Serveur
Exemple : annuaire des surnoms
interface : partie visible de l’objet (enregistrer, oter, lister, …) = méthodes publiques Java
implémentation : partie privée inaccessible depuis d’autres objets (listePersonnes : un vecteur de Personne ou un tableau ou ….)
Interface distante = contrat entre l’objet et le monde extérieur (save impossible par exemple)
Circulation de messages et machines hétérogènes
Couche de services
Objets de l’application qui résultent de la conception du modèle
Couche de transport
Responsable de l’administration des objets et de l’acheminement des messages
Infrastructure informatique de distribution
CLIENT SERVEUR
Transport TCP IP...
Service (marshalling..)
transaction sécurité nommage
Infrastructure ?
Objets distribués
Un programme (objet) peut être à la fois client de certains serveurs et serveur d’autres clients
Il peut y avoir reconfiguration dynamique des rôles Client Serveur
Infrastructure Objets Distribués
Client Client Serveur Serveur
Objet1
Objet2 Objet3
Générateurs
RMIC / Orbix...
IDL Int. Java
Spécificationsdes données Protocole d’application
Générateurs
Fichiersgénérés
Stubs Skeletons Proxy (sérialisation et désérialisation…)
RMI
public interface Surnoms extends java.rmi.Remote{public Boolean enregistrer(String nom, String surnom) throws
java.rmi.RemoteException, ServeurSurnoms.surnoms.ExisteDeja ;
…. }
RMI
Classes et Interfaces
ClasseLocale
Souche Squelette
ClasseDistante
InterfaceDistante
Remote
Appel méthode m() Appel méthode m()
Machine locale Machine distante
InterfaceDistante
Comment activer des objets distribués ?
Messages échangés entre objets = Requêtes ou Résultats
Certains envois de messages n’attendent pas de résultats
Requête = Destinataire + nom de méthode + Paramètres
Résultat = Donnée ou indication d’une erreur ou d’une défaillance
Comment activer des objets distribués ?
Mécanisme d’exécution ou de transport définit comment les messages sont véhiculés de l’objet
client vers l’objet serveur (destinataire) retrouver et activer les objets adéquats
Un objet client a deux manières d’envoyer des messages invocation statique invocation dynamique
Invocation statique
Le nom de l’objet destinataire et le message sont connus au moment du développement
Ne permet ni l’ajout ni le retrait d’objets dans les serveurs
Invocation dynamique
Permet au programme client de découvrir les objets à l’exécution et les interfaces
proposés par ces objets construire dynamiquement messages et requêtes envoyer et recevoir le résultat de telles requêtes
Rend les systèmes réactifs et faciles à modifier
Invocation dynamique + surcharge
flexibilité du code
briques logicielles avec les mêmes messages pour des objets de différentes natures définir de nouveaux objets sans modifier l’interface changements qui n’affectent pas les clients
Invoquer les services dont il a besoin par envoi de requêtes
Accès à l’objet destinataire par une référence à son implémentation par l’interface
Rôle du client
Unités autonomes - solidité - robustesse - adaptation
ID
Rôle de l’infrastructure
administre les implémentations, la création et la destruction d’objets
réceptionne les requêtes, localise le serveur, vérifie son état et celui du destinataire
active au besoin le serveur, lui envoie les données de la requête
ramène les résultats au clientdoit être informée de l’arrêt d’un serveurdoit gérer la persistance
Rôle du serveur
Administrer un flot de requêtes pour un ou plusieurs objets dont il a la responsabilité
Ordonnancer la séquence des opérations de réponses à une requête
Rôle du serveur d’objets
active si besoin l’objet destinatairerecherche et exécute la méthodepasse le résultat à l’infrastructureplusieurs requêtes peuvent arriver
simultanémentarrêt du serveur : désactiver tous les objets
et enregistrer leur état
Enregistrer un objet
• Opération pour publier un Objet– en général, opération réalisée par le serveur
• Scénario Type1. Créer un objet2. Construire un chemin d ’accès (Name)3. Appeler l ’opération « bind » ou « rebind » avec le chemin et la référence de l ’objet
void bind (in Name n, in Object obj) raises (NotFound, CannotProceed, InvalidName, AlreadyBound);
Retrouver un objet
Opération réalisée par un client ou un serveurScénario type :
construire un chemin d ’accès (Name) appeler l ’opération « resolve » avec le chemin convertir la référence obtenue dans le bon type
Object resolve (in Name n)raises (NotFound, CannotProceed, InvalidName)
Invocation de Méthode à distance Exemple : Java
Remote Method Invocation
DÉPARTEMENT SIAM DERY
À travailler seuls
Concepts généraux
Mise en œuvre Java
Merci à Rémi Vankeisbelck, Michel Riveill etc
38
Client Serveur
39
Objets distribués
Comment trouver une solution ? Programmation OO = envoi de requêtes entre
plusieurs objets Ne peut-on pas placer des objets sur différents
ordinateurs de sorte qu’ils puissent s ’envoyer directement des messages ?
40
Objets distribués
Un programme (objet) peut être à la fois client de certains serveurs et serveur d’autres clients
Il peut y avoir reconfiguration dynamique des rôles Client Serveur
41
Invocation de méthodes distantes
Mécanisme qui permet à des objets localisés sur des machines distantes de s’échanger des messages (invoquer des méthodes)
42
Invocation de méthodes distantes
Semble simple en théorie...... un peu plus complexe en réalité !!!
43
RMI
Heureusement, on utilise Java ;-) Java Remote Method Invocation est la solution à notre
problème
RMI permet à des objets Java d ’invoquer des méthodes sur des objets localisés dans des JVM différentes, et même distantes sur le réseau, et ceci de façon quasi transparente !!!
44
RMI
Core API (intégré au JDK 1.1) Gratuit 100 % Java
Développé par JavaSoftRéservé aux objets JavaUtilise les sockets et le protocole JRMP
45
Invocation de méthodes distantes
46
Stubs et encodage des paramètres
le code d’un objet client invoque une méthode sur un objet distant Utilisation d’un objet substitut dans la JVM du client :
le stub (souche) de l ’objet serveur
47
Stubs et encodage des paramètres
48
Du côté du client
Appel d’une méthode du stub (de façon entièrement transparente)
le stub construit un bloc de données avec identificateur de l’objet distant à utiliser description de la méthode à appeler paramètres encodés qui doivent être passés
puis il envoie ce bloc de données au serveur...
49Du côté du serveur
un objet de réception (Squeleton) effectue les actions suivantes : décode les paramètres encodés situe l ’objet à appeler invoque la méthode spécifiée capture et encode la valeur de retour ou l ’exception
renvoyée par l ’appel
50
Encodage des paramètres
Encodage dans un bloc d ’octets afin d ’avoir une représentation indépendante de la machine
Types primitifs et «basiques» (int/Integer...) Encodés en respectant des règles établies Big Endian pour les entiers...
Objets ...
51
Générateur de stubs
Les stubs gèrent la communication ainsi que l'encodage des paramètres
Processus évidemment complexe...Entièrement automatique
Un outil permet de générer les stubs pour les OD
52
Stubs et rmic
La commande rmic du jdk rend transparent la gestion du réseau pour le programmeur une référence sur un ODréférence son stub local
syntaxe = un appel local objetDistant.methode()
53
Un exemple : le sempiternel « Hello World » !!!
54
Interfaces et classes prédéfinies
55
L ’interface HelloWorldimport java.rmi.*;
interface HelloWorld extends Remote {public String sayHello()
throws RemoteException;}
Interface = protocole d ’application
56
Rôle de l ’interface
HelloWorldHelloWorld
57
L ’exception RemoteException doit être déclarée par toutes les méthodes distantes Appels de méthodes distants moins fiables que les
appels locaux Serveur ou connexion peut être indisponible Panne de réseau ...
Les exceptions
58
HelloWorld hello = ...;// Nous verrons par la suite comment obtenir // une première référence sur un stub
String result = hello.sayHello();System.out.println(result);
Du côté client
59
Implémentation de la classe qui gère les méthodes de l ’interface HelloWorld// Classe d'implémentation du Serveur
public class HelloWorldImpl extends UnicastRemoteObjectimplements HelloWorld {
public String sayHello() throws RemoteException {
String result = « hello world !!! »; System.out.println(« Méthode sayHello invoquée... » +
result); return result;}
}
Du côté Serveur
60
doit implanter l ’interface HelloWorlddoit étendre la classe RemoteServer du
paquetage java.rmiRemoteServer est une classe abstraiteUnicastRemoteObject est une classe concrète
qui gére la communication et les stubs
Classe d ’implémentation
61
Classe d ’implémentation
HelloWorldHelloWorld
HelloWorldImpl
62
outil livré avec le JDK permet de générer les stubs
> rmic -v1.2 HelloWorldImpl génère un fichier HelloWorldImpl_stub.class
rmic doit être passé pour toutes les classes d'implémentation des OD afin d'en générer les stubs
L ’outil RMIC
63
On sait implanter un serveur d ’un côté, et appeler ses méthodes de l ’autre
MAIS
Comment obtient-on une référence vers un stub de notre objet serveur ???
Référence sur un objet
64
On pourrait appeler une méthode sur un autre objet serveur qui renvoie une référence sur le stub...
Mais quoi qu ’il en soit, le premier objet doit lui aussi être localisé (La poule et l ’œuf) !!!
On a alors recours a un Service de Nommage
Localisation des objets de serveur
65
Obtention d'une première référence sur un objet distant : « bootstrap » à l’aide d’un Service de Nommage ou Annuaire
Enregistrement des références d'objets dans l'annuaire afin que des programmes distants puissent les récupérer
Les Services de Nommage
66
Implémentation d'un service de nommage Fourni en standard avec RMI
Permet d'enregistrer des références sur des objets de serveur afin que des clients les récupèrent
On associe la référence de l'objet à une clé unique (chaîne de caractères)
Le client effectue une recherche par la clé, et le service de nommage lui renvoie la référence distante (le stub) de l'objet enregistré pour cette clé
Exemple : Le RMIRegistry
67
Programme exécutable fourni pour toutes les plates formes
S'exécute sur un port (1099 par défaut) sur la machine serveur
Pour des raisons de sécurité, seuls les objets résidant sur la même machine sont autorisés à lier/délier des références
Un service de nommage est lui-même localisé à l'aide d'une URL
Le RMIRegistry
68
du package java.rmi permet de manipuler le RMIRegistry supporte des méthodes statiques permettant de
Lier des références d'objets serveur Naming.bind(...) et Naming.rebind(...)
Délier des références d'objets serveur Naming.unbind(...)
Lister le contenu du Naming Naming.list(...)
Obtenir une référence vers un objet distant Naming.lookup(...)
La classe Naming
69
L ’objet serveur HelloWorld (coté serveur bien entendu…) On a créé l'objet serveur et on a une variable
qui le référenceHelloWorld hello = new HelloWorldImpl();
On va enregistrer l'objet dans le RMIRegistryNaming.rebind("HelloWorld",hello);
L'objet est désormais accessible par les clients
Enregistrement d ’une référence
70
sur l'objet serveur HelloWorld On déclare une variable de type HelloWorld et
on effectue une recherche dans l'annuaire
HelloWorld hello = (HelloWorld)Naming.lookup("rmi://www.helloworldserver.com/HelloWorld");
On indique quelle est l'adresse de la machine sur laquelle s'exécute le RMIRegistry ainsi que la clé
La valeur retournée doit être transtypée (castée) vers son type réel
Obtention d'une référence coté client
71
Le Service de Nommage n'a pas pour fonction le référencement de tous les objets de serveur Il devient vite complexe de gérer l'unicité des clés
La règle de bonne utilisation du Naming est de lier des objets qui font office de point d'entrée, et qui permettent de manipuler les autres objets serveurs
Remarque
72
Rappel On veut invoquer la méthode sayHello() d'un
objet de serveur distant de type HelloWorld depuis un programme Java client
Nous allons devoir coder L'objet distant Le serveur Le client Et définir les permissions de sécurité et autres
emplacements de classes...
Conception, implémentation et exécution de l'exemple
73
1) définir une interface Java pour un OD 2) créer et compiler une classe implémentant cette
interface 3) créer et compiler une application serveur RMI 4) créer les classes Stub (rmic) 5) démarrer rmiregistry et lancer l’application
serveur RMI 6) créer, compiler et lancer un programme client
accédant à des OD du serveur
Processus de développement
74
Une interface et une classe d'implémentation stubs générés automatiquement par rmic toutes les classes nécessaires à l ’ objet de
client doivent être déployées sur la machine cliente et accessibles au chargeur de classes (dans le CLASSPATH)
L'interface HelloWorld (HelloWorld.class) Le stub HelloWorldImpl_stub généré par rmic pour cet objet
Hello World : L'objet distant
75
instancie un objet de type HelloWorld et attache au service de nommage
puis objet mis en attente des invocations jusqu'à ce que le serveur soit arrêté
import java.rmi.*;import java.rmi.server.*;
public class HelloWorldServer {
public static void main(String[] args) {try {
System.out.println("Création de l'objet serveur...");HelloWorld hello = new HelloWorldImpl();System.out.println("Référencement dans le
RMIRegistry...");Naming.rebind("HelloWorld",hello);System.out.println("Attente d'invocations - CTRL-C pour
stopper");} catch(Exception e) {
e.printStackTrace();}
}}
Hello World : Le serveur
76
Apres avoir compilé le tout... Pour démarrer le serveur, il faut tout d'abord lancer le
RMIRegistry Attention : La base de registres RMI doit connaître les
interfaces et les stubs des objets qu'elle enregistre (CLASSPATH) !!!
> rmiregistry &
et ensuite on lance le serveur
> java HelloWorldServer
Création de l'objet serveur...Référencement dans le RMIRegistry...Attente d'invocations - CTRL-C pour stopper
Serveur (suite)
77
obtenir une référence sur l'objet de serveur HelloWorld, invoquer la méthode sayHello(), puis afficher le résultat de l'invocation sur la sortie standardimport java.rmi.*;
public class HelloWorldClient {
public static void main(String[] args) {try {
System.out.println("Recherche de l'objet serveur...");HelloWorld hello = (HelloWorld)Naming.lookup("rmi://server/HelloWorld");System.out.println("Invocation de la méthode sayHello...");String result = hello.sayHello();System.out.println("Affichage du résultat :");System.out.println(result);System.exit(0);
} catch(Exception e) {e.printStackTrace();
}}
}
Hello World : client
78
Il suffit ensuite de lancer le programme
> java HelloWorldClient
Recherche de l'objet serveur...Invocation de la méthode sayHello...Affichage du résultat :hello world !!!
Au niveau du serveur, le message... Méthode sayHello invoquée... hello world !!! ...s'affichera dans la console
Le client (suite)
79
Que doit connaître le client ?
Lorsqu ’un objet serveur est passé à un programme, soit comme paramètre soit comme valeur de retour, ce programme doit être capable de travailler avec le stub associé
Le programme client doit connaître la classe du stub
80
Que doit connaître le client ?
les classes des paramètres, des valeurs de retour et des exceptions doivent aussi être connues... Une méthode distante est déclarée avec un type de
valeur de retour... ...mais il se peut que l ’objet réellement renvoyé soit
une sous-classe du type déclaré
81
Que doit connaître le client ?
Le client doit disposer des classes de stub, classes des objets retournés…
copier les classes sur le système de fichiers local du client (CLASSPATH)...
...cependant, si le serveur est mis à jour et que de nouvelles classes apparaissent, il devient vite pénible de mettre à jour le client
C ’est pourquoi les clients RMI peuvent charger automatiquement des classes de stub depuis un autre emplacement Il s ’agit du même type de mécanisme pour les
applets qui fonctionnent dans un navigateur
82
Chargement dynamique des classes
Problème de sécurité Le programme client télécharge du code sur le réseau Ce code pourrait contenir des virus ou effectuer des
opérations non attendues !!! Utilisation d ’un gestionnaire de sécurité pour les
applications de clients RMI Possibilité de créer des gestionnaires de sécurité
personnalisés pour des applications spécifiques RMI fournit des gestionnaires de sécurité suffisants
pour un usage classique
83
Pour ne plus déployer les classes du serveur chez le client
Utilisation des chargeurs de classes qui téléchargent des classes depuis une URL
Utilisation d ’un serveur Web qui fournit les classes
Ce que ça change Bien entendu, les classes et interfaces de l ’ objet distant ne
changent pas Le code du serveur ne change pas
le client et la façon de le démarrer sont modifiés Et lancer un serveur Web pour nos classes
Chargement dynamique
84
Séparation des classes Serveur (fichiers nécessaires a l'exécution du
serveur) HelloWorldServer.class HelloWorldImpl.class HelloWorld.class HelloWorldImpl_Stub.class
Download (fichiers de classes à charger dans le programme client) HelloWorldImpl_Stub.class
Client (fichiers nécessaires au démarrage du client) HelloWorld.class HelloWorldClient.class
Hello World : chargement dynamique
85
Mettre les classes Download dans le répertoire des documents Web du serveur Web, accessibles via une URL
le chargeur de classes ira chercher les classes à un emplacement de type http://www.class-server.com/classes/HelloWorldImpl_Stub.class
};
Hello World : Démarrage du serveur Web
86
Le programme Java client doit pouvoir se connecter aux ports de la base de registres RMI et des implémentations des objets de serveur, ainsi qu'au port du serveur Web
Fichier client.policygrant {
permission java.net.SocketPermission"*:1024-65535", "connect,resolve";
permission java.net.SocketPermission"*:80", "connect";
};
Hello World : Politiques de sécurité
87
Le client intègre un gestionnaire de sécurité RMI pour les stubs téléchargés dynamiquementimport java.rmi.*;import java.rmi.server.*;
public class HelloWorldClient {
public static void main(String[] args) {try {
// Installe un gestionnaire de sécurité RMISystem.setSecurityManager(new RMISecurityManager());System.out.println("Recherche de l'objet serveur...");HelloWorld hello = (HelloWorld)Naming.lookup("rmi://server/HelloWorld");System.out.println("Invocation de la méthode sayHello...");String result = hello.sayHello();System.out.println("Affichage du résultat :");System.out.println(result);
} catch(Exception e) {e.printStackTrace();
}}
}
Hello World : gestionnaire de sécurité RMI
88
1) Lancer la base de registres RMI (elle doit pouvoir accéder aux classes Download - CLASSPATH)> rmiregistry
2) Lancer le serveur Web servant les fichiers de classes Download
3) Lancer le serveur (les classes Server doivent être accessibles)> java HelloWorldServer
Création de l'objet serveur...Référencement dans le RMIRegistry...Attente d'invocations - CTRL-C pour stopper
Hello World : Démarrage coté serveur
89
Le client doit pouvoir se connecter à des machines distantes pour la base de registres RMI, les objets de serveur ainsi que le serveur Web On doit lui fournir un fichier client.policy
Le client doit bien connaître l'emplacement des classes afin de pouvoir les télécharger On va le lui préciser lors du lancement
> java -Djava.security.policy=client.policy -Djava.rmi.server.codebase=http://www.class-server.com:80/ HelloWorldClient
Hello World : Démarrage coté client
90
Passage de paramètres
On sera souvent amenés a passer des paramètres aux méthodes distantes...
Les méthodes distantes peuvent retourner une valeur ou lever une exception...
On a deux types de paramètres Les objets locaux Les objets distants
91
Passage de paramètres: ATTENTION
Certains objets sont copiés (les objets locaux), d'autres non (les objets distants)
Les objets distants, non copiés, résident sur le serveur Les objets locaux passés en paramètre doivent être
sérialisables afin d'être copiés, et ils doivent être indépendants de la plate-forme
Les objets qui ne sont pas sérialisables lèveront des exceptions
Attention aux objets sérialisables qui utilisent des ressources locales !!!
92
On a vu ce qu'est une invocation de méthode distante
On a vu le mécanisme des stubs, ainsi que l'encodage des paramètres
On a vu le déploiement avec téléchargement des classes dynamiquement
Nous avons même appliqué ces concepts au travers de l'exemple "HelloWorld » en RMI
Conclusion
Erreurs classiques
Stub inaccessible au rmiregistry java.rmi.ServerException: RemoteException
occurred in server ...java.rmi.UnmarshalException: errorunmarshalling ...java.lang.ClassNotFoundException:
Le stub est accessible au serveur MAIS PAS AU rmiregistryAttention à l’ordre d’appel : génération des stubs et appel du rmiregistry
rmiregistry pas lancé java.net.ConnectException
Oubli du constructeur pour le RemoteObject unreported exception java.rmi.RemoteException in default constructorpublic class HelloImpl extends UnicastRemoteObject implements Hello { ^
rmiregistry déjà lancéjava.rmi.server.ExportException: Port already in use: 1099On peut lancer un autre registry mais sur un autre port.
Erreurs classiques
La classe d’implémentation n'hérite pas de UnicastRemoteObject
S'il n'hérite pas de UnicastRemoteObject, il n'est pas Remote donc on ludemande d'être Serializable ...Trouble: java.rmi.MarshalException: error marshalling arguments; nested exception is: java.io.NotSerializableException: CalculatorImpl
ATTENTION aux CLASSPATH et package Java
Une autre utilisation du rmiRegistry
import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry;Client Registry registry; registry = LocateRegistry.getRegistry(); Hello hello = (Hello) registry.lookup("coucou"); Serveur LocateRegistry.createRegistry(port); // port=1099
Hello stub = (Hello) UnicastRemoteObject.exportObject(unHello, 0);Naming.rebind("rmi://"+"localhost"+":"+ port +"/coucou", stub);
95