par , 23/05/2016 à 23h28 (2741 Affichages)
J’ai pris un peu de temps pour vous faire un projet sous Eclipse (pour un NetBeanien, cela change un peu!) qui implémente un serveur et un client RMI selon les règles de l’art, et ceci pour l'un de mes étudiants en pleine VAE, a partager, si cela peut être utile à d'autres.
Ce projet se compose de 2 packages, le premier se nomme « rmiServer », il contient les sources du serveur RMI, qui :
– Fait appel au fichier security.policy et affecte cette nouvelle police de sécurité avant le démarrage du serveur RMI.
– Fait appel au rmiregistry de manière « programmatique » grâce à la méthode « java.rmi.registry.LocateRegistry.createRegistry(int port) », ceci est plus sympa et évite des manœuvre de commandes pour lancer rmiRegistry avant le serveur RMI.
– Implémente l’objet et l’enregistre dans le rmiRegistry.
Nb : Pour information, j’ai créer dans le dossier ./bin du projet un dossier « security », qui contient le fichier security.policy, il est assez simple et ouvre tous les droits grâce a un grant AllPermission sur tout (dangereux, mais plus simple à gérer).
Ci dessous le contenu du fichier security.policy
grant {
permission java.security.AllPermission;
};
Il faut compiler ce premier projet (rmiserver), cela génère les fichiers class :
- AdditionInterface.class
- Addition.class
- AdditionServer.class
Ces fichiers ne sont pas suffisants pour constituer le serveur RMI, il faut également générer un fichier class que l’on nomme Stub, et qui permettra de faire la relation entre ce serveur et notre client (a va voir comment dans quelques instants).
Il faut ensuite compiler l’objet Addition pour générer le fichier :
Pour cela il faut se placer dans le dossier ./bin du projet dans une console DOS ou Shell pour les "Linuxien" et tapez la commande suivante :
rmic rmiserver.Addition
Assurez vous que le vous êtes bien dans le dossier ./bin et que dans le dossier rmiserver qui se trouve dans le dossier ./bin il y ai bien les fichiers cités plus haut.
ceci génère dans le dossier ./bin/rmiserver, le fichier Addition_Stub.class
Il faut copier ce fichier Addition_Stub.class dans le dossier ./bin/rmiclientjfx, ceci afin qu’il soit visible et utilisable également par notre client.
L’application cliente, se trouve dans le package « rmiclientjfx », elle est constitué du fichier Additionclient.java uniquement.
Les choses importantes à réaliser au niveau du client sont :
- Mettre l’import suivant « import java.rmi.*; » qui permet d’indiquer à notre client ou trouver le fichier contenant l’interface « AdditionInterface »
- Y indiquer ou chercher le fichier security.policy
- Appeler le lookup de l’objet AdditionServer.
- Et appeler la méthode « add » distante.
compiler ce client de manière classique, ceci génère dans le dossier ./bin/rmiclientjfx, le fichier AdditionClient.class.
Il ne reste plus qu’a lancer les applications :
- Lancer le serveur, on se met dans le dossier ./bin du projet et tapez la commande :
start java rmiserver.AdditionServer
- Lancer le client, on se met dans le dossier ./bin du projet et tapez la commande :
java rmicleintjfx.AdditionClient
Et le tout doit fonctionner parfaitement.
Regardons maintenant le code source du server RMI :
AdditionInterface.java
1 2 3 4 5 6 7 8 9
|
package rmiserver;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface AdditionInterface extends Remote {
public int add(int a,int b) throws RemoteException;
} |
Addition.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
package rmiserver;
import java.rmi.*;
import java.rmi.server.*;
@SuppressWarnings("serial")
public class Addition extends UnicastRemoteObject implements AdditionInterface {
public Addition () throws RemoteException { super(); }
@Override
public int add(int a, int b) throws RemoteException {
int result=a+b;
return result;
}
} |
AdditionServer.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
package rmiserver;
import java.rmi.*;
public class AdditionServer {
public static void main (String[] argv) {
/*modifier la sécurité
on récupère le dossier courant de l'application
et on ajoute le dossier ou se trouve le fichier security.policy
IL faut ensuite modifier la propriété java.security.policy
et lui affecter la nouvelle police qui se trouve dans le fichier voir fichier dans le dossier ./security */
System.setProperty("java.security.policy",System.getProperty("user.dir")+"/bin/security/security.policy");
try {
//cette ligne démarre automatiquement le rmiregistry
java.rmi.registry.LocateRegistry.createRegistry(1099);
//on crée l'objet Addition
Addition Hello = new Addition();
//et on effectue le bind au niveau du service rmi registry
Naming.rebind("rmi://"+java.net.InetAddress.getLocalHost().getHostName()+"/ABC", Hello);
//tout est ok
System.out.println("Addition Server is ready.");
}catch (Exception e) {
//zut ko!!!
System.out.println("Addition Server failed: " + e);
}
}
} |
Regardons maintenant le code source du client RMI :
AdditionClient.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
package rmiclientjfx;
import java.rmi.*;
//l'import ci dessous est trés important, il
//indique a notre client comment est construite
//l'interface AdditionInterface (voir lignes 26 & 28)
import rmiserver.*;
public class AdditionClient {
public static void main (String[] args) {
/*modifier la securité
on récupere le dossier courant de l'application
et on ajoute le dossier ou se trouve le fichier security.policy
IL faut ensuite modifier la propriété java.security.policy et lui affecter
la nouvelle police qui se trouve dans le fichier
voir fichier dans le dossier ./security */
System.setProperty("java.security.policy",System.getProperty("user.dir")+"/bin/security/security.policy");
//on prépare un objet de type remote...
Remote hello;
try {
//On recherche nos objets RMI dans le registre RMI par son nom
hello = Naming.lookup("rmi://"+java.net.InetAddress.getLocalHost().getHostName()+"/ABC");
//si on a affaire a un objet de type AdditionInterface
if (hello instanceof AdditionInterface) {
//alors on appel nos méthodes, ici add
int result=((AdditionInterface)hello).add(9,10);
System.out.println("Result is :"+result);
}
}catch (Exception e) {
System.out.println("HelloClient exception: " + e);
}
}
} |
Bon finalement RMI reste simple vu comme cela, je me pencherai un peu plus tard sur les problèmes de déploiements, les modèles de programmations distribuées, les custom socket Factories, et le Garbage Collector distribué, la sérialisation, et les objets activables. Mais alors bien plus tard!!!
FIN