M2 RSD : Construction d’applications réparties TP N° 1 : Java RMI 2020/2021 Exe

M2 RSD : Construction d’applications réparties TP N° 1 : Java RMI 2020/2021 Exercice 1 : Dans ce qui suit, nous allons considérer les codes suivants (modification légère par rapport au TD 1) : import java.rmi.Remote; import java.rmi.RemoteException; public interface ObjetSInterface extends Remote { public String miroir (String a) throws RemoteException; } import java.rmi.Remote; import java.rmi.RemoteException; public interface ObjetCInterface extends Remote { public int mul(int a, int b) throws RemoteException; } TTT est une nouvelle interface par rapport au TD 1. import java.rmi.Remote; import java.rmi.RemoteException; public interface TTT extends Remote { public int add (int a, int b) throws RemoteException; } ObjetS implémente une seule interface contenant une seule méthode (miroir). import java.rmi.*; import java.rmi.server.*; public class ObjetS extends UnicastRemoteObject implements ObjetSInterface{ public ObjetS() throws RemoteException {} public String miroir (String a) throws RemoteException { String r=""; for (int i=a.length() ;i>0 ;i--) r=a.charAt(a.length()-i)+r; return r; } } ObjetC implémente 2 interfaces (une méthode par interface), add et mul respectivement. import java.rmi.*; import java.rmi.server.*; public class ObjetC extends UnicastRemoteObject implements ObjetCInterface, TTT { public ObjetC() throws RemoteException {} public int mul (int a, int b) throws RemoteException { return (a*b); } public int add(int a, int b) throws RemoteException { return (a+b); } } import java.rmi.*; import java.rmi.registry.LocateRegistry; public class ServeurSC { public static void main(String[] args){ try {LocateRegistry.createRegistry(1099); } catch (RemoteException e1) { System.err.println("rmiregistry est déjà lancé sur ce port"); System.exit(1); } try { ObjetS objets= new ObjetS(); System.out.println(objets); Naming.rebind("Miroir", objets); ObjetC objetc = new ObjetC(); System.out.println(objetc); Naming.rebind("Multi", objetc); System.out.println("Le serveur est pret"); } catch (Exception e) { System.err.println("Erreur: " + e.getMessage()); } } } import java.rmi.*; class ClientSC{ public static void main (String [] argv){ try { ObjetSInterface s= (ObjetSInterface) Naming.lookup ("Miroir"); // une seule interface System.out.println (s); System.out.println (s.miroir("RSDJAVARMI")); // dans ce qui suit, caster avec la première interface pour appeler mul ObjetCInterface a=(ObjetCInterface) Naming.lookup("Multi"); System.out.println (a); System.out.println (a.mul(5,6)); TTT b = (TTT)a; // caster avec la deuxième interface pour appeler add System.out.println (b); System.out.println (b.add(5,6)); } catch (Exception e) {System.err.println("Erreur: " + e.getMessage()); } } } 1. Dans ObjetS(), mettez la ligne : public ObjetS() throws RemoteException{} en commentaire. C’est quoi le problème ? 2. Reprenez votre code et retirez throws RemoteException{} de la déclaration du constructeur. C’est quoi le problème ? 3. Reprenez votre code et lancez ServeurSC plusieurs fois. Examinez le numéro de port de chaque objet, comment se fait le choix de ce port ? 4. En examinant la documentation de la classe UnicastRemoteObject. https://docs.oracle.com/javase/8/docs/api/java/rmi/server/UnicastRemoteObject.html Installez ObjetS sur le port 1000 et ObjetC sur le port 2000 (utilisez le constructeur de la classe UnicastRemoteObject ). 5. Exécutez à nouveau ServeurSC pour vérifier. 6. Peut-on installer les deux objets sur le port 1099 ? Faites un test. 7. Installez les deux objets sur le port 0. Comment se fait le choix du port dans ce cas ? 8. Comparez les infos de chaque objet distant avec son stub respectivement. Quel est le lien ? 9. Supposons que l’affichage de l’un des stub donne ce qui suit : Proxy[ObjetSInterface,RemoteObjectInvocationHandler[UnicastRef [liveRef: [endpoint: [192.168.1.6:56640](remote),objID:[-1a9a6e54:16e13d14270:-7fff, -1740617560762366171]]]]] Quel est le rôle de objID ? Voir le lien https://docs.oracle.com/javase/7/docs/api/java/rmi/server/ObjID.html. 10. Quel est le rôle de [192.168.1.6:56640] ? 11. Dans ClientSC, affichez les noms enregistrés (les clés) dans l’annuaire qui est installé coté serveur. Exercice 2 : Dans cet exercice, nous allons utiliser une autre manière afin d’exporter un objet dans le serveur. Cette manière est obligatoire si la classe représentant l’objet distant est déjà une classe fille d’une autre classe mère. Ex. dans l’exercice 1, supposons que ObjetS est déclaré comme suit : public class ObjetS extends A (A est une classe quelconque qui peut être aussi prédéfinie comme JApplet ou autres). Dans ce cas, on ne peut pas faire ce qui suit : public class ObjetS extends A, UnicastRemoteObject implements ObjetSInterface  pas d’héritage multiple en JAVA. Comment procéder dans ce cas pour exporter un objet lié à une classe mère dans le serveur ? Dans la documentation de la classe UnicastRemoteObject : https://docs.oracle.com/javase/8/docs/api/java/rmi/server/UnicastRemoteObject.html, examiner les différentes signatures de la méthode exportObject. Dans ce qui suit, nous allons utiliser la signature suivante : public static Remote exportObject(Remote obj, int port) throws RemoteException Soit les classes suivantes: import java.rmi.Remote; import java.rmi.RemoteException; public interface SSN extends Remote { public String getSSN(String name) throws RemoteException; } import java.rmi.*; import java.util.*; import javax.swing.JApplet; public class SSNImpl extends JApplet implements SSN { private Map rep; // rep est un attribut dans l’objet public SSNImpl() throws RemoteException{ rep = new HashMap(); rep.put("Anes","111-11-1111"); rep.put("Badr", "222-22-2222"); rep.put("Youcef", "333-33-3333"); rep.put("Saleh", "444-44-4444"); } public String getSSN(String name) throws RemoteException { if (rep.containsKey(name)) return (String)rep.get(name); else return null; } } Pour Map, voir : https://docs.oracle.com/javase/8/docs/api/java/util/Map.html Pour HashMap, voir :https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html Explication : notre objet contient un attribut ressemblant à une table de hachage dont les clés sont des personnes (String) et les valeurs sont leurs numéros de sécurité sociale respectivement (String). import java.rmi.server.*; import java.rmi.registry.*; import java.rmi.registry.LocateRegistry; public class SSNServer { public static void main(String args[]) { try { SSNImpl objet = new SSNImpl(); SSN objetexport =(SSN) UnicastRemoteObject.exportObject(objet, 5000); System.out.println(objetexport); Registry registry=LocateRegistry.createRegistry(4444); System.out.println(registry); registry.rebind("SSN", objetexport); System.out.println("Le serveur est prêt ..."); } catch (Exception e) {System.out.println("Exception: " + e.getMessage());} } } import java.rmi.registry.*; import java.rmi.registry.LocateRegistry; public class SSNClient { public static void main(String args[]) { try { Registry registry = LocateRegistry.getRegistry(3333); // récupérer la référence de l'annuaire SSN stub = (SSN) registry.lookup("SSN"); // utiliser la référence de l'annuaire au lieu de Naming String RA = stub.getSSN("Saleh"); // appel de la méthode à distance System.out.println("SSN de Saleh : " + RA); String RB = stub.getSSN("Youcef"); // appel de la méthode à distance System.out.println("SSN de Youcef : " + RB); String RD = stub.getSSN("Badr"); // appel de la méthode à distance System.out.println("SSN de Badr : " + RD); } catch (Exception e) {System.out.println("exception: " +e.getMessage()); } } } 1. Lancez le serveur et le client, ça ne marche pas. Vérifiez le numéro de port coté client et lancez une nouvelle exécution. 2. Dans la classe SSNImpl, remplacez public class SSNImpl extends JApplet implements SSN par public class SSNImpl extends UnicastRemoteObject implements SSN. Mettez en commentaire import javax.swing.JApplet; et ajouter import java.rmi.server.UnicastRemoteObject; Lancez le serveur. C’est quoi le problème ? Expliquez l’exécution : Exception: object already exported. Remarque : l’annuaire contient une seule clé (SSN), cette dernière pointe vers l’objet contenant l’attribut rep et c’est ce dernier qui contient le HashMap comme indiquer dans la figure suivante. 3. Reprendre la signature suivante pour SSNImpl : public class SSNImpl implements SSN. Ajoutez la méthode public void REMPLACER(String name) throws RemoteException à la classe SSNImpl. Cette méthode remplace le numéro de sécurité sociale d’une personne indiquée ici par name par son ancien numéro concaténé avec "-DZ". Exemple : L’appel suivant stub.REMPLACER("Anes"); dans le client doit remplacer 111-11-1111 par 111-11-1111-DZ dans le serveur. Ici, le client ne s’attend pas à recevoir une réponse de la part du serveur, il veut juste exécuter une méthode dans le serveur (méthode de type void). 4. Ajoutez la méthode public String AfficherTout() throws RemoteException; à la classe SSNImpl. Cette méthode affiche les numéros de sécurité sociale de toutes les personnes. Exemple : System.out.println (stub.AfficherTout()); dans le client affiche [222-22-2222, 111-11- 1111-DZ, 333-33-3333, 444-44-4444] suite à l’exécution dans le serveur de la méthode AfficherTout(). Bien évidement votre interface finale sera comme suit : import java.rmi.Remote; import java.rmi.RemoteException; public interface SSN extends Remote { public String getSSN(String name) throws RemoteException; public void REMPLACER(String name) throws RemoteException; public String AfficherTout() throws RemoteException; } Indication : voir les méthodes de https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html pour les deux dernières questions. 5. Faites une modification sur le code précédent afin de mettre en place un service d’annuaire téléphonique permettant d’enregistrer des noms et des numéros de téléphone sous la forme de chaines de caractères en se basant sur une HashMap. uploads/S4/ tp1-2020.pdf

  • 26
  • 0
  • 0
Afficher les détails des licences
Licence et utilisation
Gratuit pour un usage personnel Attribution requise
Partager
  • Détails
  • Publié le Jan 06, 2022
  • Catégorie Law / Droit
  • Langue French
  • Taille du fichier 0.1753MB