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 :)

Google+

73 Comments

Ilya

about 5 years ago

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

Reply

Ilya

about 5 years ago

I am sorry, your example works. Problem is in my implementation.

edwin

about 5 years ago

Hi Ilya, yes Thank you for your comment :)

alpesh

about 5 years ago

(Y) thanks.......... it is helpful

Reply

edwin

about 5 years ago

Thank you alpesh, glad it could help

mauro

about 5 years ago

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

Reply

edwin

about 5 years ago

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

Robert

about 5 years ago

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?

Reply

edwin

about 5 years ago

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.

Eric

about 5 years ago

Thanks. This saved me a lot of trouble.

Reply

edwin

about 5 years ago

Hi Eric, glad it can help.

Sietse

about 5 years ago

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();

Reply

edwin

about 5 years ago

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; }

lupe

about 5 years ago

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

Reply

edwin

about 5 years ago

Hi Lupe thanks, glad it could help :)

Tony

about 5 years ago

Hello, Edwin. Thank you for your helpful RMI tutorial. Greetings from Cincinnati (600 km SE of Chicago). A long way from Indonesia!

Reply

edwin

about 5 years ago

Hi Tony, greetings from Indonesia. Thank you for your comment. :)

joko

about 5 years ago

hello edwin,good article.very helpfull tutorial.greeting from malang indonesia. :-D

Reply

edwin

about 5 years ago

Hi Joko, glad it can help :)

tarun

about 5 years ago

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)

Reply

edwin

about 5 years ago

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 :)

Luk

about 5 years ago

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)

Reply

Luk

about 5 years ago

ok nvm implementation error ;] big thx for the tutorial :)

Reply

edwin

about 5 years ago

Hi Luk, glad it can help :)

Javid

about 5 years ago

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

Reply

Javid

about 5 years ago

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

edwin

about 5 years ago

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

Javid

about 5 years ago

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

Reply

edwin

about 5 years ago

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.

REMM

about 5 years ago

what about the security problems and policy file it wouldn't be complete to test the app.

Reply

edwin

about 5 years ago

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.

Budi Oktaviyan

about 5 years ago

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 ?

Reply

edwin

about 5 years ago

Hi Budi, it's because the client interface cannot found the class you wanted, thats why it raise "java.lang.ClassNotFoundException".

Ahsan

about 5 years ago

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)

Reply

edwin

about 4 years ago

Hi Ahsan, you need to create a policy file to fix it. grant { permission java.security.AllPermission; };

Stuart

about 4 years ago

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

Reply

edwin

about 4 years ago

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 ;)

Stuart

about 4 years ago

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

Reply

edwin

about 4 years ago

Hi Stuart, you could remove the securityManager or adding these line of codes to your java.policy (not recommended though) [code] grant { permission java.security.AllPermission; }; [/code]

Ana

about 4 years ago

Como se puede hacer que el servidor mande mensajes al cliente? Es que este solo manda mensajes de cliente a servidor

Reply

edwin

about 4 years ago

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.

Lola

about 4 years ago

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.

Reply

edwin

about 4 years ago

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.

Carlo

about 4 years ago

Hi Edwin, Could you provide a tutorial on how to configure the policy file? Please?

Reply

edwin

about 4 years ago

Hi Carlo, try something like this, [code] grant { permission java.security.AllPermission; }; [/code]

Carlo

about 4 years ago

Never mind, got it to work already. Thank you for the awesome tutorial! :-D

Reply

edwin

about 4 years ago

Hi Carlo, glad it can help :)

Lola

about 4 years ago

Ok, ok... how can make this method? Please help with the code.

Reply

samsad beagum

about 4 years ago

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.

Reply

edwin

about 4 years ago

Cool, thanks Samsad.

vinod bagga

about 4 years ago

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

Reply

edwin

about 4 years ago

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

Thamizh

about 4 years ago

Edwin Thanks a lot. I struggled to run RMI in netbeans and finally you solved my problem...! :-D

Reply

Thamizh

about 4 years ago

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...!

Reply

edwin

about 4 years ago

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

Jono

about 4 years ago

Thanks Edwin for the tutorial. Simply helpful for guidance near deadline :)

Reply

edwin

about 4 years ago

Glad it can help, Jono :)

Be

about 4 years ago

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!

Reply

edwin

about 4 years ago

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.

long

about 4 years ago

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 ?

Reply

edwin

about 4 years ago

Hi Long, it supposed to work, do you have any exceptions happen on your server side?

Vikas

about 4 years ago

Thank you Sir...

Reply

edwin

about 4 years ago

Glad it could help :)

Nethanz

about 3 years ago

can i know how to send a file using rmi ... plz help me find it i try lot of ways but i cant find it thank you

Reply

edwin

about 3 years ago

Hi Nethanz, you can convert the file into byte[] and send it directly.

Enam Ahmed

about 3 years ago

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 :)

Reply

Thilina

about 3 years ago

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

Reply

byte

about 3 years ago

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!

Reply

india

about 2 years ago

only that ur type of people really helps. Thanks from heart.and i wish u should always happy

Reply

V

about 2 years ago

Excellent, thanks a lot

Reply

zoila

about 12 months ago

muchas graciass Excelente

Reply

d4rkd3m0n

about 11 months ago

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 !

Reply

edwin

about 11 months ago

Hi, you could use byte[ ] instead of String as parameter.

Leave a Comment

Please be polite. We appreciate that.
Your email address will not be published and required fields are marked


:-[ (B) (^) (P) (@) (O) (D) :-S ;-( (C) (&) :-$ (E) (~) (K) (I) (L) (8) :-O (T) (G) (F) :-( (H) :-) (*) :-D (N) (Y) :-P (U) (W) ;-)