2. Rappel des conclusions sur l’appel de procédure à
distance
2
Avantages
Abstraction (les détails de la communication sont cachés)
Intégration dans un langage : facilite la portabilité, mise au point
Outils de génération: facilitent la mise en œuvre
Limitations
La structure de l’application est statique
Pas de création dynamique de serveur
Pas de possibilité de redéploiement entre sites
Pas de passage des paramètres par référence
La communication est réduite à un schéma synchrone
La persistance des données n’est pas assurée
Il faut la réaliser explicitement par sauvegarde des données dans des fichiers
Des mécanismes plus évolués visent à remédier à ces limitations
Objets répartis (ex : Java RMI, CORBA) pour les 2 premières limitations
Bus à messages (Message Oriented Middleware)
Composants répartis (ex : EJB, Corba CCM, .Net)
3. Intérêt des objets pour la construction d’applications
réparties
3
Encapsulation
L’interface (méthodes + arguments) est la seule voie
d’accès à l’état interne, non directement accessible
Classes et instances
Mécanismes de génération d’exemplaires conformes
à un même modèle
Héritage
Mécanisme de spécialisation : facilite la récupération
et réutilisation de l’existant
Polymorphisme
Mises en œuvre diverses des fonctions d’une
interface
Facilite l’évolution et l’adaptation des applications
4. Extension du RPC aux objets (1)
4
Appel de procédure vs appel de méthode sur un objet
Exemple : insérer une entrée dans un annuaire
5. Extension du RPC aux objets (2)
5
Phase préalable : création d’instances d’une classe
d’objets
Notion de fabrique (factory)
Notion de référence d’objet :
Contient tout ce qui est nécessaire pour atteindre l’objet
distant
(Localisation, protocole d’accès)
6. Notion de référence
6
Référence : notion clé pour les objets répartis
Moyen d’accès à un objet distant,
Son contenu ne peut pas être directement exploité « opaque »,
elle n’est utilisable que via un mécanisme d’appel à distance
Contenu d’une référence
Toutes les informations nécessaires pour atteindre physiquement l’objet
Site de résidence (adresse IP)
Numéro de porte sur le site (Numéro de port)
Localisation interne au serveur
…
Exemples
En Java RMI : la référence est le talon client (stub)
En Corba : format de référence spécifié (IOR : Interoperable Object
Reference)
En DCOM : format “propriétaire”
7. Java RMI (Remote Method Invocation)
7
Motivation : construction d’applications réparties avec Java
Appel de méthode au lieu d’appel de procédure
Principe : même schéma que RPC
Le programmeur fournit
Une (ou plusieurs) description(s) d’interface
Ici pas d’IDL séparé : IDL=JAVA
Le programme du serveur
Objets implémentant les interfaces
Serveur d’objets
Le programme du client
L’environnement Java fournit
Un générateur de talons : rmic
Un service de noms : rmiregistry
voir http://docs.oracle.com/javase/tutorial/rmi/
8. Java RMI : règles d’usage (1/2)
8
Interface
L’interface d’un objet distant (Remote) est celle d’un
objet Java, avec quelques règles d’usage :
L’interface distante doit être publique
L’interface distante doit étendre l’interface
java.rmi.Remote
Chaque méthode doit déclarer au moins l’exception
java.rmi.RemoteException
Passage d’objets en paramètre
Les objets locaux sont passés par valeur (copie) et
doivent être sérialisables (étendent l’interface
java.io.Serializable)
Les objets distants sont passés par référence et
sont désignés par leur interface
9. Java RMI : règles d’usage (2/2)
9
Implémentation des classes distantes
(Remote)
Une classe distante doit implémenter une
interface elle-même distante (Remote)
Une classe distante doit étendre la classe
java.rmi.server.UnicastRemoteObject (d’autres
possibilités existent)
Une classe distante peut aussi avoir des
méthodes appelables seulement localement (ne
font pas partie de son interface Remote)
10. Java RMI : règles d’écriture du
serveur10
Un serveur est une classe qui implémente
l’interface de l’objet distant
Spécifier les objets distants qui doivent être
implémentées
Définir le constructeur de l’objet distant
Fournir l’implémentation des méthodes appelables à
distance
Créer et installer le gestionnaire de sécurité
Créer au moins une instance de la classe serveur
Enregistrer au moins une instance dans le serveur de
noms
11. Le compilateur IDL : rmic
11
Le compilateur rmic génère les amorces
(stub/skeleton)
assurent le rôle d’adaptateurs pour le transport des
appels distants.
réalisent les appels sur la couche réseau.
réalisent l’emballage/déballage des paramètres
(sérialisation ou marshalling/unmarshalling).
Une référence d’objets distant correspond à une
référence d’amorce (stub).
12. Stub/Skeleton
12
Stub (talon client)
Représentant local de l’objet distant.
Initie une connexion avec la JVM distante
Assemble les paramètres pour leur transfert à la JVM
distante.
Attend les résultats de l’invocation distante.
Désassemble la valeur ou l’exception renvoyée.
Renvoie la valeur au client (l’appelant).
Skeleton (talon serveur)
Désassemble les paramètres pour la méthode distante.
Fait appel à la méthode demandée.
Assemble le résultat (valeur renvoyée ou exception) à
destination de l’appelant.
13. Serveur de noms : rmiregistry
13
Permet d’obtenir une référence d’objet distant
S’exécute sur chaque machine hébergeant des objets
distants
Utilise par défaut le port 1099
Accepte comme opérations l'enregistrement,
l'effacement et la consultation (méthodes de la classe
java.rmi.Naming)
void Naming.bind(String nom, Remote obj) : associe l'objet au
nom spécifié;
void Naming.rebind(String nom, Remote obj) : réassocie le nom
au nouvel objet;
void Naming.unbind(String nom) : supprime l'enregistrement
correspondant;
Remote Naming.lookup(String nom) : renvoie la référence (stub)
de l'objet enregistré sous le nom donné;
15. Développer une application avec
RMI16
1. Définir une interface distante (AppInterface.java).
2. Créer une classe implémentant cette interface
(AppImpl.java).
3. Compiler cette classe (javac AppImpl.java).
4. Créer une application serveur (AppServer.java).
5. Compiler l’application serveur.
6. Créer les classes stub et skeleton à l’aide de rmic:
AppImpl_Stub.java et AppImpl_Skel.java
7. Démarrage du serveur de noms (registre) avec rmiregistry.
8. Lancer le serveur AppServer pour la création d’objets et leur
enregistrement dans rmiregistry.
9. Créer une classe cliente qui appelle des méthodes distantes
de l’objet distant (AppClient.java).
10. Compiler cette classe et la lancer.
16. Exemple : Inversion d’une chaîne de
caractères
17
Invocation distante de la méthode reverseString() d’un
objet distant qui inverse une chaîne de caractères
fournie par l’appelant.
Classes nécessaires:
ReverseInterface : interface qui décrit l’objet distant
Reverse : qui implémente l’objet distant
ReverseServer : le serveur d’objets RMI
ReverseClient : le client qui utilise l’objet distant
17. Interface
18
Interface de l’objet
Permet de décrire les différentes méthodes de l'objet
distant
Partagée par le client et le serveur.
Doit étendre l’interface Remote définie dans java.rmi.
Toutes ses méthodes doivent déclarer l’exception
RemoteException.
RemoteException est déclenchée si :
connexion refusée à l’hôte distant
l’objet n’existe plus,
un problème d’assemblage ou de désassemblage.
19. Implémentation de l’objet distant
20
Une classe qui implémente l'interface définie
Permettre de rendre un objet accessible à distance par
des clients.
Doit permettre l’exposition de l'objet distant:
La solution (la plus simple) consiste à étendre la classe
UnicastRemoteObject de java.rmi.server.
20. Implémentation de l’objet distant
21
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();
}
}
21. Serveur d’objets
22
Les opérations réalisées par le serveur:
1. Définir un gestionnaire de sécurité (classe
RMISecurityManager) si le serveur est amené à charger des
classes (Inutile si pas de chargement dynamique de
classes)
System.setSecurityManager (new RMISecurityManager());
2. Créer les objets distants par instanciation de
classes Remote:
MonObjetDistant Objet = new MonObjetDistant;
22. Serveur d’objets
23
3. Exposer les objets distants : rendre accessibles
dans le serveur
Si la classe de l'objet a été définie comme une extension de
UnicastRemoteObject, l’exposition est automatique.
Sinon, l'objet doit être exposé explicitement par appel de la
méthode exportObject de la classe UnicastRemoteObject:
UnicastRemoteObject.exportObject(unObjet);
4. Faire connaitre l'existence des différents objets au
serveur de noms (rmiregistry) de la machine sur
laquelle ce serveur s'exécutera
Naming.rebind("nomUnObjet", unObjet);
23. Serveur d’objets
24
import java.rmi.*;
public class ReverseServer {
public static void main(String[] args) {
System.setSecurityManager(new RMISecurityManager());
try { System.out.println( "Serveur : Construction de
l’implémentation ");
Reverse rev= new Reverse();
System.out.println("Objet Reverse lié dans le RMIregistry");
Naming.rebind("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()) }
}}
24. Le client (1/3)
25
Le client récupère le stub de l'objet : il s'adresse
au serveur de noms auprès duquel l'objet a été
enregistré.
Cette opération est réalisée en invoquant la
méthode lookup de la classe Naming.
Pour cela, il doit nommer complètement l'objet
concerné au travers d'une URL de la forme
générale suivante :
rmi://machine:port/nom
Dans une telle URL,
si le nom de machine est omis, la machine locale est
considérée;
si le numéro de port est omis, le numéro par défaut (1099)
25. Le client (2/3)
26
La méthode lookup est susceptible de provoquer une
exception RemoteException :
try {
MonInterface stub= (MonInterface) Naming.lookup
(adresse_de_l'objet);
}
catch (Exception e){-------- }
Une fois le stub est récupéré, un client peut invoquer sur ce
stub des méthodes de l'interface comme il ferait sur un objet
local:
objet=stub.méthode(paramètres);
26. Le client (3/3)
27
import java.rmi.*;
public class ReverseClient {
public static void main (String [] args) {
System.setSecurityManager(new RMISecurityManager());
try{
ReverseInterface rev = (ReverseInterface) Naming.lookup
("rmi://localhost: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’accès à l’objet distant.");
System.out.println (e.toString());
}}}
27. Fabrique d’objets (Factory)
28
Fabrique : Permettre au client de construire des
instances multiples d’une classe sur le site serveur
Problème : Le new n’est pas utilisable tel quel (car il ne
gère que la mémoire locale, celle du client)
Solution : appel d’un objet FabriqueC, qui crée
localement (sur le serveur) les instances de C (en
utilisant new C)
29. Exemple
public interface Annuaire extends Remote{
public boolean inserer(String nom, int id) throws
RemoteException;
public boolean supprimer(String nom, int id) throws
RemoteException;
public Info rechercher(String nom) throws RemoteException; }
public interface FabAnnuaire extends Remote{
public Annuaire newAnnuaire(String titre) throws
RemoteException ;}
Interface de l’objet distant
Interface de fabrique d’objets
public class AnnuaireImpl implements Annuaire extends
UnicastRemoteObject{
private String titre;
public Annuaire(String titre) {this.titre=titre};
public boolean inserer(String nom, Info info) throws
RemoteException{…};
public boolean supprimer(String nom) throws RemoteException{…};
public Info rechercher(String nom) throws RemoteException{…}; }
Implémentation de l’objet distant
public class FabAnnuaireImpl implements FabAnnuaire extends
UnicastRemoteObject{
public FabAnnuaireImpl{};
public Annuaire newAnnuaire(String titre) throws RemoteException {
return new AnnuaireImpl(titre)};
Implémentation de la fabrique d’objets
30. Serveur d’objets
import java.rmi.*;
public class HelloClient {
public static void main (String [ ] argv) {
try {
/* trouver une référence vers la fabrique */
FabAbannuaire fabrique = (FabAbannuaire ) Naming.lookup
("rmi://goedel.imag.fr/Fabrique") ;
annuaireIMAG = fabrique.newAnnuaire("IMAG"); /* créer un annuaire */
annuaireINRIA= fabrique.newAnnuaire("INRIA"); /* créer un autre annuaire */
/* utiliser les annuaires */
annuaireIMAG.inserer(…, …);
annuaireINRIA.inserer(…, …);
} catch (Exception e) { System.out.println("Erreur client : " + e) ;
Client
import java.rmi.*;
public class Server {
public static void main (String [ ] argv) {
try {
Naming.rebind ("Fabrique”,new (FabAnnuaireImpl))
;
System.out.println ("Serveur prêt.") ;
}
catch (Exception e) { System.out.println("Erreur serveur : " +
e) ;}
}}
Exempl
e
31. Passage d’objets en paramètres
32
Deux cas possibles
Passage en paramètre d’un objet local (sur la JVM de l’objet
appelant)
Passage par valeur : on transmet une copie de l’objet (plus
précisément : une copie de l’ensemble ses variables d’état)
Pour cela l’objet doit être sérialisable (i.e. implémenter
l’interface java.io.Serializable)
Exemple de l’annuaire : le client transmet un objet de la classe
locale Info
Passage en paramètre d’un objet non-local (hors de la JVM
de l’objet appelant, par ex. sur un site distant)
Passage par référence : on transmet une référence sur l’objet
(plus précisément : un stub de l’objet). Le destinataire utilisera ce
stub pour appeler les méthodes de l’objet.
Exemple de l’annuaire : le client passe un objet de type Annuaire
(localisé sur le serveur distant)
33. Passage d’objets en
paramètres34
Notions sur les objets sérialisables
Un objet sérialisable (transmissible par valeur hors de
sa JVM) doit implémenter java.io.Serializable
Les objets référencés dans un objet sérialisable
doivent aussi être sérialisables
Comment rendre effectivement un objet sérialisable ?
Pour les variables de types primitifs (int, boolean,..) rien à
faire
Pour les objet dont les champs sont constitués de telles
variables : rien à faire
On peut éliminer une variable de la représentation
sérialisée en la déclarant transient
Pour un champ non immédiatement sérialisable (ex. :
Array), il faut fournir des méthodes readObject() et
writeObject()
Voir javadoc de l’interface Serializable et des classes
ObjectOutputStream et ObjectInputStream
34. Fonctionnement interne de JavaRMI
35
La classe UnicastRemoteObject
Rappel de la règle d’usage: une classe d’objets accessibles à
distance étend la classe java.rmi.UnicastRemoteObject
La principale fonction de cette clase se manifeste lors de la création d’une
instance de l’objet
public class AnnuaireImpl extends UnicastRemoteObject {…}
AnnuaireImpl (…) { /* le constructeur d’AnnuaireImpl appelle
automatiquement
le constructeur de la superclasse
UnicastRemoteObject*/
…
monAnnuaire = new AnnuaireImpl (…) ; Le constructeur de UnicastRemoteObject crée une instance de stub pour l’objet, en
utilisant la classe Annuaire_Stub engendrée par rmic, et retourne ce stub comme
résultat de la création.
Le contenu d’un stub
Un stub contient essentiellement une variable ref de type RemoteRef qui
contient la localisation de l’objet (adresse IP, port)
Un appel de méthode se fait par appel de ref.invoke() qui utilise les sockets
35. Fonctionnement interne de javaRMI
36
Le serveur de noms (registry)
Classes utiles (fournies par java.rmi)
Naming : sert de représentant local du serveurs de noms
Permet d’utiliser les méthodes bind(), rebind(), lookup(),
unbind(), list()
LocateRegistry: permet de localiser un serveur de noms
(getRegistry()) et éventuellement d’en créer
un(createRegistry()), appelé en interne par Naming
36. Appel en retour (callback)
37
Le problème
Réaliser un appel du serveur vers le client
Intérêt
Augmenter l’asynchronisme
appel client-serveur avec retour immédiat (demande
service)
rappel serveur-client quand le service est exécuté
Augmenter le dynamisme
Le serveur peut demander des informations
complémentaires au client en cours d’exécution
L’exécution du service peut faire appel à des services
fournis par le client
Exemple : traitement d’exceptions
37. Appel en retour : principe
38
Le client passe en paramètre au serveur l’objet à
rappeler
Le serveur exécute un appel asynchrone sur cet objet
38. Appel en retour : réalisation
(interfaces des objets distants)
39
43. Gestionnaire de sécurité
44
Installer un gestionnaire de sécurité
Utile lorsqu’on télécharge du code à partir d’une
machine distante
Permet de protéger la machine virtuelle java de
tout utilisateur malintentionné qui essaye de faire
tourner du code malicieux sur la machine.
Utiliser le gestionnaire de sécurité fournit par
RMI: RMISecurityManager
System.setSecurityManager(new RMISecurityManager());
44. Gestionnaire de sécurité
45
La politique de sécurité spécifie les actions
autorisées, en particulier sur les sockets
Les opérations possibles sur les sockets:
connect est utilisé pour établir une connexion
avec un serveur.
listen est utilisé par un serveur pour indiquer qu'il
est disposé à accepter des connexions.
Après un listen, un serveur peut attendre une
demande de connexion d'un client par accept
45. Gestionnaire de sécurité
46
Exécuter le programme java utilisant un gestionnaire de
sécurité avec l’option :
java –Djava.security.policy=java.policy NomClasse
Où java.policy et le fichier des permissions
Exemple de contenu du fichier java.policy:
grant {
permission java.net.SocketPermission "localhost 1024-
65535","connect,accept";
permission java.net.SocketPermission ":80", "connect";
};
46. Chargement dynamique
47
Les définitions de classes sont hébergées sur un
serveur Web
Les paramètres, les stubs sont envoyés au client
via une connexion au serveur web
Pour fonctionner, une application doit télécharger
les fichiers de classe nécessaires
Chargement dynamique
Évite de disposer localement de toutes les définitions
de classe
les mêmes fichiers de classe (même version) sont
partagés par tous les clients
Charge une classe au besoin
47. Fichiers nécessaires si pas de chargement
dynamique
Interface :
ReverseInterface
Stub :
Reverse_Stub
Client :
ReverseClient
Interface :
ReverseInterface
Objet : Reverse
Stub :
Reverse_Stub
Serveur d’objets:
ReverseServer
48
Côté Client Côté Serveur
48. Fichiers nécessaires si chargement
dynamique
client :
ReverseClient
serveur d’objets:
ReverseServer
49
Côté Client Côté Serveur
Récupérer les fichiers de classe à partir de
serveur web
Interface : ReverseInterface
Stub : Reverse_Stub
L’objet : Reverse
49. Client dynamique
client : DynamicClient serveur d’objets:
ReverseServer
50
Côté Client Côté Serveur
Récupérer les fichiers de classe à partir de serveur
web
Interface : ReverseInterface
Stub : Reverse_Stub
L’objet : Reverse
Le client : ReverseClient
Le client peut lui même être dynamique
50. Client & Serveur dynamiques
Chargement dynamique du
client et de l’interface à partir
d’un répertoire local. Si non
disponibles localement, ils
sont recherchés sur le
serveur Web spécifié.
L’exécution de
ReverseClient permet
d’obtenir la référence de
l’objet Reverse et l’appel
distant de sa méthode
Chargement dynamique de
l’objet Reverse à partir du
serveur Web
Enregistrement de l’objet
dans RmiRegistry (bind)
Attente de requêtes des
clients
51
Client : DynamicClient
Serveur dynamique :
ReverseServer
Récupérer les fichiers de classe à partir de serveur web
Interface : ReverseInterface
Stub : Reverse_Stub
L’objet : Reverse
Le client : ReverseClient
51. Deux propriétés systèmes dans RMI
52
java.rmi.server.codebase
Spécifie l’URL (file://, ftp://, http://) où peuvent se
trouver les classes
Lorsque RMI sérialise l’objet (envoyé comme
paramètre ou reçu comme résultat), il rajoute
l’URL spécifié par codebase
java.rmi.server.useCodebaseOnly
informe le client que le chargement de classes
est fait uniquement à partir du répertoire du
codebase
52. Principe de chargement
dynamique53
À l’enregistrement (dans rmiregistry) de l’objet
distant, le codebase est spécifié par
java.rmi.server.codebase
À l’appel de bind(), le registre utilise ce codebase
pour trouver les fichiers de classe associés à
l’objet
Le client recherche la définition de classe du stub
dans son classpath. S’il ne trouve pas, il
essayera de la récupérer à partir du codebase.
Une fois que toutes les définitions de classe sont
disponibles, la méthode du stub appelle les objets
sur le serveur
53. Sécurité lors d’un chargement
dynamique
54
Les classes java.rmi.RMISecrurityManager et
java.rmi.server.RMIClassLoader vérifient le
contexte de sécurité avant de charger les classes
à partir d’emplacements distants
La méthode LoadClass de RMIClassLoader
charge la classe à partir du codebase spécifié
54. Etapes d’un chargement
dynamique55
Ecrire les classes correspondant respectivement à l’interface et à
l’objet
Les compiler
Générer le stub correspondant à l’objet
Installer tous les fichiers de classe sur un serveur web
Ecrire le serveur dynamique
Lancer rmiregistry au niveau de la machine du serveur
Lancer le serveur en lui précisant l’URL des fichiers de classe afin
qu’il puisse charger dynamiquement le fichier de classe
correspondant à l’objet, l’instancier et l’enregistrer dans rmiregistry
Sur la machine du client, écrire le code du client
Compiler le client statique et l’installer éventuellement sur le
serveur web
Compiler le client dynamique et le lancer en précisant l’URL des
fichiers de classe.
60. Exécution
61
mulder> ls
Reverse.java ReverseInterface.java DynamicServer.java
mulder> javac *.java
mulder> rmic -v1.2 Reverse
mulder> mv Reverse*.class /home/duvallet/public_html/rmi
Le répertoire destination des fichiers de classe doit être accessible par http.
mulder> ls *.class
DynamicServer.class
mulder>rmiregistry –J –D java.security.policy=client1.policy &
mulder>java -Djava.security.policy=client1.policy -
Djava.rmi.server.codebase= http://localhost/~duvallet/rmi
DynamicServer
Objet lié Attente des invocations des clients ... ---------------------------------
61. Exécution
62
scott>ls *.java
ReverseClient.java DynamicClient.java
scott>javac *.java
scott> java –D java.security.policy=client1.policy
-D java.rmi.server.codebase=http://localhost/~duvallet/rmi
DynamicClient
L’inverse de Alice est ecilA
Le chargement de ReverseClient se fera à partir du répertoire
local alors que ReverseInterface et Reverse_Stub seront chargés
à partir du serveur Web spécifié dans la commande.
62. Conclusion
63
Extension du RPC aux objets
Permet l’accès à des objets distants
Pas de langage séparé de description d’interfaces
(IDL fourni par Java)
Limitations
Environnement restreint à un langage unique (Java)
Mais passerelles possibles, en particulier RMI/IIOP
Services réduits au minimum
Service élémentaire de noms (sans attributs)
Pas de services additionnels
Duplication d’objets
Transactions
63. Ce qui reste à voir
64
Parallélisme sur le serveur
Un serveur RMI peut servir plusieurs clients.
Dans ce cas, un thread séparé est créé pour
chaque client sur le serveur. C’est au
développeur du programme serveur d’assurer
leur bonne synchronisation (exemple : méthodes
synchronized) pour garantir la cohérence des
données
Activation automatique de serveurs
Un veilleur (demon) spécialisé, rmid, peut assurer
le lancement de plusieurs classes serveur sur un
site distant (cette opération est invisible au client)
Editor's Notes
L’interface (méthodes + attributs) est la seule voie d’accès à l’état interne, non directement accessible
Poymorphysme : Remplacement d’un objet par un autre si interfaces “compatibles”
J’ai modifié : serveur serveur d’objets
Spécifier les références distantes qui doivent être implémentées (objets passés en paramètres)
Initie une connexion avec la JVM distante en transmettant l’invocation distante à la couche des références d’objets.
Permet d’obtenir une référence d’objet distant à partir de la référence locale au stub.
possède une table de hachage dont les clés sont des noms et les valeurs sont des objets distants).
Un unique rmiregister par machine virtuelle JVM
À déplacer :
Le protocole JRMP a été modifié afin de supprimer la nécessité des squelettes car depuis la version 1.2 de Java, une même classe skeleton générique est partagée par tous les objets distants.
exposer les objets, c'est-à-dire les rendre accessibles dans le serveur: cette opération a comme effet de créer et de lancer le serveur de l'objet exposé sous la forme d'une thread. Si la classe de l'objet a été définie comme une extension de UnicastRemoteObject, cette exposition est automatique. Par contre, si ce n'est pas le cas, l'objet doit être exposé explicitement par appel de la méthode statique exportObject de la classe UnicastRemoteObject
Une interface est constituée d'un ensemble de déclarations de méthodes sans implantation.
On n'y trouve uniquement, pour chaque méthode, que la définition de son profil, c'est-à-dire son en-tête suivi de ; .
Les interfaces sont définies par le mot clé interface. Si les interfaces permettent de déclarer des variables de référence portant leur type, elles ne sont pas, par contre, instanciables. En particulier une interface ne possède pas de constructeur. Une classe peut implanter une ou plusieurs interface(s) : la définition de la classe comporte alors le mot clé implements suivi d'une liste de noms d'interfaces (les noms des interfaces implantées y sont séparés par une virgule).
Classe abstraite possède une méthode Inversion d’une chaîne de caractères en appelant un objet distant
de abstraire (sans implémentation)
Spécifier l'interface de l'objet
Classe StringBuffer
Il s'agit de créer des objets buffer ou zone de travail qui contiennent des caractères. On réserve un buffer simplement en indiquant la taille ou la valeur initiale, comme :str=StringBuffer (128) ;str=StringBuffer ("Bonjour ") ;
La différence avec un objet String est que la taille d'un StringBuffer est variable. Une telle chaine peut être modifiée et ainsi être utilisée lors d'une construction dynamique.
Afin de permettre l'appel des méthodes de l'interface, celle-ci doit hériter de l'interface java.rmi.Remote qui ne contient aucune méthode propre, mais a comme objectif de permettre la désignation des objets distants. Ainsi un objet distant va se présenter comme un une instance d'une classe implantant l'interface java.rmi.Remote (ou de toute interface basée sur cette interface):
Implanter l'interface du côté serveur
Si la classe de l'objet a été définie comme une extension de UnicastRemoteObject, cette exposition est automatique. Par contre, si ce n'est pas le cas, l'objet doit être exposé explicitement par appel de la méthode statique exportObject de la classe UnicastRemoteObject
Super() sert à appeler un constructeur de la classe mère d'une classe.
Définir un gestionnaire de sécurité : Objet de la classe RMISecurityManager qui autorisera le chargement depuis une autre application de classes sérialisables:
c'est-à-dire les rendre accessibles dans le serveur: cette opération a comme effet de créer et de lancer le serveur de l'objet exposé sous la forme d'une thread.
le stub de l'objet (objet de la classe Remote)
Comme lors de l'enregistrement d'un objet par un serveur, la méthode lookup est susceptible de provoquer une exception (RemoteException). Il est donc nécessaire d'en prévoir l'occurrence.
Installe un gestionnaire de sécurité pour contrôler les stubs chargés dynamiquement
public String titre;
public String liretitre {return titre};
Un objet sérialisable (transmissible par valeur hors de sa JVM) doit implémenter java.io.Serializable. Celle-ci est réduite à un marqueur (pas de variables ni d’interface)
Exemples de sérialisation : passage en paramètres, écriture sur un fichier.
Le support de sérialisation est un stream (flot) : classes
java.io.ObjectOutputStream et java.io.ObjectInputStream.
Pour des détails techniques : voir javadoc de l’interface Serializable et des classes
ObjectOutputStream et ObjectInputStream
LocateRegistry: permet de localiser un serveur de noms (rmiregistry) et éventuellement d’en créer un. En général invisible au client (appelé en interne par Naming)
Une fois que toutes les définitions de classe sont disponibles, la méthode proxy du stub appelle les objets sur le serveur
scott> Le chargement de ReverseClient se fera à partir du répertoire local alors que ReverseInterface et Reverse_Stub seront chargés à partir du serveur Web spécifié dans la commande.