TP Miage3 2005-2006
Mise en place d'une applicationpartie en Java : Java RMI
1. Java RMI
L'environnement Java fournit un mécanisme d'appel à distance : RMI pour Remote
Method Invocation. Ce mécanisme peut être utilisé pour la mise en place d'applications
réparties selon le modèle client-serveur.
En Java, on peut définir des objets distants qui se trouveront dans des serveurs. Ces objets
distants pourront être appelés (à distance) à partir de clients qui auront obtenu les références
des objets. L'appel s'effectuera à l'aide de Java RMI :
1. Il partira du client et
2. passera par un talon qui encapsulera la requête pour qu'elle passe sur le réseau
3. La requête sera reçue par un squelette du côté du serveur
4. Le squelette reconstruira l'appel et l'acheminera vers le bon objet
5. L'objet exécutera la méthode et retournera un résultat
6. Le résultat sera encapsulé côyté serveur pour être passé sur le réseau
7. Le résultat sera reçu côté client par le talon qui récupérera le résultat sous la
forme approprié
8. Le résultat sera retransmis au client
Pour écrire une application client –serveur en Java, le pogrammeur doit fournir :
La description d'interface (en Java) de l'objet distant
Le programme du serveur
Les objets qui implémentent les interfaces (ce seront les objets distants)
Le serveur lui-même
Le programme du client
L'environnement fournit :
Un générateur de talons (rmic)
Un service de noms (rmiregistry)
2. Exemple d'application Java répartie : HelloWorld
Nous allons écrire une application Java répartie qui est composée d'un client et d'un serveur,
le serveur contenant un objet distant qui retourne une chaîne de caractères à afficher.
Client
Serveur
requête
réponse
2.1 L'interface de l'objet distant
import java.rmi.*;
public interface HelloInterface extends Remote {
public String sayHello()
throws java.rmi.RemoreException;
}
L'interface DOIT OBLIGATOIREMENT étendre l'interface prédéfinie
java.rmi.Remote. Chaque méthode de l'interface doit être publique et générer au moins
une exception java.rmi.RemoteException.
2.2 L'implémentation de l'objet distant
import java.rmi.*;
import java.rmi.server.*;
public class Hello extends UnicastRemoteObject
implements HelloInterface {
private String message;
/*constructeur*/
public Hello(String s) throws RemoteException{
message=s;
}
public String sayHello() throws RemoteException {
return message;
}
}
Pour que l'objet soit effectivement accessible à distance, il doit implémenter des
focntionnalités spécifiques de communication. En Java, la classe prédéfinie
java.rmi.server.UnicastRemoteObject fournit une implémentation de ces
fonctionnalités.
Notre objet distant étend donc la classe prédéfinie UnicastRemoteObject et
implémente l'interface distante que l'on a définié dans le point précédent. Ce sera bien l'objet
qui fournit la réalisation de cette interface.
La réalisation de l'objet contient un attribut privé (le message à afficher), le
constructeur et la méthode définie dans l'interafce HelloInterface. Remarquer que les
deux méthodes génèrent l'exception RemoteException.
2.3 Le programme serveur
Le serveur doit instancier l'objet distant et l'enregistrer auprès d'un service de noms pour
qu'un client puisse récupérer sa référence.
import java.rmi.*;
public class HelloServer {
public static void main(String[] args) {
try {
Naming.rebind("Hello1",
new Hello("Hello world!"));
System.out.println("Serveur prêt!");
} catch (Exception e) {
System.err.println("Erreur serveur " + e);
}
}
Dans le code donné, l'objet est instancié par new Hello("Hello world!") et
enregistré dans le service de noms à l'aide de Naming.rebind("Hello1",…). Cela veut
dire que l'objet est enregistré sous le nom de Hello1, tout client recherchant un objet portant
ce nom, retrouvera la référence de cet objet distant.
2.4 Le programme client
Le client recherche la référence de l'objet distant et appelle la méthode sayHello.
import java.rmi.*;
import java.rmi.server.*;
public class HelloClient {
public static void main(String[] args) {
try {
HelloInterface hello = (HelloInterface)
Naming.lookup(rmi://goedel.imag.fr/Hello1);
System.out.println(hello.sayHello());
} catch (Exception e) {
System.err.println("Erreur client " + e);
}
}
}
La recherche de la référence de l'objet se fait en utilisant Naming.lookup. Le nom
qui est recherché est bien Hello1 avec des informations en plus, disant que l'on va chercher
l'objet sur goedel.imag.fr. L'information que l'objet tournera sur goedel.imag.fr est donnée
lolrs du lancement du serveur (cf plus loin).
2.5 La compilation
Sur la machine serveur ; les interfaces et le programme serveur
javac HelloInterface.java Hello.java HelloServer.java
Sur la machine serveur : créer les talons client et serveur pour les objets appelés à
distance (à partir de leurs interfaces)
rmic -keep Hello
NB. -keep permet de garder les sources des classes générées
Sur la machine client : les interfaces et le programme client
javac HelloInterface.java Hello.java HelloClient.java
2.6 La sécurité
La sécirité est importante puisqu'il y a téléchargement de code. Mettre en place un
fichier policy
grant {
permission java.net.SocketPermission "*:1024-65535",
"connect,accept";
permission java.net.SocketPermission "*:80", "connect";
};
2.7 Le lancement
Lancer le serveur de noms sur la machine serveur
rmiregistry&
rmiregistry écoute par défaut sur le port 1099, il est possible de lancer rmiregistry
NoPort &
ATTENTION bien mettre la variable CLASSPATH de votre environnement à jour
pour que rmiregistry puisse trouver les classes
Lancer le serveur
java -Djava.rmi.server.codebase=
http://goedel.imag.fr/répertoire_des_classes HelloServer
-Djava.security.policy=<votre fichier policy> &
Lancer le client
java HelloClient &
3. La sérialisation Java
La sérialisation Java permet de représenter les objets Java sous une forme qui peut être
passée sur le réseau. Dans le cadre des applications Java réparties, la sérialisation est
utilisée pour passer des objets en paramètre par valeur (i.e ce n'est pas une référence vers
l'objet qui est passée mais une copie de l'objet).
Pour qu'un objet soit sérialisable il faut :
qu'il implémente l'interface java.io.Serializable (c'est juste un marquer, pas de
méthodes à implémenter)
que tous les objets qui le composent implémentent cette interface
Les objets sérialisables en Java , sans rien faire :
les objets de type de base : int, boolean…
String, Integer, Float…
et nombreux d'autres, consulter l'API Java
4. TRAVAIL A EFFECTUER
4.1 Application HelloWorld
Faitez tourner l'application HelloWorld sur deux machines. Travaillez avec un autre
binôme. (au liue de dire goedel.imag.fr vous pouvez donner l'adresse IP directement…)
4.2 Modification de HelloWorld
Modifier l'application pour que le serveur instancie un autre objet distant qui implémente
une interface différente : CalculInterface (avec des opérations plus, moins, multiplier et
diviser ayant deux paramètres, des float). Le client recherchera la référence de cet objet et
effectuera quelques calculs.
4.3 Sérialisation dans HelloWorld
Modifiez votre objet distant de calcul pour qu'il accepte une liste de requêtes et qu'il
retourne la liste des résultats.
Exemple :
En supposant que vous ayez une classe Operation qui permet de représenter une requête
de calcul.
Dans le client (c est la référence de l'objet distant) :
Vector v = new Vector();
v.addElement(new Operation("plus",10,20));
v.addElement(new Operation("moins", 50, 56.8));
Vector result = c.listeCalculs(v);
//result contient 30, -6.8
Faire la même chose mais en utilisant des tableaux et non des vecteurs.
4.4 Authentification dans HelloWorld
Protéger l'appel de l'objet Hello par une authentification i.e à chaque appel de la
méthode sayHello, demander le login et le mot de passe, si le login réussit, la méthode
est appelée, sinon, retour d'erreur.
1 / 5 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !