Skip to content
JackSparrow414
Go back

Getting Started with Java RMI

Table of contents

Open Table of contents

Java RMI

Background

When different JVMs need to call one another, how can a method call from JVM A to JVM B feel like a local call? This is where RMI—Remote Method Invocation—comes in.

The JVMs can be on the same machine or on different machines.

Basic Principles

I find terms such as stub and skeleton hard to remember, and their meaning is not obvious from the names. Instead, I will explain this using the currently popular concept of microservices.

If you are familiar with microservices, the RMI invocation process is quite similar.

For a detailed understanding, I highly recommend the Proxy Pattern chapter in Head First Design Patterns, which gives a vivid, detailed explanation of RMI’s principles and inner workings.

Example

Provide a Remote Interface on the Server

  1. Extend the Remote interface.
  2. Methods exposed for remote invocation must throw RemoteException.
public interface RmiServerInterface extends Remote {

    /**
     * All methods exposed through RMI must throw RemoteException; otherwise, the following
     * Exception "remote object implements illegal remote interface"?
     * error occurs.
     * @return
     * @throws RemoteException
     */
    String sayHello() throws RemoteException;
}

Implement the Remote Interface on the Server

  1. Extend UnicastRemoteObject.
  2. The no-argument constructor throws RemoteException.
public class RmiInterfaceImpl extends UnicastRemoteObject implements RmiServerInterface{

    public RmiInterfaceImpl() throws RemoteException{
    }

    @Override
    public String sayHello() {
        return "hello, I'm Remote JVM Server";
    }
}

Registry

public class Server {
    public static void main(String[] args) throws RemoteException {
        // Start the registry
        Registry registry = LocateRegistry.createRegistry(2001);
        try {
          // Bind the service
            registry.bind("hello", new RmiInterfaceImpl());
            System.err.println("Server ready");
        } catch (AlreadyBoundException e) {
            System.out.println("Server bind fail" + e.getMessage());
        }
    }
}

Invoke the Remote Service from the Client

  1. Look up the service directly in RMI Registry.
public class RmiClient {

    public static void main(String[] args) {
        try {
          // The lookup name must match the name registered in the registry
            RmiServerInterface hello = (RmiServerInterface) Naming.lookup("rmi://localhost:2001/hello");
            System.out.println("Response from the server interface: " + hello.sayHello() +" "+ hello.getClass().getName());
        } catch (RemoteException | NotBoundException | MalformedURLException e) {
            System.out.println("Connect Server fail"+ e.getMessage());
        }
    }
}
  1. Another way to invoke RMI remotely is to use getRegistry instead of Naming.
Registry registry = LocateRegistry.getRegistry(targetHost, targetPort);
RmiServerInterface hello = (RmiServerInterface)registry.lookup("hello");
System.out.println("Response from the server interface: " + hello.sayHello() +" "+ hello.getClass().getName());

The Difference Between Naming.lookup and Registry.lookup

Answer on Stack Overflow In practice, there is little difference in usage; it comes down to developer preference.

Verification

  1. Start RMI Registry.
  2. Start the client and inspect its output. The class received by the client is actually a proxy class.

Other Points

  1. If the server returns an object, its class must implement the serialization interface because network transmission and I/O are involved.
  2. Code repository
  3. RMI brings RPC to mind. How are they related? In my view, RMI is a subset of RPC, customized for Java and its object model, making it convenient for Java developers to invoke methods across JVMs.

Official Documentation

Note: when following the official documentation, I consistently ran into problems configuring codebase.


Share this post:

Previous Post
Getting Started with Lua Scripts, with Example Code
Next Post
SpEL: Getting Started and Quick Reference

Comments

Questions, corrections, and experiences are welcome. Sign in with GitHub to comment; both language versions share this discussion.

Comments are available on the live site only.