RMI compréhension

Conception de logiciels Intranet : patrons et canevas

Moderators: douinj, graffiop

Post Reply
guill_f58
Posts: 68
Joined: 10 Oct 2020 19:42

RMI compréhension

Post by guill_f58 » 10 May 2022 9:55

Bonjour à tous, j'ai quelques interrogations sur le fonctionnement de RMI.

Le ClientRMI et le ServeurRMI doivent se partager des interfaces voir des classes. Dans nos exercices, elles peuvent être mise à disposition par l'un ou l'autre.
Quand je veux compiler une classe comme "Client1" par exemple, celle-ci n'a pas la référence de "AffichageLointain1". Comment cela se fait-il que l'on puisse la compiler ?

Aussi, dans une situation réelle avec 2 ordinateurs : 1 client et 1 serveur.
Le Client doit-il avoir au minimum les interfaces en commun sur son poste ? Si ce n'est pas le cas, comment fait il pour compiler ? puisque son seul moyen d'y avoir accès est via la ligne de commande "codebase" qui pointe vers les ressources mais qu'il faut compiler avant ?

-------------------------------------------------------
Si je reprends un exemple du cours, par exemple le n°4 (runServeur4, Client4 et runOnce) :
runOnce :

Code: Select all

start rmiregistry -J-Djava.rmi.server.useCodebaseOnly=false 
start java -cp . ServeurWeb8086
 
Ligne 1 : rend possible pour l'un des deux parties (Client/Serveur) de spécifier l'emplacement ou se trouvera les fichiers communs. En gros, on peut utiliser la commande codebase=file://, http:// ...
Et exécute le registre RMI qui permet de communiquer entre Client et Serveur.
Ligne 2 : on exécute au passage un serveur web local pour l'exemple qui nous permettra de spécifier un codebase=http://.
Important à comprendre pour ce serveurWeb, ce dernier est présent à la base de l'exemple dans le dossier "exemples_cours_rmi_bluej".
Par conséquent, quand on écrit "...codebase=http://localhost:8086/", c'est comme si on était dans "exemples_cours_rmi_bluej".
Libre à nous ensuite de spécifier un dossier comme ClientsRMI, InterfacesRMI, ...

PETITE INTERROGATION : dans une situation réelle, le serveur tout comme le client doivent exécuter rmiregistry ?

runServeur4 :

Code: Select all

start java -cp ../interfacesRMI.jar;. -Djava.rmi.server.useCodebaseOnly=false -Djava.rmi.server.codebase=http://localhost:8086/interfacesRMI.jar -Djava.rmi.server.logCalls=true -Djava.security.policy=java.policy Serveur4
On doit spécifier le classpath en cours : "java -cp (../interfacesRMI.jar;) ."
Pour faire fonctionner Serveur4, on doit mettre à disposition le package "../interfacesRMI.jar;" qui se trouve dans le dossier précédent de notre cp.
Je crois que "-Djava.rmi.server.useCodebaseOnly=false" ne sert à rien car on l'a déjà spécifié avec runOnce (quand j'enlève la commande, cela semble marcher).
Ensuite "-Djava.rmi.server.codebase=http://localhost:8086/interfacesRMI.jar" me permet de mettre à disposition pour le Client4 des interfaces côté serveur, en l'occurrence il s'agit de "StartService".
Puis "-Djava.rmi.server.logCalls=true" est le mode bavard.
Suit ensuite "-Djava.security.policy=java.policy" qui spécifie la politique de sécurité du serveur avec un fichier "java.policy" qui se trouve au niveau du cp.
Pour finir, on exécute "Serveur4.class".

A ce moment là, on a 1 serveur web (local), 1 registre RMI commun pour le client/serveur (local, à titre d'exemple), la mise à disposition sur le serveur web des interfaces nécessaires aux clients et le côté serveurRMI.

Maintenant côté client :
RunClient4 :

Code: Select all

java -cp ../interfacesRMI.jar;. -Djava.rmi.server.useCodebaseOnly=false -Djava.security.policy=java.policy -Djava.rmi.server.codebase=http://localhost:8086/clientsRMI/ Client4
Alors techniquement, je ne devrais pas avoir besoin de "../interfacesRMI.jar;" vu qu'il a été spécifié côté serveur. Mais quand j'enlève cette partie, j'ai "java.lang.NoClassDefFoundError: StartService". Je ne comprends pas bien pourquoi.
Même remarque pour "-Djava.rmi.server.useCodebaseOnly=false" et "-Djava.security.policy=java.policy".
Ensuite "-Djava.rmi.server.codebase=http://localhost:8086/clientsRMI/" permet de mettre à disposition le dossier "clientsRMI" présent sur le serveur et qui contient Horloge4 et Compteur4.

A ce moment là, en plus j'ai la mise à disposition des classes client utiles côté serveur.
-------------------------------------------------------

Autre interrogation, quand on utilise uniquement ce code par exemple sur le Serveur4 :
"System.setSecurityManager(new RMISecurityManager());" et "Naming.rebind()".

C'est possible car a "extends UnicastRemoteObject" donc pas besoin UnicastExportObject ...
Ensuite, c'est aussi possible car on a spécifier les informations dans les fichiers .bat ? (java.policy, ...)


Voilà, j'aimerais surtout une clarification sur ce qui est commun entre les deux postes, l'histoire du "./interfacesRMI.jar;" alors qu'il est déjà dispo/spécifier sur le serveur et la compilation qui n'est pas possible quand la classe ou l'interface n'existe pas sur le poste.

douinj
Posts: 462
Joined: 18 Mar 2009 15:46

Re: RMI compréhension

Post by douinj » 10 May 2022 10:42

Bonjour, je vais vous répondre en plusieurs fois ...
Le Client doit-il avoir au minimum les interfaces en commun sur son poste ? Si ce n'est pas le cas, comment fait il pour compiler ?
C'est bien le cas, il le faut cf le CLASSPATH, ou bien un .jar partagé
codebase=file ....
Attention là vous en êtes à l'exécution, par exemple lors de la construction du proxy (cf. rmiregistry)
PETITE INTERROGATION : dans une situation réelle, le serveur tout comme le client doivent exécuter rmiregistry ?
Non seulement la machine qui possède le service, rmi rend obligatoire cette présence sur la machine qui délivre le service + fichier dit de sécurité

à suivre....

douinj
Posts: 462
Joined: 18 Mar 2009 15:46

Re: RMI compréhension

Post by douinj » 10 May 2022 10:45

Alors techniquement, je ne devrais pas avoir besoin de "../interfacesRMI.jar;" vu qu'il a été spécifié côté serveur. Mais quand j'enlève cette partie, j'ai "java.lang.NoClassDefFoundError: StartService". Je ne comprends pas bien pourquoi.
2 étapes compilation et exécution

1) à la compilation il vous faut les .class
2) les .class sont nécessaires afin de sérialiser, désérialiser ...

nous ferons une révision ensemble si névessaire

bon rmi

guill_f58
Posts: 68
Joined: 10 Oct 2020 19:42

Re: RMI compréhension

Post by guill_f58 » 10 May 2022 12:48

douinj wrote:
10 May 2022 10:45
Alors techniquement, je ne devrais pas avoir besoin de "../interfacesRMI.jar;" vu qu'il a été spécifié côté serveur. Mais quand j'enlève cette partie, j'ai "java.lang.NoClassDefFoundError: StartService". Je ne comprends pas bien pourquoi.
2 étapes compilation et exécution

1) à la compilation il vous faut les .class
2) les .class sont nécessaires afin de sérialiser, désérialiser ...

nous ferons une révision ensemble si névessaire

bon rmi
Bonjour, alors si je récapitule un peu :
-Il faut obligatoirement avoir la présences des interfaces sur le serveur et chez le client.
-Il faut obligatoirement avoir "../interfacesRMI.jar;" et "-Djava.rmi.server.codebase=http://localhost:8086/interfacesRMI.jar" car
=> le 1er permet de compiler Serveur4 ou Client4
=> le 2ème qui est nécessaire pour le "marshalling". C'est à dire pour rendre les interfaces compréhensibles à travers les échanges RMI.

C'est un peu spécial de devoir le spécifier deux fois pour deux tâches différentes.

C'est curieux que BlueJ n'est pas a "importer" les interfaces pour compiler. De mon côté, Intellj m'y oblige.

Post Reply