IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

avec Java Discussion :

rmi me fait des misères


Sujet :

avec Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 247
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 247
    Par défaut rmi me fait des misères
    Salut à tous.
    Complètement novice en Java, ça fait 2 jour que j'essaye d'implémenter un serveur rmi
    J'ai regardé plusieurs tutos mais rien à faire.

    Mon interface :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    package MonPackage;
    import java.rmi.Remote;
    import java.rmi.RemoteException;
     
    public interface Banzai extends Remote {
        public String QuelServeurPour(String service) throws RemoteException;
    }
    Mon implémentation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    package MonPackage;
    import java.rmi.*;
    import java.rmi.server.*;
     
    public class ServeurNomImpl extends UnicastRemoteObject implements Banzai
    {
        public ServeurNomImpl() throws RemoteException
        {
            super();
        }
        public String QuelServeurPour(String service) throws RemoteException
        {
            return "OK";
        }
        public static void main(String[] args)
        {
            System.setSecurityManager(new RMISecurityManager());
            try{
                  String nomServ = "NOMBIDON";
                Banzai serveur = new ServeurNomImpl();
     
                Naming.rebind(nomServ, serveur);
                System.out.println("Serveur "+nomServ+ " pret");
            }
            catch(Exception e){
                System.out.println("Exception à  l'enregistrement : "+ e);
                System.exit(1);
            }
        }
      }
    J'ai beau tourner, retourner le code, j’obtiens toujours l'erreur suivante déclenchée sur le Naming.rebind :
    Exception à l'enregistrement : java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
    java.lang.ClassNotFoundException: MonPackage.Banzai

  2. #2
    Membre émérite

    Homme Profil pro
    Architecte technique
    Inscrit en
    Juin 2005
    Messages
    588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Juin 2005
    Messages : 588
    Par défaut
    Le serveur de nom (rmiregistry) est-il en tâche de fond ?
    Tu le lances comment ton serveur ?
    Verifies en particulier ton parameters java.rmi.server.codebase...
    Mets tu un truc du genre -Djava.rmi.server.codebase=file://\C:\...\CLASSES\

    Note: ton nom de serveur n'est pas complet. Tu devrais avoir un truc du genre Naming.rebind("rmi://localhost:1099/bidon", serveur);

  3. #3
    Membre émérite

    Homme Profil pro
    Architecte technique
    Inscrit en
    Juin 2005
    Messages
    588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Juin 2005
    Messages : 588
    Par défaut
    Je te propose le code suivant avec le lancement du serveur de nom par ton serveur:

    Server.java
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    import java.rmi.*;
    import java.rmi.server.*;
    import java.rmi.registry.*;
     
    public class Server extends UnicastRemoteObject implements Banzai
    {
        public Server() throws RemoteException
        {
            super();
        }
        public String sayHello() {
            return "Hello, world!";
        }
        public static void main(String[] args)
        {
          try{
               LocateRegistry.createRegistry(1099); 
     
               System.setSecurityManager(new RMISecurityManager());
     
                String nomServ = "rmi://localhost:1099/bidon";
                Hello serveur = new Server();
     
                Naming.rebind(nomServ, serveur);
                System.out.println("Serveur "+nomServ+ " pret");
            }
            catch(Exception e){
                System.out.println("Exception: " + e);                  
             }
        }
      }
    Server.policy
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    grant {
        permission java.security.AllPermission;
    };
    Compilation:
    javac -d classDir Banzai.java Server.java
    Lancement du serveur:
    java -classpath classDir -Djava.rmi.server.codebase=file:classDir/ -Djava.security.policy=Server.policy Server
    Résultat:
    Serveur rmi://localhost:1099/bidon pret
    CTRL^C pour arrêter ton serveur

    Remarques:
    - j'ai supprimé monPackage par simplicité
    - attention danger... aucune restriction de sécurité dans Server.policy => à modifier donc !
    Tu pourraus aussi supprimer System.setSecurityManager(new RMISecurityManager()); & le fichier Server.policy avec le même résultat... Mais je te le déconseille...
    - le code commence par le lancement du serveur de nom sur le port 1099 (port par défaut)
    - l'URL est complète i.e. "rmi://localhost:1099/bidon" (Ce n'est pas obligatoire puisque tout est en local... mais pour moi c'est plus lisible)

    Tu peux aussi générer ton jar
    jar -cvf Server.jar classDir\*
    Puis lancer ton serveur:
    java -classpath classDir -Djava.rmi.server.codebase=file:Server.jar -Djava.security.policy=Server.policy Server

    Et une variante pour ton serveur avec la classe Registry (inutile d'étendre UnicastRemoteObject)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public static void main(String args[]) {        
            try {            
               System.setSecurityManager(new RMISecurityManager());
     
                LocateRegistry.createRegistry(1099); 
                Server obj = new Server();
                Banzai stub = (Banzai) UnicastRemoteObject.exportObject(obj, 0);
     
                Registry registry = LocateRegistry.getRegistry();            
                registry.bind("Banzai", stub);
                System.err.println("Server ready");
            } catch (Exception e) {
                System.err.println("Server exception: " + e.toString());
                e.printStackTrace();
            }
        }
    Je te conseillerais de séparer l'implémanation de ton service du serveur.
    A savoir faire un classe BanzaiImpl et une classe Server.

    Je pense que dans ton cas le stub est bien accessible au serveur MAIS PAS AU rmiregistry (et quelque soit ton codebase => défaut de classpath). L'implémenation RMI a beaucoup évoluée de version en version: depuis JDK1.5. Le codebase n'est alors utilisé que lorsque tu sépares les services du serveur.

    Dur dur de commencer par du RMI !!! Bon courage...

  4. #4
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 247
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 247
    Par défaut
    Désolé pour la réponse tardive, we pascal oblige.

    Je vais regardé cela plus précisément demain si je peux mais déjà,
    Le serveur de nom (rmiregistry) est-il en tâche de fond ?
    Oui, il tourne en tache de fond (double click sur l’exécutable depuis l'explorateur)
    Tu le lances comment ton serveur ?
    Je le lance en faisant exécuter dans l'ide. J'ai aussi essayé deuis la ligne de commande, même en passant un fichier policy en paramètre donnant toutes les permissions (c'est juste pour un petit projet dans le cadre d'un formation, la sécurité n'est pas la priorité)

    Verifies en particulier ton parameters java.rmi.server.codebase...
    Mets tu un truc du genre -Djava.rmi.server.codebase=file://\C:\...\CLASSES\
    Je regarderais

    Note: ton nom de serveur n'est pas complet. Tu devrais avoir un truc du genre Naming.rebind("rmi://localhost:1099/bidon", serveur);
    J'ai "anonymisé" le code que j'ai donné ici. Je regarderais dans mon vrai code si j'ai mis un nom correct.

    .....

    Et une variante pour ton serveur avec la classe Registry (inutile d'étendre UnicastRemoteObject)

    Je te conseillerais de séparer l'implémanation de ton service du serveur.
    A savoir faire un classe BanzaiImpl et une classe Server.
    Les bouts de codes donnés par le prof dans la formation sont comme ça. J'avais tenté de tenté de séparer les choses moi-aussi pour que ce soit plus clair, mais comme ça ne marchais pas et que je ne suis pas javaïste, j'en suis revenu aux exemples donnés par le prof.

    Je pense que dans ton cas le stub est bien accessible au serveur MAIS PAS AU rmiregistry (et quelque soit ton codebase => défaut de classpath). L'implémenation RMI a beaucoup évoluée de version en version: depuis JDK1.5. Le codebase n'est alors utilisé que lorsque tu sépares les services du serveur.
    Pour les tests que j'avais fait avec Netbeam, j'avais pris le tout dernier (1.6, je crois). Maintenant avec Eclipse, je sais pas, j'ai pas eu de jdk à installer (c'est pourtant pas la même machine). Mais j'ai pris la dernière version d'Eclipse.

    Dur dur de commencer par du RMI !!! Bon courage...
    La formation et le projet porte sur les applications clients/serveurs. On a le choix entre plusieurs langages et donc soit une implémentation des sockets, ou une implémentation des RPC/RMI. Comme je suis plutôt Dotnet et C#, j'ai pensé que ça serais plutôt avec Java que je m'en sortirais le mieux (et c'est une occasion de commencer à l'apprendre). Ensuite RMI me semble plus simple à mettre en place que toute une architecture avec des sockets.

  5. #5
    Membre émérite

    Homme Profil pro
    Architecte technique
    Inscrit en
    Juin 2005
    Messages
    588
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Juin 2005
    Messages : 588
    Par défaut
    Citation Envoyé par sevyc64 Voir le message
    Je le lance en faisant exécuter dans l'ide. J'ai aussi essayé deuis la ligne de commande, même en passant un fichier policy en paramètre donnant toutes les permissions (c'est juste pour un petit projet dans le cadre d'un formation, la sécurité n'est pas la priorité)
    Ton exception arrive dans rmiregistry...

    Problème de classloader: le classloader est un problème récurent quand tu développes en Java...

    Deux solutions:
    - lancer rmiregistry depuis ton serveur comme je te l'ai proposé plus haut.
    - lancer rmiregistry depuis l'ide

    Je pense que la première solution te sera suffisante. Pour la deuxième il faut ajouter une tâche ant (attention dans eclipse tu devras installer le plugin ant - dans netbeans c'est déjà pré-installé)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <target name="startRMI" depends="init">
          <exec executable="rmiregistry" dir=" ton classpath ... ">
          </exec>
     </target>
    Bon codage...

    Note: ton environnement IDE (ou DOS) ne correspond pas à la vrai vie.
    A savoir: cela peut sembler bien fonctionner dans ton IDE et ne plus fonctionner correctement une fois déployé. En particulier il faut bien t'assurer que ce sont bien les classes déportées qui sont chargées et non pas des classes locales (on en revient au classpath)...

  6. #6
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 247
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 247
    Par défaut
    Bon, pour le serveur ça semble ok, le nom n'était effectivement pas bon et il fallait lancer le registre rmi depuis le code.

    MAintenant c'est le client qui pose problème.
    J'obtiens systématiquement l'erreur suivante :
    Erreur avec la référence du serveur java.security.AccessControlException: access denied (java.net.SocketPermission 192.168.0.2:1099 connect,resolve)
    Client et serveur sont sur des machines différentes. Je ne vois rien de particulier dans les logs parefeu des 2 machines.

    Mon code client :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
            //Récupération du nom du serveur de nom
            String site = "192.168.0.2:1099/bidon";
     
            String srvNom = "rmi://"+site+"/Banzaï";
            ServeurNom serveur = null;
     
            try{
                LocateRegistry.createRegistry(1099); 
     
                // Mise en place de la connection
                System.setSecurityManager(new RMISecurityManager());
                serveur = (bidon)Naming.lookup(srvNom);
            }
            catch (Exception e) {
                System.out.println("Erreur avec la référence du serveur "+e);
                System.exit(1);
            }
    J'ai essayer avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String srvNom = "rmi://"+site+"/Banzaï";
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String srvNom = "rmi://"+site;
    ça ne change rien

    EDIT : J'utilise aussi mon fichier policy pour le client

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. GetEnvironmentVariable() me fait des misères.
    Par bvsud dans le forum API, COM et SDKs
    Réponses: 6
    Dernier message: 09/10/2014, 20h28
  2. [MySQL] Boucle while qui me fait des misères
    Par joboy84 dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 06/08/2009, 14h40
  3. Mon makefile me fait des misères !
    Par myryad dans le forum C
    Réponses: 2
    Dernier message: 14/04/2008, 21h21
  4. Menu qui fait des misères
    Par kaiser59 dans le forum Mise en page CSS
    Réponses: 5
    Dernier message: 08/12/2006, 20h06
  5. [gcc me fait des misères]
    Par GyZmoO dans le forum Autres éditeurs
    Réponses: 4
    Dernier message: 11/05/2006, 19h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo