Remote Method Invocation in Java
Remote Method Invocation (RMI) in Java is an API that enables an
object in one JVM to invoke methods on an object located in another
JVM, either on the same machine or a remote system. It supports
building distributed applications by allowing seamless client-server
communication through method calls.
Uses a client-server architecture where the client invokes methods on
remote objects.
Relies on the [Link] package and requires remote interfaces
extending Remote.
Communication is managed internally by the JVM, simplifying
remote interaction.
Stub (Client-side Proxy): It acts as a proxy for the remote object and
forwards method calls from the client to the server.
The block consists of
An identifier of the remote object to be used
Method name which is to be invoked
Parameters to the remote JVM
Working of RMI
Communication between client and server is handled using a Stub
(client-side proxy), while server-side request handling is managed
internally by the RMI runtime.
Note: In earlier RMI versions, Skeleton was used on the
server side, but it is now deprecated and no longer
required.
The steps to implement RMI are as follows
The following steps demonstrate how to build and run a basic RMI
application in Java.
Step 1: Defining the remote interface
The first thing to do is to create an interface that will provide the
description of the methods that can be invoked by remote clients. This
interface should extend the Remote interface and the method prototype
within the interface should throw the RemoteException.
Example:
import [Link].*;public interface Search extends Remote{ //
Declaring the method prototype public String query(String search)
throws RemoteException;}
Step 2: Implementing the remote interface
The next step is to implement the remote interface. To implement the
remote interface, the class should extend to UnicastRemoteObject class
of [Link] package. Also, a default constructor needs to be created to
throw the [Link] from its parent constructor in class.
import [Link].*;import [Link].*;public class
SearchQuery extends UnicastRemoteObject
implements Search{ // Default constructor to throw RemoteException
// from its parent constructor SearchQuery() throws RemoteException
{ super(); }
// Implementation of the query interface public String query(String
search) throws RemoteException { String result;
if ([Link]("Reflection in Java")) result = "Found"; else
result = "Not Found";
return result; }}
Step 3: No need to generate Stub/Skeleton manually
In modern Java, stub classes are generated dynamically by the JVM, so
the rmic tool is not required.
Step 4: Start the rmiregistry
Start the registry service by issuing the following command at the
command prompt start rmiregistry
Step 5: Create and execute the server application program
The next step is to create the server application program and execute it
on a separate command prompt.
The server program uses createRegistry method of LocateRegistry
class to create rmiregistry within the server JVM with the port
number passed as an argument.
The rebind method of Naming class is used to bind the remote object
to the new name.
import [Link].*;import [Link].*;public class
SearchServer{ public static void main(String args[]) { try
{ // Create an object of the interface // implementation
class Search obj = new SearchQuery();
// rmiregistry within the server JVM with // port number
1900 [Link](1900);
// Binds the remote object by the name // geeksforgeeks
[Link]("rmi://localhost:1900"+
"/geeksforgeeks",obj); } catch(Exception ae) {
[Link](ae); } }}
Step 6: Create and execute the client application program
The last step is to create the client application program and execute it on
a separate command prompt . The lookup method of the Naming class is
used to get the reference of the Stub object.
import [Link].*;public class ClientRequest{ public static void
main(String args[]) { String answer,value="Reflection in Java";
try { // lookup method to find reference of remote object
Search access =
(Search)[Link]("rmi://localhost:1900"+
"/geeksforgeeks"); answer = [Link](value);
[Link]("Article on " + value + ""+
answer+" at GeeksforGeeks"); } catch(Exception ae) {
[Link](ae); } }}
Note: The above client and server program is executed on the same
machine so localhost is used. In order to access the remote object from
another machine, localhost is to be replaced with the IP address where
the remote object is present.
save the files respectively as per class name as
[Link] , [Link] , [Link] &
[Link]
Important Observations:
RMI is a pure java solution to Remote Procedure Calls
(RPC) and is used to create the distributed applications
in java.
Stub objects are used on the client side, while server-
side communication is handled internally by the RMI
runtime.
What is a remote interface in java?
JavaObject Oriented ProgrammingProgramming
A Remote interface is available in the [Link] package it is a
marking/tagging interface, it is used with remote method
invocation(RMI).
RMI is a mechanism that allows an object residing in one system (JVM)
to access/invoke an object running on another JVM.
To it is a marking interface, to mark an object of a class remote, you need
to implement this interface.
To create a remote interface −
Create an interface that extends the predefined interface Remote which
belongs to the package or, implement the Remote interface with the class,
which you need to make remote.
Declare all the business methods that can be invoked by the client in this
interface.
Since there is a chance of network issues during remote calls, an
exception named RemoteException may occur; throw it.
Example
import [Link];
import [Link];
// Creating Remote class for our application
public class RemoteExample implements Remote {
}
Or,
import [Link];
import [Link];
// Creating Remote interface for our application
public interface Hello extends Remote {
void printMsg() throws RemoteException;
}
[Link] is a checked exception in Java RMI that
indicates a network-related communication failure during a remote
method call, such as connection refused, server unavailability, or
serialization issues. It serves as a safety mechanism, requiring developers
to handle potential faults in distributed systems. [1, 2, 3]
Common Causes and Solutions:
Connection Refused: The registry is not running, or the port is wrong.
Ensure rmiregistry is started on the correct port.
Hostname Resolution: The server binds to [Link] (loopback) instead
of the actual network IP, preventing external clients from connecting. Set
the system property [Link] to the server's actual IP
address or hostname.
Serialization Errors: Parameters or return types passed between client
and server do not implement Serializable.
Misconfigured Stub/Skeleton: The remote object is not properly
exported. Ensure [Link]() is used correctly.
Package Discrepancies: Ensure the remote interface package name is
identical in both client and server projects. [1, 2, 3, 4, 5, 6]
Key Details:
Package: [Link]
Handling: Must be caught or thrown in all methods of an interface
extending Remote.
Subclasses: ConnectException, MarshalException,
NoSuchObjectException, and UnmarshalException.
Status: While functional, the [Link] package is largely considered
legacy, with some components removed or deprecated in modern JDK
versions (JDK 17+). [1, 2, 3, 4, 5]
A remote object is an instance whose methods can be invoked from a
different Java Virtual Machine (JVM), often across a network, primarily
used in Java Remote Method Invocation (RMI). It implements the
[Link] interface, allowing clients to interact with server-side
objects via "stubs" (proxies). [1, 2, 3]
Key Aspects of Remote Objects:
RMI Registry: A server registers the remote object, allowing clients to
look up and obtain a stub.
Remote Interface: Methods must be declared in an interface that extends
[Link].
Stub/Skeleton: The client uses a stub (proxy) to invoke methods, while
the skeleton (or server-side handler) receives the request.
Implementation: Commonly implemented by extending
[Link].
Active vs. Passive: An active object is currently exported in a JVM,
while a passive object is activated upon the first method invocation. [1, 2,
3, 4, 5, 6]
Other frameworks, such as Qt Remote Objects, also use this concept to
share data objects across different processes or devices. [1]
Compiling a Remote Object class in Java RMI (Remote Method
Invocation) involves two primary stages: generating the standard Java
class file and creating the necessary communication proxies (stubs and
skeletons). [1, 2]
1. Compile the Java Source Files [1]
First, you must use the standard javac compiler to compile all source
files, including the remote interface and its implementation. [1, 2]
Command: javac *.java
Goal: This creates the .class files required for the next step. [1, 2, 3]
2. Generate Stubs and Skeletons [1]
Once the implementation class is compiled, you use the rmic (RMI
Compiler) to generate the "stub" and "skeleton" classes. [1, 2]
Stub: A client-side proxy that marshals method arguments and transmits
them to the server.
Skeleton: A server-side entity that unmarshals the request and dispatches
it to the actual object implementation.
Command: rmic [PackageName].ClassName (e.g., rmic
[Link]).
Result: This produces files like HelloImpl_Stub.class and
HelloImpl_Skel.class. [1, 2, 3, 4]
Important Modern Note
In modern Java versions (specifically Java 5.0 and later), the explicit
use of rmic is often unnecessary for building stubs. The RMI system can
generate dynamic stubs at runtime, meaning you typically only need to
compile your source files with javac. However, rmic is still required if
you are working with legacy systems or RMI-IIOP. [1, 2, 3, 4, 5]
Prerequisites for Success
Before compiling, ensure your implementation class meets these
requirements:
Implements a Remote Interface: The class must implement an interface
that extends [Link].
Exception Handling: All methods in the remote interface must declare
that they throw [Link].
Constructor: The constructor should generally throw RemoteException,
especially if it extends UnicastRemoteObject. [1, 2, 3, 4]
rmic - The Java RMI Stub Compiler
DESCRIPTION. The rmic compiler generates stub and skeleton class
files for remote objects from the names of compiled Java classes ...
Columbia University
Getting Started Using RMI
Write an Implementation Class. To write a remote object, you write a
class that implements one or more remote interfaces. The impl...
Columbia University
rmic - The Java RMI Stub Compiler
rmic generates stubs and skeletons for remote objects.
San Diego State University
Show all
Client-Server Model
Last Updated : 10 Feb, 2026
The Client-Server Model is a network architecture in which clients send
requests for resources or services, and servers process these requests,
returning the required responses.
Client: A device or program that requests data or services (e.g., web
browser).
Server: A system that stores resources, manages data, and responds
to client requests.
Request–response mechanism: Communication follows a
structured cycle — client requests, server responds.
Centralized management: Data and services are controlled from
servers, improving security and consistency.
Working
The client-server model works on a request–response flow where a
client requests a service/data and the server processes that request and
returns a response.
Client-Server Model
Client is a device/app that requests services from a server, like a web
browser or email app.
Server is a system that listens for requests and responds by sending
data or performing operations.
Servers can handle many clients at the same time using concurrent
request handling.
Example client apps include Chrome/Firefox and Gmail/Outlook.
Example servers include web servers (Apache/Nginx), email servers,
and database servers.
How Client-Server Communication Works in C++
In C++, sockets are used for communication between the client and the
server over a network.
Example:
Server Code ([Link])
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <netinet/in.h>
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int addrlen = sizeof(address);
char buffer[1024] = {0};
// Create socket
server_fd = socket(AF_INET, SOCK_STREAM, 0);
// Setup address
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(8080);
// Bind socket
bind(server_fd, (struct sockaddr*)&address, sizeof(address));
// Start listening
listen(server_fd, 3);
std::cout << "Server waiting for connection...\n";
// Accept a client connection
new_socket = accept(server_fd, (struct sockaddr*)&address,
(socklen_t*)&addrlen);
// Read message from client
read(new_socket, buffer, 1024);
std::cout << "Client says: " << buffer << std::endl;
// Send reply
const char* reply = "Hello from server!";
send(new_socket, reply, strlen(reply), 0);
close(new_socket);
close(server_fd);
return 0;
}
Client Code ([Link])
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
int main() {
int sock = 0;
struct sockaddr_in serv_addr;
char buffer[1024] = {0};
// Create socket
sock = socket(AF_INET, SOCK_STREAM, 0);
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(8080);
inet_pton(AF_INET, "[Link]", &serv_addr.sin_addr);
// Connect to server
connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
// Send message
const char* hello = "Hello from client!";
send(sock, hello, strlen(hello), 0);
// Receive reply
read(sock, buffer, 1024);
std::cout << "Server says: " << buffer << std::endl;
close(sock);
return 0;
}
How a Browser Interacts With a Server
Client-Server Request and Response
User enters a URL in the browser (example: [Link]).
Browser performs a DNS lookup to convert the domain name into an
IP address.
Browser establishes a connection and sends an HTTP/HTTPS request
to the server using that IP.
Server responds with website resources like HTML, CSS, JavaScript,
and images.
Browser renders the webpage by processing these files and
displaying the content.
Types of Client-Server Architecture
Client-server architecture is commonly classified by how many layers
handle presentation, logic, and data.
1. 2-Tier Architecture
In a 2-tier architecture, the client communicates directly with the server,
which is typically responsible for both processing and data storage.
It consists of two layers: the client layer and the server layer.
The client handles the user interface and may perform some
processing before sending requests.
The server processes client requests and manages the database.
This architecture is suitable for small applications and environments
with limited users.
However, it becomes difficult to scale and manage when many
clients connect to the server simultaneously.
2. 3-Tier Architecture
In a 3-tier architecture, the system is divided into three layers to
improve performance, security, and scalability.
It consists of the presentation layer (client), application layer
(business logic), and data layer (database server).
The client interacts with the application server instead of
communicating directly with the database.
The application server processes requests, applies business logic, and
retrieves or stores data in the database.
This structure enhances security because the database is not directly
exposed to clients.
It is widely used in web applications and enterprise systems due to its
flexibility and easier maintenance.
Advantages
It centralizes data and services, which makes management and
updates easier.
It improves security because access control and authentication can be
enforced on the server.
It supports multiple clients at the same time, so many users can use
the same service concurrently.
It makes data sharing consistent because clients get information from
a single trusted source.
It becomes easier to maintain because most changes can be done on
the server without updating every client.
Limitations
It creates a dependency on the server, so services may stop if the
server fails.
It can become a bottleneck when many clients send requests at the
same time.
It requires higher server cost because servers need strong hardware,
storage, and continuous availability.
It needs network connectivity, so poor networks can reduce
performance or block access.
It can be complex to scale properly because load balancing,
replication, and backups may be required.
Applications
Web browsing uses browsers as clients and web servers to deliver
webpages and APIs.
Email systems use email clients and mail servers to send, store, and
retrieve messages.
Online banking systems use mobile/web apps to access secure
banking servers.
Social media platforms use client apps to request feeds, posts, and
media from backend servers.
Cloud storage services use client apps to upload, download, and sync
files from storage servers.
Database-driven applications use clients to query and update data
stored on database servers.
The RMI Registry (rmiregistry) is a server-side bootstrap naming service
in Java Remote Method Invocation (RMI) that maps remote object names
to their stubs. It acts as a directory, allowing servers to bind (register)
objects and clients to look them up for method invocation, typically
operating on port 1099. [1, 2, 3, 4, 5]
Key Aspects of the RMI Registry:
Functionality: It provides a simple remote object naming service. It is
primarily used to locate the first remote object, which can then provide
access to other objects.
Registration (bind/rebind): A server process creates a remote object and
registers it with the rmiregistry on the local host.
Lookup (lookup): A client queries the registry by name to obtain a stub
(reference) for a remote object, which it uses to invoke methods.
LocateRegistry Class: The [Link] class is used
to get a registry on a specific host/port or to create a new registry in the
current virtual machine.
Naming Class: The [Link] class provides methods to lookup,
bind, rebind, unbind, and list objects in the registry.
Limitations: Generally, rmiregistry only accepts registration of objects
from the same host, requiring a registry to run on each host.
Running the Registry: It can be started using the command rmiregistry
[port] in a terminal. [1, 2, 3, 4, 5, 6, 7]