Java RMI
What is RMI in Java?
A framework for developing distributed Java applications is provided by the RMI (Remote Method Invocation) API. An object can call methods on an object running in another JVM via RMI.
Two objects, stub, and skeleton are used by the RMI to enable remote communication between the apps.
Understanding stub and skeleton
For communication with the remote object, RMI uses skeleton and stub objects.
Any object whose method can be called from another JVM is considered a remote object. Let's examine how to comprehend stub and skeleton objects:
Stub
A gateway for the client side, the stub is an object. It serves as the conduit for all outbound requests. It is a client-side object that represents a distant object. The following things happen when the caller calls a method on the stub object:
1. It begins communication with a distant virtual machine (JVM),
2. The parameters are written and sent (marshaled) to the distant Virtual Machine (JVM),
3. It anticipates the outcome.
4. The return value or exception is read (unmarshalled), and
5. The value is then returned to the caller.
Skeleton
A gateway for the server-side object, the skeleton is an object. It is used to route each and every request that comes in. The skeleton does the following actions when it gets an incoming request:
1. It reads the remote method parameter
3. It writes and transmits (marshals) the outcome to the caller after invoking the method on the actual remote object in step 2.
A stub protocol that does away with skeletons was added to the Java 2 SDK.

Recognizing the needs of distributed applications
Any program that handles these duties could be distributed.
1. The program needs to find the remote method
3. The program needs to load the object class definitions. It also needs to offer connectivity with remote objects.
With all these features, the RMI application qualifies as a distributed application.
Java RMI Example
The six steps for writing the RMI program are provided.
- Establish the remote interface.
- Describe how to implement a remote interface.
- Utilizing the rmic tool, compile the implementation class and produce the skeleton and stub objects.
- the rmiregistry utility to launch the registry service
- Establish and launch the remote application.
- Establish and launch the client application.
Now let us discuss each of them in brief.

Establish the remote interface
The Remote interface should be extended to create the Remote interface, and all of the RemoteException's methods should be declared. Here, a remote interface that expands the Remote interface is being created. The add() function is the sole one and it declares RemoteException.
import java.rmi.*;
public interface Subtracter extends Remote{
public int sub(int x,int y)throws RemoteException;
}
Describe how to implement a remote interface
Now present the remote interface implementation. We must either utilize the exportObject() method of the UnicastRemoteObject class or extend the UnicastRemoteObject class to provide the implementation of the Remote interface.
If you decide to extend the UnicastRemoteObject class, you must include a function Object() { [native code] } (constructor) with the RemoteException keyword.
SubtracterRemote.java
import java.rmi.*;
import java.rmi.server.*;
public class SubtracterRemote extends UnicastRemoteObject implements Subtracter{
SubtracterRemote()throws RemoteException{
super();
}
public int sub(int a,int b){
return a-b;
}
}
Utilizing the rmic tool, compile the implementation class and produce the skeleton and stub objects
The rmi compiler will then be used to construct skeleton and stub objects. The rmic tool generates skeleton and stub objects while invoking the RMI compiler.
rmic SubtracterRemote
the rmiregistry utility to launch the registry service
The rmiregistry tool is now used to launch the registry service. A default port number is used if the port number is not specified. We're using port 5000 in this instance.
rmiregistry 5000
Establish and launch the remote application
A server process is now required to host rmi services. The Naming class offers ways to retrieve and save distant objects.
SearchServer.java
import java.rmi.*;
import java.rmi.registry.*;
public class SearchServer
{
public static void main(String args[])
{
try{
Subtracter s=new SubtracterRemote();
Naming.rebind("rmi://localhost:5000/javaTpoint",s);
}
catch(Exception e)
{
System.out.println(e);
}
}
Establish and launch the client application
Using the lookup() function of the Naming class at the client, we are retrieving the stub object and calling the method on it. In this example, localhost is used because the server and client programs are both executing on the same system. Change localhost to the hostname (or IP address) of the machine where the remote item is located if you want to access it from another machine.
ClientServer.java
import java.rmi.*;
public class ClientServer
{
public static void main(String args[])
{
Try
{
Subtracter s=(Subtracter)Naming.lookup("rmi://localhost:5000/javaTpoint");
System.out.println(stub.sub(34,4));
}
catch(Exception e)
{ }
}
}
Output:
30