TP RMI

Annick Fron, Mireille Blay-Fornarino, Anne-Marie Pinna-Dery

fron@essi.fr

Printemps 2003


Environnement au choix

Java sous linux :
    export PATH=/usr/java/j2sdk1.4.0_01/bin:$PATH

Eclipse sous linux



Objet Partagé

Exo 1 :


1) A partir de l'interface Calculator suivante, implémenter la classe CalculatorImpl correspondante.
Dans l'environnement Eclipse vous pourrez générer le "patron" de cette classe.

Compilez l'interface et l'objet.

2) Générez le stub à l'aide de la commande rmic - keep

Nota : l'option -keep permet de garder le .java intermédiaire généré.

Regardez le code  CalculatorImpl_Stub.java

3) Complétez le code CalculatorServer.java pour rajouter l'enregistrement dans le Naming

4) Complétez le code CalculatorClient.java pour rajouter l'obtention d'une référence dans le Naming

5) Compilez le tout

6) Lancez

rmiregistry& //Attention le classpath doit être correct!

java CalculatorServer&

java CalculatorClient

Nota: Le calculator est partagé par les clients, il existe au niveau du serveur.
Plusieurs clients accédant au calculator en modifient la mémoire. 

Exo 2 :

7) Définir l'interface CalculatorCentral qui permet de calculer la somme des mémoires de deux calculateurs  passés en argument.

8) Implémenter et tester.



Sérialisation

Exo 3:

On rappelle que les types primitifs (String, float...) ne nécessitent aucune précaution et sont passés par valeur tels quels.

Par contre, tous les autres objets pour lesquels on veut "un passage par valeur" doivent implémenter l'interface Serializable

Définir l'implémentation d'un calculator sérialisable et tester.

Nota: Chaque client dispose de son calculateur, la mémoire commune n'est pas modifiée. 

Exo 3':

R-tetester le calculateur central avec des calculateurs sérialisés.

Exo 3'':

A présent, rajouter la propriété transient devant le champs mémoire, que se passe-t-il ?

Exo 3''':

A présent, ajouter la méthode div qui lève une exception DivisionParZéro que vous aurez définie.
L'attraper au niveau du client. Comment est-elle passée?



Comparaison temporelle des  2 approches

Exo 5 :

En vous aidant des lignes de code suivantes, comparer les temps des deux approches : sans paramètres, sérialisés par référence ....
Expliquez vos résultats. 


            System.out.println("Appel sur le serveur sans paramètre");
            long t1 = System.currentTimeMillis();
            for (int i = 0; i < 1000; i++) {
                c.vide();
            }
            long t2 = System.currentTimeMillis();
            System.out.println(
                " time:" + (t2 - t1) / 1000 + "." + (t2 - t1) % 1000 + " ms");
            System.out.println(" time:" + (t2 - t1) + " micros");



Chargement Dynamique de stub

Exo 4:

L'objectif est dans cet exercice de définir un Client qui au lancement de l'application n'a pas dans son classPath, les stubs nécessaires à son exécution.

Elements de solution:
1) Recopier un des clients dans un nouveau un nouveau répertoire ainsi que l'interface Calculator sans changer son nom (par exemple exo1.Calculator).
Votre client  ne doit importer que l'interface Calculator bien sûr.

Lancer votre client.

Une erreur stub inconnu se produit!

2) Relancer votre client en ajoutant la propriété suivante au lancement:
-Djava.rmi.server.codebase=chemin où se trouve le . class des stubs,
 ( chemin par exemple : http://ciel.essi.fr/classes/ ou file:/u/essi/blay/RMI/RMI2002/src/exo1/)
N'oublier pas le / à la fin de la commande.

Vous avez alors un problème de sécurité qui se confirme.

3) La définition d'un gestion de sécurité très laxiste est alors nécessaire, tel que celui-ci par exemple.
Il ne nous reste plus à présent qu'à autoriser notre client à charger des stubs en ajoutant les lignes suivantes:
            if (System.getSecurityManager()==null){
                System.setSecurityManager(new DownloadableSecurityManager());
            }


Et maintenant, ce code devrait fonctionner!



Exo 4'':

Que pensez-vous des temps d'exécutions?



Sécurité et RMIRegistry

Exo 6 :

Modifier le code de RMIServer.java pour lancer par programme le registry (équivalent de rmiregistry) avec la commande :

LocateRegistry.createRegistry( PORT );

Modifier également le nom de l'hôte en remplaçant par celui de votre machine dans RMIServer.java et RMIClient.java.

Lancer les deux programmes. Que se passe-t-il?


Des Informations sur la sécurité


Le SecurityManager

voir aussi Security

Introduction

Lorsque l'on essaie d'utiliser un SecurityManager, on obtient le message d'erreur suivant :

java.security.AccessControlException: access denied
(java.net.SocketPermission 127.0.0.1:1099 connect,resolve)

Modification par programme

System.setSecurityManager (new RMISecurityManager() {
public void checkConnect (String host, int port) {}
public void checkConnect (String host, int port, Object context) {}
});

Le fichier .java.policy

Les permissions du SecurityManager sont spécifiées dans l'ordre :

dans le fichier java.policy de ${java.home}/lib/security/java.policy

puis dans

${user.home}/.java.policy (attention au point !)

Les instructions du fichier policy

Le serveur doit pouvoir accepter des connexions d'un hôte particulier :

permission java.net.SocketPermission "sace.essi;fr", "accept";

ou de tous les hôtes et pouvoir faire resolve également :

permission java.net.SocketPermission "*", "accept, resolve";

Pour définir cela, lancer la commande (sous jdk/bin) (voir aussi "A quick look at policytool"):

policytool

et éditer le fichier .java.policy (sous Linux sous ~, sur PC sur c:\winnt\profiles\votreNomuser)

Voir également policy files

On trouvera également ici un fichier levant toutes les sécurités : policy

Voir également la documentation Sun

Utilisation d'un fichier policy par commande en ligne

java -Djava.security.manager -Djava.security.policy=policy-file MyClass

Téléchargement de classes

-Djava.rmi.server.codebase=code-base

Utilisation d'un serveur de classes

http://java.sun.com/products/jdk/rmi/class-server.zip


Utilisation d'eclipse

Eclipse (http://www.eclipse.org) est une environnement de développement java en Open source.

Créer un répertoire metadata sous votre racine

cd ~

mkdir metadata

Lancer les commandes :

cd /linux/eclipse

./eclipse -data ~/metadata

Créer alors un nouveau projet sous eclipse

Pour cela, consulter la FAQ eclipse :

http://www.eclipse.org/eclipse/faq/eclipse-faq.html#users_4

Importer dans le projet les jars du répertoire /opt/mqm/java/lib (clic droit sur project properties puis onglet libraries/add external jars)