Jusqu'à présent, toutes les classes étaient exécutées dans l'environnement clos d'une machine ( virtuelle ), la JVM. Nous allons maintenant voir que nous pouvons également exécuter des classes distantes. C'est la notion d'objets distribués.
Considérons un réseau de machines reliées pouvant dialoguer via des couches de communications. Chacune d'elles possède des ressources :
Hardware ( CPU, mémoire )
Software ( accès à des programmes dans un environnement donné )
A accès restreint ( machine ayant les accès privilégiés sur le LAN...)
Dans un environnement classique, sur chaque machine, nous avons une JVM et des classes qui s'exécutent en local. Malheureusement, il n'y a aucun dialogue entre ces environnements d'exécution: une classe Ca s'exécutant sur une machine A ne peut échanger de résultats avec une classe Cb s'exécutant sur une autre machine ou même sur la même machine mais dans une autre JVM.
Par
exemple, Lancez java Ca puis java Cb sur la même
machine ou une machine distante. Il n'y a aucune
communication possible entre les deux processus. Le concept d'objets
distribués permet de résoudre ce problème.
Il permet de rendre disponible un objet à
toutes les machines autorisées. L'objet est alors distribué
car accessible de tout point du réseau.
Ce type d'architecture est profondément client/serveur. Nous trouvons pour chaque objet distribué:
La machine serveur qui possède l'objet
Les machines clientes qui demandent l'exécution de l'objet et récupèrent les résultats de ses méthodes.
En exécutant un objet distant, il devient alors possible de créer un dialogue entre les machines clientes et la machine serveur et d'utiliser des ressources distantes.
Communication entre deux applications Java: un tableau provenant d'un tableur est incorporé via drag & drop dans le document en cours d'un traitement de texte.
Calcul distribué: nous envoyons à une machine puissante une équation à résoudre, le calcul se fait sur cette machine et le résultat est récupéré sur notre PC.
Middleware: vous ne pouvez accéder à des ressources distantes mais vous demandez au middleware d'effectuer des requêtes ou des lancements de programmes.
Communication entre deux machines distantes: du bureau, vous demandez à votre PC de fermer les fenêtres de chez vous en cas d'orage, de lancer une machine à laver ou le chauffage.
Bref, le RMI permet à deux
machines de communiquer de façon transparente.
Mais entrons davantage dans le détail du RMI en détaillant son fonctionnement général.
Un objet distribué possède toujours deux parties:
La partie serveur implémentant l'objet et dérivant toujours de java.rmi.server.UnicastRemoteObject
La partie cliente est une simple interface dérivant de java.rmi.Remote et déclare les mêmes méthodes que la partie serveur.
La communication client-serveur se fait ainsi:
Coté serveur,
Un programme natif appelé RMIRegistry tourne et fait office de listener aux demandes RMI qui se font par défaut sur le port 1099. Une classe instancie l'objet distribué, donne son URL et accepte les demandes RMI d'accès à cet objet ( fait un rebind ).
Coté client
L'utilisateur lance une classe qui fait une recherche sur l'objet distant ( un lookup ) et récupère une référence distante. Dès lors, il peut utiliser cet objet comme s'il était en local. Remarque: Nous ne détaillerons pas ici les mécanismes assez complexes qui sous-tendent ce processus. Pour une formation plus poussée, consulter le tutorial RMI de SUN dont l'URL est donnée plus bas.
En guise de cours, nous allons donner un rapide exemple d'application RMI appelé MiniMiddleware et servant à gérer le lancement d'un programme placé sur un serveur à partir de n'importe quel poste client ( rexec ) . Une application pourrait être le lancement de binaires AIX placé sur un serveur Unix à partir d'un poste sous Microsoft Windows et d'en récupérer le code de sortie.
1- Déclarer une interface pour l'objet distribué
interface
MiniMiddleware extends java.rmi.Remote{
public int launch(String sProg) throws java.rmi.RemoteException;
}
}
Puis compiler l'interface pour disposer d'une classe MiniMiddleware
2- Implémenter l'objet distribué
public
class MiniMiddlewareImpl extends UnicastRemoteObject implements
MiniMiddleware{ //on remarque la norme de nommage 'Impl'
public
MiniMiddleware() throws java.rmi.RemoteException{ //constructeur par
défaut
super();
}
public int
launch(String sNomProg) throws java.rmi.RemoteException {
Process p=System.exec(sNomProg); //lancement du programme
p.waitFor(); //attente de la fin de l'exécution
return (int)p.getExitValue();
}
}
Le compiler.
3- Générer les classes squelette qui vont permettre le dialogue avec RMIRegistry par le programme JDK rmic:
rmic MiniMiddleware
qui devrait créer les classes MiniMiddleware_Skel.class et MiniMiddleware_Stub.class
4- Implémenter le programme serveur de gestion de l'objet distribué.
import
java.rmi.Naming;
public class MiniMiddlewareServer{
public static void main(String[] sArgs)
{
try{
MiniMiddleware mmServer=new MiniMiddleware(); //on instancie cet
UnicatRemoteObject
Naming.rebind("rmi://"+sArgs[0]+":"+sArgs[1]+"/MiniMiddlewareService",mmServer);
}
catch(RemoteException
re){
re.printStackTrace();
}
}
}
Compiler cette classe.
5- Implémenter un exemple de classe cliente utilisant l'objet distribué
import
java.rmi.*;
public class TestMiniMiddleware(){
public static void main(String[] sArgs){
try{
MiniMiddleware
mmClient=(MiniMiddleware)Naming.lookup("rmi://"+sArgs[0]+":"+sArgs[1]+"/MiniMiddlewareService");
mmClient.launch(sArgs[2]);
}
catch(RemoteException
re){
re.printStackTrace();
}
}
}
Compiler la classe.
6- Lancer le serveur RMI:
rmiregistry
Puis le programme serveur:
java MiniMiddlwareServer [nom de la machine] [port]
Testons finalement la communication:
java TestMiniMiddleware [nom de la machine] [port] [ commande à lancer sur le serveur]
Tutorial Sun:
http://developer.java.sun.com/developer/onlineTraining/rmi/
Corba ou 'Common Object Request Broker Architecture' est une norme élaborée par 700 sociétés regroupées dans le groupe de développement OMG. Tout comme RMI, il permet de faire interagir des objets distribués. Cependant, il ajoute une 'couche' à la programmation distribuée pour rendre les objets indépendants du langage de programmation dans lequel ils ont été écris. Ainsi, un objet C++ peut dialoguer avec un objet Java ou Lisp... Les langages supportés par Corba sont principalement: C,C++, Java, Ada, Cobol, Smalltalk et Lisp. Un 'objet' Corba est une simple interface écrit en IDL (Interface Definition Language) et n'implémente aucune méthode. Le compilateur IDL va générer une interface dans le langage désiré. Ainsi, nous obtenons comme en RMI une classe 'squelette' qui sera l'image de la classe implémentée. Ensuite, il faut implémenter la classe correspondant à cet interface. A l'utilisation, le dialogue entre les objets se fera via un ORB (Object Request Broker) qui joue le même rôle que le RmiRegistry de Java. L'ORB permettra l'exécution de méthodes distantes et accessoirement écrites dans un autre langage. L'IDL supporte :
les principaux types (int,long,float,string)
Les exceptions
Les types structurés
Le protocole de communication Corba s'appelle l'IIOP ( Internet Inter-ORB protocole ).
Tutorial Sun:
http://developer.java.sun.com/developer/onlineTraining/corba/