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

API standards et tierces Java Discussion :

[RMI] rmic et packages


Sujet :

API standards et tierces Java

  1. #1
    Membre confirmé
    Inscrit en
    Avril 2004
    Messages
    101
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 101
    Par défaut [RMI] rmic et packages
    Bonjour,

    je développe avec des collègues un programme Client/Serveur qui utilise du RMI.

    (Nous utilisons Eclipse 2.1)
    Il y a un projet Client et un projet Serveur.
    Ces deux projets contiennent des class qui se trouvent à le racine du projet, donc dans "default package" sous Eclipse.
    Actuellement le projet fonctionne correctement.

    Pour souhaitons désormais mettre toutes nos class dans diférents packages, ce qui ne pose pas de problème mise à part pour RMI :
    le client ne parvient plus à se connecter au serveur et donne ce message d'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Erreur --java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
            java.lang.ClassNotFoundException: serveur.Entier_Stub (no security manager: RMI cl
    ass loader disabled)
    serveur.Entier étant la méthode "main" du serveur.
    Nous n'avons pas de "security manager", est-ce obligatoire ? et en quoi ça consiste ?

  2. #2
    Membre émérite
    Avatar de divxdede
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    525
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2004
    Messages : 525
    Par défaut
    Je ne maitrise pas trop le secutiry manager, mais il s'occupe nottament de controler les accés via l'introspection. par exemple lorsque tu fais un Field.setAccessible(true);

    Je en suis pas sur que tu en ai besoin. ou disons que l'implementation par défaut de celui de sun convient dans la plupart des cas.

    Es-tu sur que les stubs du client sont en phases avec ton serveur ?

  3. #3
    Membre confirmé
    Inscrit en
    Avril 2004
    Messages
    101
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 101
    Par défaut
    oui j'ai bien recompiler et distribuer les deux stubs.
    Par contre avant je faisait :

    >c:\monProg\rmic Entier

    et maintenant :

    >c:\monProg\rmic serveur.Entier

    pourrait-il s'agir d'un problème de ClassPath ?

  4. #4
    Membre Expert

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Par défaut
    essaye, juste avant le createRegistry() et le rebind() de ton serveur de mettre ces 2 lignes :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            if (System.getSecurityManager() == null)
                System.setSecurityManager(new RMISecurityManager());

  5. #5
    Membre confirmé
    Inscrit en
    Avril 2004
    Messages
    101
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 101
    Par défaut
    on avance... merci

    j'ai rajouté les deux lignes que tu as données et désormais il y a ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    java.security.AccessControlException: access denied (java.net.SocketPermission HostE1 res
    olve)
            at java.security.AccessControlContext.checkPermission(Unknown Source)
    HostE1 étant mon numero de host.
    comment définir les permissions ?

  6. #6
    Membre Expert

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Par défaut
    si c'est un programme java normal (c'est a dire un programme qui n'est pas une applet), tu peux rajouter dans la ligne de commande :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    java ... -Djava.security.policy="chemin/awfullPolicy"
    avec :

    awfullPolicy un fichier contenant juste :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    grant {
            // Allow everything for now
            permission java.security.AllPermission;
    };
    et "chemin" étant le chemin jusqu'au fichier de maniere absolue.
    Par exemple :

  7. #7
    Membre confirmé
    Inscrit en
    Avril 2004
    Messages
    101
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 101
    Par défaut
    ok, le serveur se lance bien sans erreur de securité, par contre j'en reviens au même problème avec le client :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
            java.lang.ClassNotFoundException: serveur.ChatRoomImpl_Stub
            at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)

  8. #8
    Membre confirmé
    Inscrit en
    Avril 2004
    Messages
    101
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 101
    Par défaut
    j'ai dis que c'était le même problème mais pas tout à fait, ce n'est plus une erreur de sécurité mais plutôt un problème de localisation de package.

    j'ai regardé pas mal d'exemple RMI et la démarche est toujours le suivante pour la méthode Naming.lookup :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Naming.lookup("rmi://host:port/class");
    mon problème est que ma classe "class" est dans un package, donc en argument de lookup je met :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Naming.lookup("rmi://host:port/pachage/class");
    et c'est ça qui semble déranger, mais ce doit bien être possible !?

  9. #9
    Membre Expert

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Par défaut
    Ok ;o)

    ca, c'est parce qu'il trouve pas la classe en effet.

    En fait, RMI propose un systeme de chargement de classes "a chaud", lors de l'execution. Il faut donc lui indiquer le chemin jusqu'au classes...

    c'est a dire rajouter cela dans la ligne de commande de lancement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    java ... -Djava.rmi.server.codebase=file:/.../classes/
    Il faut la aussi mettre le chemin absolu, et il ne faut pas oublier non plus de mettre le / a la fin (sinon ca marche pô ;o)

    Ca, c'est pour le cas ou le repertoire /classes/ contient les .class (ou dans ton cas particulier, contient le dossier "serveur" contenant ChatRoomImpl_Stub.class)

    je sais pas trop comment indiquer un .jar dans le codebase, peut etre qu'il suffit d'indiquer le repertoire du .jar, ou plus vraisemblablement, le chemin complet avec le nom du .jar...

    Je ne peux que te conseiller d'essayer au debut d'indiquer un chemin avec les .class décompressés dans un repertoire, et si ca fonctionne d'essayer de le faire fonctionner avec le .jar

  10. #10
    Membre Expert

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Par défaut
    Citation Envoyé par _Eric_
    j'ai regardé pas mal d'exemple RMI et la démarche est toujours le suivante pour la méthode Naming.lookup :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Naming.lookup("rmi://host:port/class");
    mon problème est que ma classe "class" est dans un package, donc en argument de lookup je met :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Naming.lookup("rmi://host:port/pachage/class");
    et c'est ça qui semble déranger, mais ce doit bien être possible !?
    Les packages n'ont rien a voir avec ca ;o)

    En fait, tu doit mettre dans le Naming.lookup() exactement ce que tu as mis dans le rebind() du serveur !

    Le nom n'a aucune importance.

    Tu peux tres bien faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class MaClass... {
    ...
       rebind("rmi://host:post/toto",this);
    ...
    }
    "MaClass" est "toto" n'ont aucun besoin d'etre identique

  11. #11
    Membre confirmé
    Inscrit en
    Avril 2004
    Messages
    101
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 101
    Par défaut
    ah !!! c'est dernière réponse est très intéressante, en effet je voulais absolument mon rebind et lookup avec le nom de package mais comme tu l'as dis c'est inutile !
    je m'endormirai moins bête ce soir.

    Bon sinon j'ai peur de faire un peu le boulet mais ça marche pas le "codebase= truc"

    est-ce que j'ai un problème de syntaxe ? j'ai essayé ça sur le client :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    java -Djava.security.policy=file:/C:\OAP\TEST\Chat\Client/policy.txt -Djava.rmi.server.codebase=file:/C:\OAP\TEST\Chat\Client/classes/ ChatUserImpl
    j'ai essayé également sur le serveur, puis sur les deux, mais c'est toujours pareil : le serveur fonctionne mais pas le client.

  12. #12
    Membre Expert

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Par défaut
    Aucun probleme pour le faire fonctionner chez moi dans un package ;o)

    Le seul probleme, c'est que si tu met les classes du serveur dans un package tu doit mettre les classes du client dans un autre package (j'ai utilisé "client")

    J'ai donc ces fichiers :

    D:\test\client\ChatUser.java
    D:\test\client\ChatUserImpl.java
    D:\test\server\ChatRoom.java
    D:\test\server\ChatRoomImpl.java
    D:\test\server\StartChatRoom.java

    Avec comme contenu :

    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
    package server;
     
    import java.rmi.*;
    import client.*;
     
    public class StartChatRoom {
        public static void main(String [] args) throws Exception {
            try {
                java.rmi.registry.LocateRegistry.createRegistry(1099);
            } catch(Exception e) {
                // un registre RMI est déjà existant.
            }
     
            ChatRoomImpl room = new ChatRoomImpl();
            Naming.rebind("ChatRoom", room);
        }
    }

    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    package server;
     
    import java.rmi.server.*;
    import java.rmi.*;
    import java.util.*;
    import client.*;
     
    public class ChatRoomImpl extends UnicastRemoteObject
                              implements ChatRoom {
    	private Hashtable users = new Hashtable();
     
        public ChatRoomImpl() throws RemoteException {
    	super();
        }
     
        public void subscribe(ChatUser user, String pseudo) throws RemoteException {
            String message = "Connexion de " + pseudo;
            System.out.println(message);
            this.postMessage("ChatRoom", message);
            this.users.put(pseudo, user);
        }
     
        public void unsubscribe(String pseudo) throws RemoteException {
            String message = "Déconnexion de " + pseudo;
            this.users.remove(pseudo);
            System.out.println(message);
            this.postMessage("ChatRoom", message);
        }
     
        public void postMessage(String pseudo, String message) throws RemoteException {
            String fullMessage = pseudo + " >> " + message;
            System.out.println(fullMessage);
     
            Enumeration enum = users.elements();
            while(enum.hasMoreElements()) {
                ChatUser user = (ChatUser)enum.nextElement();
                user.displayMessage(fullMessage);
            }
        }
     
        // Autres définitions si nécessaire
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    package server;
     
    import java.rmi.*;
    import client.*;
     
    public interface ChatRoom extends Remote {
        public void subscribe(ChatUser user, String pseudo) throws RemoteException;
        public void unsubscribe(String pseudo) throws RemoteException;
     
        public void postMessage(String pseudo, String message) throws RemoteException;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    package client;
     
    import java.rmi.*;
    import server.*;
     
    public interface ChatUser extends Remote {
        public void displayMessage(String message) throws RemoteException;
    }
    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    package client;
     
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.rmi.*;
    import java.rmi.server.*;
    import server.*;
     
    public class ChatUserImpl extends UnicastRemoteObject implements ChatUser {
        private ChatRoom room = null;
        private String title = "Logiciel de discussion en ligne";
        private String pseudo = null;
     
        private JFrame window = new JFrame(this.title);
        private JTextArea txtOutput = new JTextArea();
        private JTextField txtMessage = new JTextField();
        private JButton btnSend = new JButton("Envoyer");
     
        public ChatUserImpl() throws RemoteException {
    		super();    // Appel au constructeur de UnicastRemoteObject
    		try {
    			this.room = (ChatRoom)Naming.lookup("rmi://localhost/ChatRoom");
    		} catch(Exception e) {
    			System.err.println("Salle de discussion non localisée");
    			System.exit(0);
    		}
            this.createIHM();
            this.requestPseudo();
        }
     
        public void createIHM() {
            // Assemblage des composants
            JPanel panel = (JPanel)this.window.getContentPane();
    	JScrollPane sclPane = new JScrollPane(txtOutput);
    	panel.add(sclPane, BorderLayout.CENTER);
            JPanel southPanel = new JPanel(new BorderLayout());
            southPanel.add(this.txtMessage, BorderLayout.CENTER);
            southPanel.add(this.btnSend, BorderLayout.EAST);
            panel.add(southPanel, BorderLayout.SOUTH);
     
            // Gestion des évènements
            window.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    window_windowClosing(e);
                }
            });
            btnSend.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    btnSend_actionPerformed(e);
                }
            });
    	txtMessage.addKeyListener(new KeyAdapter() {
    	    public void keyReleased(KeyEvent event) {
    		if (event.getKeyChar() == '\n')
    		    btnSend_actionPerformed(null);
    	    }
    	});
     
            // Initialisation des attributs
            this.txtOutput.setBackground(new Color(220,220,220));
    	this.txtOutput.setEditable(false);
            this.window.setSize(500,400);
            this.window.setVisible(true);
            this.txtMessage.requestFocus();
        }
     
        public void requestPseudo() throws RemoteException {
            this.pseudo = JOptionPane.showInputDialog(
                    this.window, "Entrez votre pseudo : ",
                    this.title,  JOptionPane.OK_OPTION
            );
            if (this.pseudo == null) System.exit(0);
          this.room.subscribe(this, this.pseudo);
        }
     
        public void window_windowClosing(WindowEvent e) {
    		try {
    			room.unsubscribe(pseudo);
    		} catch(Exception exc) {
    			System.err.println("Desinscription impossible");
    		}
    		System.exit(-1);
        }
     
        public void btnSend_actionPerformed(ActionEvent e) {
    		try {
    			this.room.postMessage(this.pseudo, this.txtMessage.getText());
    		} catch (Exception exception) {
    			System.err.println("Envoie message impossible");
    		}
    		this.txtOutput.append(this.txtMessage.getText() + "\n");
    		this.txtMessage.setText("");
            this.txtMessage.requestFocus();
        }
     
        public void displayMessage(String message) throws RemoteException {
    		this.txtOutput.append(message + "\n");
    		this.txtOutput.moveCaretPosition(this.txtOutput.getText().length());
        }
     
        public static void main(String[] args) throws RemoteException {
            new ChatUserImpl();
        }
    }
    Ensuite, je me met dans une fenetre MS-DOS, et je tape :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    C:\>d:
    D:\>cd test
    D:\test>javac client\*.java
    D:\test>javac server\*.java
    D:\test>rmic client.ChatUserImpl
    D:\test>rmic server.ChatRoomImpl
    D:\test>start java servert.StartChatRoom
    D:\test>java client.ChatUserImpl
    et tout fonctionne a peu pres correctement (sous reserve des "bug" du programme original ;o)

  13. #13
    Membre confirmé
    Inscrit en
    Avril 2004
    Messages
    101
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 101
    Par défaut
    bonjour,

    en effet ça fonctionne
    Merci d'avoir passé du temps sur mon problème.

    Tchaô

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

Discussions similaires

  1. [RMI] L'outil rmic ne me génère pas le skeleton
    Par verbose dans le forum API standards et tierces
    Réponses: 5
    Dernier message: 17/07/2008, 12h27
  2. [RMI] rmic ne marche pas
    Par kha_yassine dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 03/11/2007, 10h57
  3. [RMI] RMIC + Package
    Par gmonta dans le forum API standards et tierces
    Réponses: 5
    Dernier message: 04/05/2005, 09h25
  4. [RMI]comment creer les stubs sous eclipse(lancement de rmic)
    Par juflata dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 22/06/2004, 13h51
  5. [rmi] Comment exécuter rmic sous Jbuilder9
    Par ensi dans le forum JBuilder
    Réponses: 4
    Dernier message: 27/03/2004, 09h09

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