Professional Documents
Culture Documents
v 1.80
RMI (Remote Method Invocation) est une technologie dveloppe et fournie par Sun partir du JDK 1.1 pour permettre de mettre en oeuvre facilement des objets distribus. Ce chapitre contient plusieurs sections : La prsentation et l'architecture de RMI Les diffrentes tapes pour crer un objet distant et l'appeler avec RMI Le dveloppement cot serveur Le dveloppement cot client La gnration de la classe stub La mise en oeuvre des objets RMI open in browser PRO version Are you a developer? Try out the HTML to PDF API
pdfcrowd.com
25.2. Les diffrentes tapes pour crer un objet distant et l'appeler avec RMI
Le dveloppement cot serveur se compose de : La dfinition d'une interface qui contient les mthodes qui peuvent tre appeles distance L'criture d'une classe qui implmente cette interface
pdfcrowd.com
L'criture d'une classe qui instanciera l'objet et l'enregistrera en lui affectant un nom dans le registre de nom RMI (RMI Registry) Le dveloppement ct client se compose de : L'obtention d'une rfrence sur l'objet distant partir de son nom L'appel la mthode partir de cette rfrence Enfin, il faut gnrer les classes stub et skeleton en excutant le programme rmic avec le fichier source de l'objet distant
25.3.1. La dfinition d'une interface qui contient les mthodes de l'objet distant
L'interface dfinir doit hriter de l'interface java.rmi.Remote. Cette interface ne contient aucune mthode mais indique simplement que l'interface peut tre appele distance. L'interface doit contenir toutes les mthodes qui seront susceptibles d'tre appeles distance. La communication entre le client et le serveur lors de l'invocation de la mthode distante peut chouer pour diverses raisons telles qu'un crash du serveur, une rupture de la liaison, etc ... Ainsi chaque mthode appele distance doit dclarer qu'elle est en mesure de lever l'exception java.rmi.RemoteException.
pdfcrowd.com
Exemple ( code Java 1.1 ) : 01. 02. 03. 04. 05. 06. 07. 08. 09. package com.jmdoudoux.test.rmi; import java.rmi.*; public interface Information extends Remote { public String getInformation() throws RemoteException; }
pdfcrowd.com
Comme indiqu dans l'interface, toutes les mthodes distantes, mais aussi le constructeur de la classe, doivent indiquer qu'elles peuvent lever l'exception RemoteException. Ainsi, mme si le constructeur ne contient pas de code il doit tre redfini pour inhiber la gnration du constructeur par dfaut qui ne lve pas cette exception. Exemple ( code Java 1.1 ) : 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. package com.jmdoudoux.test.rmi; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; public class InformationImpl extends UnicastRemoteObject implements Information { private static final long serialVersionUID = 2674880711467464646L; protected InformationImpl() throws RemoteException { super(); } public String getInformation() throws RemoteException { System.out.println("Invocation de la mthode getInformation()"); return "bonjour"; }
25.3.3. L'criture d'une classe pour instancier l'objet et l'enregistrer dans le registre
Ces oprations peuvent tre effectues dans la mthode main d'une classe ddie ou dans la mthode main de la classe de l'objet distant. L'intrt d'une classe ddie et qu'elle permet de regrouper toutes ces oprations pour un ensemble d'objets distants.
pdfcrowd.com
La marche suivre contient trois tapes : la mise en place d'un security manager ddi qui est facultative l'instanciation d'un objet de la classe distante l'enregistrement de la classe dans le registre de noms RMI en lui donnant un nom
Il est aussi possible d'activer un security manager en utilisant simplement l'option -Djava.security.manager de la JVM.
pdfcrowd.com
pdfcrowd.com
C'est ce nom qui sera utilis dans une URL par le client pour obtenir une rfrence sur l'objet distant. L'enregistrement se fait en utilisant la mthode rebind de la classe Naming. Elle attend en paramtre l'URL du nom de l'objet et l'objet lui mme. Exemple ( code Java 1.1 ) : 01. public static void main(String[] args) { 02. try { 03. if (System.getSecurityManager() == null) { 04. System.setSecurityManager(new RMISecurityManager()); 05. } 06. 07. InformationImpl informationImpl = new InformationImpl(); 08. 09. String url = "rmi://" + InetAddress.getLocalHost().getHostAddress() + "/TestRMI"; 10. System.out.println("Enregistrement de l'objet avec l'url : " + url); 11. Naming.rebind(url, informationImpl); 12. 13. System.out.println("Serveur lanc"); 14. } catch (RemoteException e) { 15. e.printStackTrace(); 16. } catch (MalformedURLException e) { 17. e.printStackTrace(); 18. } catch (UnknownHostException e) { 19. e.printStackTrace(); 20. } 21. }
pdfcrowd.com
Ce registre peut tre lanc en tant qu'application fournie dans le JDK (rmiregistry) comme indiqu dans un chapitre suivant ou tre lanc dynamiquement dans la classe qui enregistre l'objet. Ce lancement ne doit avoir lieu qu'une seule et unique fois. Il peut tre intressant d'utiliser le code ci-dessous si l'on cre une classe ddie l'enregistrement des objets distants. Le code pour excuter le registre est la mthode createRegistry() de la classe java.rmi.registry.LocateRegistry. Cette mthode attend en paramtre un numro de port. Exemple ( code Java 1.1 ) : 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. package com.jmdoudoux.test.rmi; import import import import import import import java.net.InetAddress; java.net.MalformedURLException; java.net.UnknownHostException; java.rmi.Naming; java.rmi.RMISecurityManager; java.rmi.RemoteException; java.rmi.registry.LocateRegistry;
public class LanceServeur { public static void main(String[] args) { try { LocateRegistry.createRegistry(1099); System.out.println("Mise en place du Security Manager ..."); if (System.getSecurityManager() == null) { System.setSecurityManager(new RMISecurityManager()); } InformationImpl informationImpl = new InformationImpl(); String url = "rmi://" + InetAddress.getLocalHost().getHostAddress() + "/TestRMI"; System.out.println("Enregistrement de l'objet avec l'url : " + url); Naming.rebind(url, informationImpl); System.out.println("Serveur lanc"); } catch (RemoteException e) { e.printStackTrace(); } catch (MalformedURLException e) {
Are you a developer? Try out the HTML to PDF API
pdfcrowd.com
31. } catch (MalformedURLException e) { 32. e.printStackTrace(); 33. } catch (UnknownHostException e) { 34. e.printStackTrace(); 35. } 36. } 37. }
pdfcrowd.com
25.4.2. L'obtention d'une rfrence sur l'objet distant partir de son nom
Pour obtenir une rfrence sur l'objet distant partir de son nom, il faut utiliser la mthode statique lookup() de la classe Naming. Cette mthode attend en paramtre une URL indiquant le nom qui rfrence l'objet distant. Cette URL est compose de plusieurs lments : le prfix rmi://, le nom du serveur (hostname) et le nom de l'objet tel qu'il a t enregistr dans le registre prcd d'un slash. Il est prfrable de prvoir le nom du serveur sous forme de paramtres de l'application ou de l'applet pour plus de souplesse. La mthode lookup() va rechercher dans le registre du serveur l'objet et retourner un objet stub. L'objet retourn est de la classe Remote (cette classe est la classe mre de tous les objets distants). Si le nom fourni dans l'URL n'est pas rfrenc dans le registre, la mthode lve l'exception NotBoundException. Exemple ( code Java 1.1 ) : 01. public static void main(String[] args) { 02. 03. if (System.getSecurityManager() == null) { 04. System.setSecurityManager(new RMISecurityManager()); 05. } 06. 07. try { 08. Remote r = Naming.lookup("rmi://10.0.0.13/TestRMI"); 09. } catch (Exception e) { 10. e.printStrackTrace(); 11. } 12. 13. }
pdfcrowd.com
pdfcrowd.com
28. } catch (NotBoundException e) { 29. e.printStackTrace(); 30. } 31. System.out.println("Fin du client"); 32. } 33. }
pdfcrowd.com
18. } 19. } catch (Exception e) { 20. e.printStrackTrace(); 21. } 22. } 23. 24. public void paint(Graphics g) { 25. super.paint(g); 26. g.drawString("chaine retourne = "+s,20,20); 27. } 28. }
rmic va gnrer et compiler la classe stub sous le nom InformationImpl_Stub.class. Cette classe sera utilis par la partie cliente pour invoquer l'objet distant correspondant.
pdfcrowd.com
pdfcrowd.com
Pour ne pas avoir de problme, il faut s'assurer que toutes les classes utiles (la classe de l'objet distant, l'interface qui dfinit les mthodes) sont prsentes dans un rpertoire dfini dans le classpath. Si un gestionnaire de scurit est mis en place, il faut dfinir un fichier qui va contenir la politique de scurit qu'il doit mettre en oeuvre. Exemple ( code Java 1.1 ) : le fichier ma_policy_serveur 1. 2. 3. 4. 5. grant{ permission java.net.SocketPermission "localhost:1099", "connect, resolve"; permission java.net.SocketPermission "*:1024-", "connect, resolve"; permission java.net.SocketPermission "*:1024-", "accept, resolve"; };
Les permissions dfinies concernent les permissions de connexions par socket au serveur. Lors du lancement du serveur, l'option java.security.policy permet de prciser le fichier qui sera utilis par le gestionnaire de scurit. Exemple ( code Java 1.1 ) : le fichier ma_policy_serveur 1. 2. 3. 4. 5. C:\Users\Jean Michel\workspace\TestRmiServer>java -cp bin -Djava.security.policy =ma_policy_serveur com.jmdoudoux.test.rmi.LanceServeur Mise en place du Security Manager ... Enregistrement de l'objet avec l'url : rmi://10.0.0.13/TestRMI Serveur lanc
pdfcrowd.com
Le client qui invoque l'objet distant est invoqu de manire classique. Exemple : 1. 2. 3. 4. 5. 6. C:\temp>java -jar TestRMIClient.jar Lancement du client InformationImpl_Stub[UnicastRef [liveRef: [endpoint:[10.0.0.13:62802](remote),ob jID:[7b7739e4:135b4a87a5e:-7fff, -3323459310870193038]]]] chaine renvoyee = bonjour Fin du client
Si le serveur n'est pas dmarr, une exception est leve Exemple : 01. C:\temp>java -jar TestRMIClient.jar 02. Lancement du client 03. java.rmi.ConnectException: Connection refused to host: 10.0.0.13; nested excepti 04. on is: 05. java.net.ConnectException: Connection timed out: connect 06. at sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source) 07. at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source) 08. at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source) 09. at sun.rmi.server.UnicastRef.newCall(Unknown Source) open in browser PRO version Are you a developer? Try out the HTML to PDF API
pdfcrowd.com
09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29.
at sun.rmi.server.UnicastRef.newCall(Unknown Source) at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source) at java.rmi.Naming.lookup(Unknown Source) at com.jmdoudoux.test.rmi.LanceClient.main(LanceClient.java:17) Caused by: java.net.ConnectException: Connection timed out: connect at java.net.TwoStacksPlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source) at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source) at java.net.AbstractPlainSocketImpl.connect(Unknown Source) at java.net.PlainSocketImpl.connect(Unknown Source) at java.net.SocksSocketImpl.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at java.net.Socket.<init>(Unknown Source) at java.net.Socket.<init>(Unknown Source) at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(Unknown S ource) at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(Unknown S ource) ... 7 more Fin du client
La partie client peut tre lance avec un gestionnaire et une politique de scurit associe. Exemple ( code Java 1.1 ) : 1. 2. 3. 4. 5. 6. C:\temp>java -jar -Djava.security.policy=ma_policy_client TestRMIClient.jar Lancement du client InformationImpl_Stub[UnicastRef [liveRef: [endpoint:[10.0.0.13:62802](remote),ob jID:[7b7739e4:135b4a87a5e:-7fff, -3323459310870193038]]]] chaine renvoyee = bonjour Fin du client
Si le gestionnaire est activ sans policy associ, alors la connexion au serveur est impossible. Exemple ( code Java 1.1 ) : open in browser PRO version
pdfcrowd.com
01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.
C:\temp>java -jar -Djava.security.manager TestRMIClient.jar Lancement du client Exception in thread "main" java.security.AccessControlException: access denied ( "java.net.SocketPermission" "10.0.0.13:1099" "connect,resolve") at java.security.AccessControlContext.checkPermission(Unknown Source) at java.security.AccessController.checkPermission(Unknown Source) at java.lang.SecurityManager.checkPermission(Unknown Source) at java.lang.SecurityManager.checkConnect(Unknown Source) at java.net.Socket.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at java.net.Socket.<init>(Unknown Source) at java.net.Socket.<init>(Unknown Source) at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(Unknown S ource) at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(Unknown S ource) at sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source) at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source) at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source) at sun.rmi.server.UnicastRef.newCall(Unknown Source) at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source) at java.rmi.Naming.lookup(Unknown Source) at com.jmdoudoux.test.rmi.LanceClient.main(LanceClient.java:17)
Dveloppons en Java
v 1.80
pdfcrowd.com