Bonsoir,

Il existe deux manière d'utiliser la classe UnicastRemoteObject pour créer un stub.

Une première solution consiste à créer une classe héritant de UnicastRemoteObject et implémentant Remote.
L'autre solution consiste à utiliser la méthode static UnicastRemoteObject.exportObject() sur une classe implémentant Remote.
L'avantage de la seconde est qu'elle évite l'héritage multiple.

Mais j'aimerais mieux comprendre comment le stub est retourné vers le client entre les deux solutions proposées.
En effet, d'après mon enseignant, la première solution instancie le stub et la référence de la classe, mais utilise l'instance de la classe lorsqu'on est sur le serveur, et retourne "automatiquement" le stub vers le client lorsque celui-ci l'utilise à distance ("la JVM reconnait que c'est un Remote, donc retourne le stub") :

Solution n°1 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
public interface MyRemoteInterface extends Remote{ /**/ }
 
public class MyRemoteImplementation 
    extends UnicastRemoteObject 
    implements MyRemoteInterface { /**/ }
 
// Une méthode de l'implémentation RMI
public MyRemoteInterface getMyRemoteInterface() throws RemoteException {
    MyRemoteImplementation ri = new MyRemoteImplementation(); 
    // instance MyRemoteImplementation ET du stub
    return ri; // "ri" n'est PAS un stub
}
/* @return : Le client récupère le stub de "ri" même si "ri" n'est pas un stub */
Pour cette première solution, le stub n'est pas directement accessible coté Serveur. Par contre la JVM retourne un stub au client.



Solution n°2 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
public interface MyRemoteInterface extends Remote{ /**/ }
 
public class MyRemoteImplementation 
    // extends UnicastRemoteObject 
    implements MyRemoteInterface { /**/}
 
// Une méthode de l'implémentation RMI
public MyRemoteInterface getMyRemoteInterface() throws RemoteException {
    MyRemoteImplementation ri = (MyRemoteImplementation) UnicastRemoteObject.exportObject(new MyRemoteImplementation(), 0); 
    // instanciation de ri, puis exportObject retourne son stub
    return ri; // "ri" est un stub !
}
/* @return : Ici on retourne directement "ri" qui est un stub */
Pour la seconde solution, le stub est directement accessible niveau Serveur, si on utilise "ri" au niveau du Serveur, on risque d'effectuer des appels réseaux vers le serveur lui-même à cause du stub.


La première solution me parait "magique" -> On instancie la classe et le stub implicitement : le serveur retourne l'instance "ri", mais le client récupère le stub de MyRemoteImplementation.
Tandis que la seconde me parait plus logique car on récupère directement le stub de MyRemoteImplementation et on le retourne au client sans apporter de modification.



  • Pour le type de retour, comment la JVM sait qu'elle doit récupérer le stub ou pas en fonction de la première solution et de la seconde solution ?
  • Comment est-ce que la JVM agit en fonction de ces deux solutions ? (reformulation de la question précédente)



Merci et bonne soirée.