This discussion is archived
14 Replies Latest reply: Nov 3, 2010 2:37 AM by EJP RSS

RMI Problem

808398 Newbie
Currently Being Moderated
Hi all,

I've been trying to get an RMI program working and I have reached my limit of knowledge on how to fix it. I will attach my code. My first question is, is my server even running. At the moment i use Netbeans to run my program and i'm assuming that netbeans looks after all the nitty gritty in the background but to be honest i don't believe this is correct. I try to follow examples as best i can but I run into errors one after the other.

My first problem is the sever code.
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package server;

/**
 *
 * @author Mike
 */
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

public class MessageServer {

    public static void main(String args[]) {

        try {
         Message obj = new MessageImpl();
         System.out.println("here3");
         Naming.rebind( "Message_Server",obj);
         System.out.println("Server in Registry");
         }catch (Exception e)  {
             System.out.println ("Message_Server error: " +
                    e.getMessage());
         }



    }
}
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package server;

/**
 *
 * @author Mike
 */
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;


public class MessageImpl extends UnicastRemoteObject implements Message {

    private String message;

    public MessageImpl() throws RemoteException{
        super();
    }
    public String getMessage() throws RemoteException {
        return message;
    }

    public void setMessage(String message) throws RemoteException {
        this.message = message;
    }
} 
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package server;

/**
 *
 * @author Mike
 */
import java.rmi.Remote;
import java.rmi.RemoteException;


public interface Message extends Remote{

    public String getMessage() throws RemoteException;

    public void setMessage(String message) throws RemoteException;
}
I start the rmiregistry and run this through the command console and bizarrely after several attempts to get it running it eventually will. For example, at the moment the code tells me that the sever is running. If however i restart my computer and go through the exact same process again it will not run first time.


Can anyone tell me if what i am doing is correct? Also does any one know how to run this in a netbeans project or do i just have to run it manually in the command console.

Any help is greatly appreciated!

Michael
  • 1. Re: RMI Problem
    jtahlborn Expert
    Currently Being Moderated
    are you getting any sort of exception or other failure indication?
  • 2. Re: RMI Problem
    808398 Newbie
    Currently Being Moderated
    Yea, at the time of my first post the code was telling me that the server was running. At this moment, after restarting my pc, its telling me this:
    Message_Server error: RemoteException occurred in server thread; nested exception is: 
            java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
            java.lang.ClassNotFoundException: server.Message
    Mike
  • 3. Re: RMI Problem
    jtahlborn Expert
    Currently Being Moderated
    yeah, that's what i was guessing. you need to start the rmiregistry with the necessary classes on its classpath (easy), or setup remote classloading (difficult and usually unnecessary). The rmiregistry needs access to any classes in the remote API of the service (in this case, the Message class and any classes to which it refers).
  • 4. Re: RMI Problem
    808398 Newbie
    Currently Being Moderated
    As a bit of an update, if i give up on Netbeans and run the program the manual command prompt way, according to my code the server is running.

    The steps i use are: 1. javac server/*.java
    2. start rmiregistry (it has to be in this order otherwise i get the error as above, maybe someone can explain why)
    3. start java server.MessageServer


    If i do it this way the program (seems) to execute properly.


    Is the simple answer just to not use Netbeans and just to use the command prompt way?

    Mike
  • 5. Re: RMI Problem
    808398 Newbie
    Currently Being Moderated
    I kept coding under the assumption that my server is running correctly. I came across this error and do not know what it means:
    $Proxy0 cannot be cast to client.Message
    java.lang.ClassCastException: $Proxy0 cannot be cast to client.Message
            at client.MessageClient.<init>(MessageClient.java:33)
            at client.MessageClient$3.run(MessageClient.java:128)
            at java.awt.event.InvocationEvent.dispatch(Unknown Source)
            at java.awt.EventQueue.dispatchEvent(Unknown Source)
            at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
            at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
            at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
            at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
            at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
            at java.awt.EventDispatchThread.run(Unknown Source)
    Here is my code:
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    
    package client;
    
    /**
     *
     * @author Mike
     */
    import java.rmi.Remote;
    import java.rmi.RemoteException;
    
    
    public interface Message extends Remote{
    
        public String getMessage() throws RemoteException;
    
        public void setMessage(String message) throws RemoteException;
    }
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    
    package client;
    
    /**
     *
     * @author Mike
     */
    import java.rmi.Naming;
    import java.rmi.Remote;
    import java.rmi.RemoteException;
    import java.rmi.registry.LocateRegistry;
    import java.rmi.registry.Registry;
    import java.rmi.server.UnicastRemoteObject;
    
    public class MessageClient extends javax.swing.JFrame {
    
        private Message client;
        Remote remoteObject;
        String name = "rmi://127.0.0.1/MESSAGE_SERVER";
    
        /** Creates new form MessageClient */
        public MessageClient() {
    
    
            try
            {
    
                Registry registry = LocateRegistry.getRegistry("localhost");
               Message client = (Message) registry.lookup("Message_Server");
                System.out.println(client.getMessage());
            } catch (Exception e) {
                System.out.println("Error Finding MESSAGE_SERVER\n");
                System.out.println(e.getMessage());
                e.printStackTrace();
            }
    
        }
    
        /** This method is called from within the constructor to
         * initialize the form.
         * WARNING: Do NOT modify this code. The content of this method is
         * always regenerated by the Form Editor.
         */
        @SuppressWarnings("unchecked")
        // <editor-fold defaultstate="collapsed" desc="Generated Code">
        private void initComponents() {
    
            lblMessage = new javax.swing.JLabel();
            cmdGet = new javax.swing.JButton();
            txtMessage = new javax.swing.JTextField();
            cmdSetMessage = new javax.swing.JButton();
    
            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    
            cmdGet.setText("Get Message");
            cmdGet.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    cmdGetActionPerformed(evt);
                }
            });
    
            cmdSetMessage.setText("Set Message");
            cmdSetMessage.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    cmdSetMessageActionPerformed(evt);
                }
            });
    
            javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
            getContentPane().setLayout(layout);
            layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addGap(20, 20, 20)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                        .addComponent(lblMessage, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(cmdGet, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addGap(32, 32, 32)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addComponent(txtMessage)
                        .addComponent(cmdSetMessage, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addContainerGap(160, Short.MAX_VALUE))
            );
            layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                        .addComponent(txtMessage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(lblMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(cmdGet)
                        .addComponent(cmdSetMessage))
                    .addContainerGap(231, Short.MAX_VALUE))
            );
    
            pack();
        }// </editor-fold>
    
        private void cmdGetActionPerformed(java.awt.event.ActionEvent evt) {
           try {
                lblMessage.setText(client.getMessage());
            } catch (RemoteException ex) {
                System.out.println("Error Getting Message");
            }
        }
    
        private void cmdSetMessageActionPerformed(java.awt.event.ActionEvent evt) {
            try {
                client.setMessage(txtMessage.getText());
            } catch (RemoteException ex) {
                System.out.println("Error Setting Message");
            }
        }
    
        /**
         * @param args the command line arguments
         */
        public static void main(String args[]) {
            java.awt.EventQueue.invokeLater(new Runnable() {
    
                public void run() {
                    new MessageClient().setVisible(true);
                }
            });
        }
        // Variables declaration - do not modify
        private javax.swing.JButton cmdGet;
        private javax.swing.JButton cmdSetMessage;
        private javax.swing.JLabel lblMessage;
        private javax.swing.JTextField txtMessage;
        // End of variables declaration
    }
    Any help is really appreciated,

    Mike
  • 6. Re: RMI Problem
    jtahlborn Expert
    Currently Being Moderated
    My guess would be that you are compiling the Message class into 2 different packages. don't do that.
  • 7. Re: RMI Problem
    808398 Newbie
    Currently Being Moderated
    This is just another part of RMI that confuses me. I thought that there has to be an interface class in both packages, one for the server and one for the client. Is this not correct?

    Mike
  • 8. Re: RMI Problem
    jtahlborn Expert
    Currently Being Moderated
    mike wrote:
    This is just another part of RMI that confuses me. I thought that there has to be an interface class in both packages, one for the server and one for the client. Is this not correct?
    No, this is not correct. you generally have a "remote API" which consists of the remote interface(s) and any transfer objects (other Serializable objects to be transferred). this would be compiled into one jar and shared between the client and server. then, the client and server would each have their own set of implementation classes which are compiled against the shared remote API.
  • 9. Re: RMI Problem
    808398 Newbie
    Currently Being Moderated
    Is there any chance you could explain this to me. I have a program that is in two packages arith2_1 and arith2_2. In these packages there is Arith.java, ArithImpl.java and ArithServer.java, and Arith.java and ArithClient.java respectively. This program runs as it should at the command line. I've used this example as the "blueprint" to my own program. Can you explain why the arith program works but mine does not?

    My apologies for basically asking you to fix my code but i have honestly reached my limit at understanding this.

    Michael

    arith2_1

    Arith.java
    package arith2_1;
    
    public interface Arith extends java.rmi.Remote 
    {
         int[] add (int a[],int b[])
                     throws java.rmi.RemoteException;
    }
    ArithImpl.java
    package arith2_1;
    import java.rmi.*;
    import java.rmi.server.*;
    
    public class ArithImpl extends UnicastRemoteObject implements Arith{
          private String name;
          public ArithImpl (String s)
             throws RemoteException {
                 // super();
                  name =s;
    }
    public int[] add (int a[], int b[])
      throws RemoteException {
            int c[]= new int [10];
            for ( int i=0;i<10;i++)
                  c[i] = a[i] +b;
    System.out.println ( "Hello arith");
    return c;
    }
    }


    ArithServer.java
    /*ArithServer.java*/
    package arith2_1;
    import java.rmi.*;
    public class ArithServer {
    
      //final static String SVR= "rmi://localht:2200/";
       public static void main( String argv[]) {
           System.out.println("here");
             
          // RMISecurityManager sm =
            //               new RMISecurityManager();
        
          //System.setSecurityManager(new RMISecurityManager());
          System.out.println("here2");
          try {
             Arith obj = new ArithImpl("ArithServer");
             System.out.println("here3");
             Naming.rebind( "ArithServer",obj);
             System.out.println("Server in Registry");
             }catch (Exception e)  {
                 System.out.println ("ArithImpl error: " +
                        e.getMessage());
             }
       }
    }
      
    arith2_2

    Arith.java
    package arith2_2;
    
    public interface Arith extends java.rmi.Remote 
    {
         int[] add (int a[],int b[])
                     throws java.rmi.RemoteException;
    }
    ArithClient.java
    package arith2_2;
    import java.rmi.*;
    //import java.net.*;
    public class ArithClient {
    
    
      public static void main(String argv[])
         {
                     int a[]={1,2,3,4,5,6,7,8,9,10};
                     int b[]={1,2,3,4,5,6,7,8,9,10};
                     int result[] = new int[10];
              
              //System.setSecurityManager( new RMISecurityManager());
                     
              try  
              {
                             /*get reference to server from
                           server’s registry*/
                             Arith obj = (Arith) Naming.lookup( "ArithServer");
                            result= obj.add(a,b);
                       
              }
              catch (Exception e)
              {
                             System.out.println(e.getMessage());
                              e.printStackTrace();
                      }
    
    
      System.out.println("The Sum = ");
      for (int i=0;i < result.length;i++)
            System.out.print(result[i]+"  ");
      System.out.println();
      }
    }
  • 10. Re: RMI Problem
    EJP Guru
    Currently Being Moderated
    As he said, you have to have one remote interface class that both the server and the client are using. Two interfaces with the same name and same methods in different packages are two interfaces, not one. You may like to create a third package containing the stuff that is common to both server and client, i.e. the remote interface for a start, and any application-specific classes that it refers to, and so on until closure.
  • 11. Re: RMI Problem
    808398 Newbie
    Currently Being Moderated
    That's brilliant. I put the interfaces into a different package and it worked perfectly. As just a matter of interest can you tell me why having the interface in two packages (as of the Arith example above) worked?


    Michael
  • 12. Re: RMI Problem
    EJP Guru
    Currently Being Moderated
    You would have to show me your directory layout and your commands first, and the contents of those directories at the time you did the test. It certainly shouldn't work.
  • 13. Re: RMI Problem
    808398 Newbie
    Currently Being Moderated
    For the arith example the directory layout was:

    ArithExample
    
                      - arith2_1                   -arith2_1
                         -Arith.java                  -Arith.java
                         -ArithImpl.java             -ArithClient.java
                         -ArithServer.java 
    
    
    At the command line i executed it this way:
    
    cd ArithExample
    
    javac  arith2_1/*.java
    start rmiregistry
    start java -Djava.security.policy=arith2_1/policy arith2_1.ArithServer
    
    
    javac arith2_2/*.java
    java -Djava.security.policy=arith2_2/policy arith2_2.ArithClient
    Edited by: mike on 29-Oct-2010 01:37
  • 14. Re: RMI Problem
    EJP Guru
    Currently Being Moderated
    Cannot reproduce. I get:
    $Proxy0 cannot be cast to arith2_2.Arith
    java.lang.ClassCastException: $Proxy0 cannot be cast to arith2_2.Arith
            at arith2_2.ArithClient.main(ArithClient.java:30)
    The Sum =
    0  0  0  0  0  0  0  0  0  0
    as expected. You must have had other .class files lying around.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points