Remote Method Invocation in Java

Remote Method Invocation (RMI) is a Java API that allows a client application to invoke methods on remote objects running on a different Java Virtual Machine (JVM) or on a different physical machine.


With RMI, the client application interacts with the remote object as if it were a local object. The RMI system takes care of marshalling and unmarshalling the method parameters and results across the network.


Here is an example of how to use RMI in Java:


First, you need to define the remote interface that the remote object will implement. The remote interface is used to declare the methods that can be invoked remotely. Here is an example of a remote interface:


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

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


The MyRemoteInterface interface extends the Remote interface and declares a single method called sayHello() that can be called remotely.


Next, you need to implement the remote object that will provide the implementation of the sayHello() method. Here is an example of a remote object implementation:

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

public class MyRemoteObject extends UnicastRemoteObject implements MyRemoteInterface {
    public MyRemoteObject() throws RemoteException {
        // constructor must declare RemoteException
    }

    public String sayHello() throws RemoteException {
        return "Hello, world!";
    }
}


The MyRemoteObject class extends the UnicastRemoteObject class and implements the MyRemoteInterface interface. It provides an implementation of the sayHello() method.


Finally, you need to create and start the RMI registry and register the remote object with the registry. 


Here is an example of how to do this:

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class MyServer {
    public static void main(String[] args) throws Exception {
        // Create and export the remote object
        MyRemoteObject obj = new MyRemoteObject();

        // Create the RMI registry on port 1099
        Registry registry = LocateRegistry.createRegistry(1099);

        // Bind the remote object to the registry
        registry.rebind("MyRemoteObject", obj);

        System.out.println("Server ready");
    }
}


The MyServer class creates and exports an instance of the MyRemoteObject class, creates an RMI registry on port 1099, and binds the remote object to the registry with the name "MyRemoteObject".


Now the remote object is available for clients to invoke its methods remotely. Here is an example of a client application that uses the remote object:

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class MyClient {
    public static void main(String[] args) throws Exception {
        // Get a reference to the RMI registry
        Registry registry = LocateRegistry.getRegistry("localhost", 1099);

        // Look up the remote object by name
        MyRemoteInterface obj = (MyRemoteInterface) registry.lookup("MyRemoteObject");

        // Call the remote method
        String result = obj.sayHello();

        System.out.println(result);
    }
}


The MyClient class gets a reference to the RMI registry running on the local machine on port 1099, looks up the remote object by name, and invokes its sayHello() method. The result is printed to the console.