A Simple Java RMI Tutorial

Java Remote Method Invocation (Java RMI) enables the programmer to create distributed Java technology-based to Java technology-based applications, in which the methods of remote Java objects can be invoked from other Java virtual machines, possibly on different hosts. RMI uses object serialization to marshal and unmarshal parameters and does not truncate types, supporting true object-oriented polymorphism.

Let’s just say RMI is the “older version” of ejb remote. Because in EJB, enterprise beans are made available for remote clients using RMI.

In this example, im trying to create 2 different project, one is the RMI Server and another one is RMI Client.

First is a simple interface, i will use this interface to create invocation methods and implementations. This interface will be on both Server’s and Client’s side.

package com.edw.rmi;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Message extends Remote {
    void sayHello(String name) throws RemoteException;
}

and next is the implementation for my interface, it is exist only on the server’s side. It has to implements my interface and extends to UnicastRemoteObject class.

package com.edw.rmi;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class MessageImpl extends UnicastRemoteObject implements Message {

    public MessageImpl() throws RemoteException {        
    }
    
    @Override
    public void sayHello(String name) throws RemoteException {
        System.out.println("hello "+name);
    }
    
}

And next is creating my server side application. Im running on port 1099 for RMI port.

package com.edw.main;

import com.edw.rmi.MessageImpl;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Main {
    
    private void startServer(){
        try {
            // create on port 1099
            Registry registry = LocateRegistry.createRegistry(1099);
            
            // create a new service named myMessage
            registry.rebind("myMessage", new MessageImpl());
        } catch (Exception e) {
            e.printStackTrace();
        }      
        System.out.println("system is ready");
    }
    
    public static void main(String[] args) {
        Main main = new Main();
        main.startServer();
    }
}

And this is my client’s side application

package com.edw.main;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import com.edw.rmi.Message;

public class Main {
    
    private void doTest(){
        try {
			// fire to localhost port 1099
            Registry myRegistry = LocateRegistry.getRegistry("127.0.0.1", 1099);
			
			// search for myMessage service
            Message impl = (Message) myRegistry.lookup("myMessage");
			
			// call server's method			
            impl.sayHello("edwin");
			
            System.out.println("Message Sent");
        } catch (Exception e) {
            e.printStackTrace();
        }        
    }
    
    public static void main(String[] args) {
        Main main = new Main();
        main.doTest();
    }
}

This is the screenshot of what happen on my netbeans’ console, for my RMI client’s side

and RMI’s server side

and this is my netbeans’ project

While this is what RMI messages looks like

Have fun with RMI 🙂

73 thoughts on “A Simple Java RMI Tutorial”

  1. Hello,

    Thanks a lot for your article, but this code does not work. I guess you should start RMI in console. Right?

  2. Hi edwin . COmpliments for yours interessant tutorials.
    Escuse my bad english.

    I you ask how use the codebase into RMI . I know that it is possible download all class for client from codebase .
    But you can make me a example?????
    tank you .
    mauro

    1. Hi Mauro,
      usually the server side provide interface class to communicate with the client’s side.

  3. Hy Edwin!
    I try to connect to a mysql database, and it’s throwing an exception like this: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

    The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.

    what can I do?

    1. Hi Robert,
      There are lots of reasons why it happened, one of the reason is because mysql close it’s connection. Try to post more detailed exception.

  4. Thanks! This sure makes the difference! The other RMI tutorial only ended up with a connection error.

    Still I am stuck with a small thing. I want to return a String on the remote server in stead of only printing something to the console, but it does not seem to work like that. Do you know how I can return a String?

    Currently I have:
    String hello = conn.sayHello();

    1. Hi Sietse,
      create a method to return String on your RMI Interface
      perhaps something like,

      public interface Message extends Remote {
      String sayHello(String name) throws RemoteException;
      }

  5. Excelente ayuda, me sirvio mucho, apenas inicio con rmi.

    Now i try in english.

    Thanks, it’s helpful,, i’m new in the workd of rmi

  6. Hello, Edwin.

    Thank you for your helpful RMI tutorial.

    Greetings from Cincinnati (600 km SE of Chicago). A long way from Indonesia!

  7. Hello,

    RMI Works on First Run then Connection Refused.

    Error Log
    Connection refused to host: 10.114.154.208;nested exception is: java.net.ConnectException: Connection refused: connectjava.lang.Throwable:
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
    at sun.rmi.transport.Transport$1.run(Unknown Source)

    1. Hi Tarun,
      perhaps your RMI server is shutdown after receiving the first message. Try check whether the server’s application is still alive or not 🙂

  8. hi i have problem error log is below

    java.lang.UnsupportedOperationException: helloedwin
    at com.luk.rmi.MessageImpl.sayHello(MessageImpl.java:19)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:322)
    at sun.rmi.transport.Transport$1.run(Transport.java:177)
    at sun.rmi.transport.Transport$1.run(Transport.java:174)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:273)
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:251)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:160)
    at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
    at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
    at $Proxy0.sayHello(Unknown Source)
    at com.luk.main.Main.doTest(Main.java:14)
    at com.luk.main.Main.main(Main.java:23)

  9. Hej and thanks for a very useful tutorial on java RMI.

    I tried your program and in runs fine. I was just wondering that the Client program terminates when it’s run. But the Server does terminate after execution. How come?

    Best regards

    Javid

    1. I mean to say that the Server program does NOT terminate after execution. Can you explain why?

    2. Hi Javid, it is because the server side runs as a daemon thread.
      It keeps on running just like a webserver 🙂

  10. Thanks for your answer.
    I have another question. I have seen several other java RMI tutorials in the past, where you had to deal with setting the security manager on the client side and setting policy file. And also you had to start rmiregistry process before anything else.

    Was that with old versions of java?

    Looking forward to hearing from you

    Regards

    1. Hi Javid, sorry i missed your question 🙂 .
      Im using java6.0 and i dont need to use security manager because security manager is needed only in the case when RMI downloads code from the remote machine.
      If both client and server use the same classes, it’s not needed.

    1. Hi REMM,
      if you got AccessControlException, SocketPermission
      you need to create a policy file,

      grant {
      // Allow everything, do not use in production
      permission java.security.AllPermission;
      };

      and run the application using -Djava.security.policy parameter.

  11. why I got this error ???

    “no security manager: RMI class loader disabled”

    caused by: on my client interfaces it said, “java.lang.ClassNotFoundException”

    how can I solved this problem ?

    1. Hi Budi,
      it’s because the client interface cannot found the class you wanted, thats why it raise “java.lang.ClassNotFoundException”.

  12. hi , please help me i am stuck due to this error at client side , i have also included the policy file at the build folder but still not solving any problem for me …

    java.security.AccessControlException: access denied (“java.net.SocketPermission” “127.0.0.1:1099” “connect,resolve”)
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:366)
    at java.security.AccessController.checkPermission(AccessController.java:560)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
    at java.lang.SecurityManager.checkConnect(SecurityManager.java:1051)
    at java.net.Socket.connect(Socket.java:574)
    at java.net.Socket.connect(Socket.java:528)
    at java.net.Socket.(Socket.java:425)
    at java.net.Socket.(Socket.java:208)
    at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
    at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:146)
    at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
    at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
    at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
    at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:340)
    at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
    at rmichatapplication.RMIChatApplicationClient.main(RMIChatApplicationClient.java:31)

    1. Hi Ahsan,
      you need to create a policy file to fix it.

      grant {
      permission java.security.AllPermission;
      };

  13. Hi Edwin,

    I am trying to get my head around the use of RMI in Netbeans 7.3. Do I have to deploy the server code to the appliocation server? I assume so, but what is the best way to do that in Netbeans7.3? When deploying Ajax2 WebServices there is a ‘Deploy to Server’ context menu item. Once I have got my code on to the application server do I have to manually start the RMIRegistry, or does it start automatically?

    Regards,

    Stuart

    1. Hi Stuart,
      there are lots of difference between RMI and Webservice. So you cannot compare apple to apple between both of them.
      RMI could alive with or without application server, but to have RMI server run from your applicationserver is a little bit tricky.
      First you need to create a ServletContextListener, and you can call RMI server from inside contextInitialized method
      dont forget to register your ServletContextListener to your web.xml okay 😉

  14. When I use the following:
    System.setSecurityManager(new java.rmi.RMISecurityManager());
    I get the following exception:
    Exception in thread “main” java.security.AccessControlException: access denied (“java.net.SocketPermission” “127.0.0.1:1099” “connect,resolve”)

    I am running the ClientMain application with the following VM option:
    -Djava.security.policy=”C:/Program Files/Java/jdk1.7.0_17/jre/lib/security/java.policy”

    If I comment out the above line then I get the following exception:
    java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
    java.lang.ClassNotFoundException: com.homeserve.rmi.server.impl.Message (no security manager: RMI class loader disabled)

    The java.policy file is default.

    Any ideas to resolve this would be much appreciated.

    Regards,

    Stuart

    1. Hi Stuart, you could remove the securityManager or adding these line of codes to your java.policy (not recommended though)

      grant {
          permission java.security.AllPermission;
      };
      
  15. Como se puede hacer que el servidor mande mensajes al cliente? Es que este solo manda mensajes de cliente a servidor

    1. Hi Ana, RMI is not like a long polling ajax or jswebsocket, where the server can push message to the client. In RMI your client retrieves messages from server. You could fetch your messages periodically from server by using ThreadPool.

  16. Would you help me with this code? I’m trying my Server sends messages to my Client, because only my Client sends the messages to Server. I’m programming with the code “A Simple Java RMI Tutorial”. But, I can’t. Please, help me.

    1. Hi Lola, so you want to send messages from server to client? What you need is like a push ajax or a long polling ajax. A server does not typically push messages to a client, the client retrieves them from the server. The workaround is creating a thread that retrieves messages from server periodically.

    1. Hi Carlo, try something like this,

      grant {
          permission java.security.AllPermission;
      };
      
  17. samsad beagum

    Solution for NoClassFound Exception in RMI Client.
    Case:

    You have the server implementation in one folder and the client in a different folder in a different package.

    Solution:
    In the client folder, create a package with the same name of the package holding the server and keep the server stub (interface) under this package. In client side java file, import the package having the server stub.

  18. vinod bagga

    can be use this example on command prompt….i tried
    but server is not started..so plz let me know, how it will work

    1. Hi Vinod, could you share your error log? Perhaps there is something you’ve missed?

  19. Edwin Thanks a lot. I struggled to run RMI in netbeans and finally you solved my problem…! 😀

  20. Hi edwin I have a small doubt in the code. What does at “127.0.0.1”(host) means. Is there any other way to connect to the server using client…!

    1. Hi Thamizh,
      it is the location of your RMI ip server, you can change it into your server’s ip.

  21. NICE Edwin!!
    This is explains RMI a lot easier then the oracle tutorial. 🙂
    And u dont have to use any commandline compilation-and set-up.
    This deserves a beer (B) !

    By the SayHello methode in the interface, u make the client and server communicate.
    So by creating a ‘Message impl = (Message) myRegistry.lookup(“myMessage”);’ in Main-server u can send data from the server to the client, correct?

    Greetings,
    Be!

    1. Hi Be,
      actually it’s one way trip, not 2 ways
      the client could send data to server but not the other way around, the server side can only reply to client’s request message
      because the server doesnt know what is the client’s ip address.

  22. hello edwin , i have a problems with my rmi program . At server side , my remote interface define a function : public long add(long a,long b) . I want server will send result of adding 2 long a and b . I run server , it’s ok ! I run client , it’s ok but nothing print to the screen , i use : System.out.println(cal.add(5, 7)); . Can you help me ?

  23. Thanks a lot man !!
    🙂
    After looking here and there and after searching so may places At last I found your blog and It’s done without any exception (y)

    really helpful. I bookmark your site and its very helpful that you upload your work with photos 🙂
    thanks again 🙂

  24. I have the concept and my code is perfectly running but can I know why some people are using
    rmic ….(generate stub and skel)
    then rmiregistry

    then run the code

    But I didn’t and its working fine any idea bro

  25. Hi edwin.
    I copied your application but splited the server and client into diferent projects. I have no errors executing it. But it prints nothing than “system is ready”. Client’s execution ends qickly without errors or the expected output!

  26. Hi, your example worked very well, thank you. I have a question, do you know maybe how to handle files instead of strings via RMI ? or maybe do you have another tutorial ? it would be great

    thanks again !

Leave a Reply to Luk Cancel Reply

Your email address will not be published.