Advance Java ProgrammingUnit 611 min read
RMI: Remote Method Invocation in Java
Unit 6 of Advance Java Programming introduces Remote Method Invocation (RMI), a Java technology for distributed object communication, covering its architecture, components (stubs, skeletons, registry), data marshalling/unmarshalling, security, and real-world applications like banking systems and e-commerce platforms.
TAKEAWAYS:
- RMI enables Java objects to call methods on remote objects as if they were local, using stubs, skeletons, and the RMI registry.
- Marshalling converts Java objects to byte streams for network transmission; unmarshalling reconstructs them on the remote side.
- The RMI architecture consists of client, server, stub, skeleton, and registry, with security managers enforcing access control.
- RMI differs from CORBA in language neutrality (CORBA) vs. Java-only (RMI) and in its use of dynamic proxies vs. IDL interfaces.
- Real-world use: eSewa’s transaction validation, Daraz’s inventory checks, and NEPSE’s stock price updates rely on distributed method calls.
- Exam focus: Write client-server RMI programs, explain stub/skeleton roles, and compare RMI with CORBA or servlets.
1. Introduction to RMI
RMI allows a Java object (client) to invoke methods on a remote Java object (server) transparently. Unlike traditional socket-based communication, RMI abstracts network details using stubs (client-side proxies) and skeletons (server-side adapters).
Key Idea: RMI turns distributed objects into local method calls, hiding network latency and serialization complexities.
2. RMI Architecture
The RMI system consists of five core components:
flowchart TD
A["Client"] -->|"Calls remote method"| B["Stub"]
B -->|"Marshalls args"| C["Network"]
C -->|"Unmarshalls args"| D["Skeleton"]
D -->|"Invokes method"| E["Remote Object"]
E -->|"Returns result"| D
D -->|"Marshalls result"| C
C -->|"Unmarshalls result"| B
B -->|"Returns to client"| A
F["RMI Registry"] -->|"Binds/lookups"| B & DComponents Explained:
- Client: The application invoking remote methods.
- Stub: A local proxy that marshals arguments and sends them over the network.
- Skeleton: A server-side adapter that unmarshals arguments and invokes the actual remote object.
- Remote Object: The actual object implementing remote methods (extends
java.rmi.Remote). - RMI Registry: A naming service (port
1099by default) that maps remote objects to network addresses.
3. How RMI Works: Step-by-Step
When a client calls a remote method:
- Stub serializes (marshalls) arguments into a byte stream.
- Network transmits the byte stream to the server.
- Skeleton deserializes (unmarshalls) the byte stream and calls the remote object.
- Remote object executes the method and returns a result.
- Skeleton marshalls the result back to the client.
- Stub unmarshalls the result and returns it to the caller.
Example: Calculating the product of two numbers remotely.
4. Data Marshalling and Unmarshalling
RMI uses Java’s serialization to convert objects into byte streams for network transmission.
Marshalling:
// Stub converts args to bytes
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(args); // Serializes arguments
Unmarshalling:
// Skeleton converts bytes back to objects
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
int result = (int) ois.readObject(); // Deserializes result
Limitations:
- Only serializable objects can be transmitted.
- Primitive types (int, double) and String are automatically supported.
- Custom objects must implement
java.io.Serializable.
5. RMI Registry
The RMI Registry acts as a white pages service for remote objects:
- Binds: Registers a remote object under a name (e.g.,
"Calculator"). - Unbinds: Removes a remote object.
- Lookups: Clients query the registry to find the remote object’s URL.
Example Registry Command:
rmiregistry 1099 # Starts registry on port 1099
6. Writing an RMI Application
Worked Example: Remote Calculator (Product of Two Numbers)
Step 1: Define the Remote Interface
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Calculator extends Remote {
int multiply(int a, int b) throws RemoteException;
}
Step 2: Implement the Remote Object
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
public class CalculatorImpl extends UnicastRemoteObject implements Calculator {
public CalculatorImpl() throws RemoteException {
super();
}
@Override
public int multiply(int a, int b) throws RemoteException {
return a * b;
}
}
Step 3: Server Code (Exports Remote Object)
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class CalculatorServer {
public static void main(String[] args) {
try {
Calculator obj = new CalculatorImpl();
Registry registry = LocateRegistry.createRegistry(1099);
registry.rebind("Calculator", obj);
System.out.println("Server ready");
} catch (Exception e) {
System.err.println("Server error: " + e);
}
}
}
Step 4: Client Code (Calls Remote Method)
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class CalculatorClient {
public static void main(String[] args) {
try {
Registry registry = LocateRegistry.getRegistry("localhost", 1099);
Calculator stub = (Calculator) registry.lookup("Calculator");
int result = stub.multiply(5, 3);
System.out.println("Product: " + result); // Output: 15
} catch (Exception e) {
System.err.println("Client error: " + e);
}
}
}
7. RMI vs. CORBA
| Feature | RMI | CORBA |
|---|---|---|
| Language | Java-only | Language-neutral (IDL) |
| Interface | Java Remote interface |
IDL (Interface Definition Language) |
| Proxy Generation | Automatic (stubs/skeletons) | Manual (ORB generates stubs/skeletons) |
| Portability | Limited to Java | Cross-language (C++, Python, etc.) |
| Use Case | Java-based distributed systems | Heterogeneous distributed systems |
8. Security in RMI
RMI includes security managers to control:
- Network access (e.g., blocking malicious calls).
- Class loading (preventing code injection).
- Method invocation (enforcing permissions).
Example Security Policy:
java -Djava.security.policy=policy.all -cp . CalculatorServer
Policy File (policy.all):
grant {
permission java.net.SocketPermission "localhost:1099", "connect, accept";
};
9. Real-World Applications
In the Real World
eSewa Transaction Validation
- Idea: RMI enables real-time balance checks across multiple servers.
- How: When a user requests a transaction, eSewa’s backend uses RMI to call a remote balance service running on a different server, ensuring consistency without direct database access.
Daraz Inventory Management
- Idea: Distributed product availability checks.
- How: When a customer adds an item to their cart, Daraz’s frontend calls a remote inventory service (via RMI) to verify stock levels across warehouses, updating the UI instantly.
NEPSE Stock Price Updates
- Idea: Real-time market data aggregation.
- How: NEPSE’s trading servers use RMI to publish stock prices to multiple client applications (e.g., trading platforms), ensuring low-latency updates without polling.
10. Worked Example: Discounted Price Calculation
Scenario: A retail app calculates the selling price after a discount. Given:
- Cost price = Rs. 5000
- Discount = Rs. 500
Step 1: Remote Interface
public interface PriceCalculator extends Remote {
double calculateSellingPrice(double cost, double discount) throws RemoteException;
}
Step 2: Server Implementation
public class PriceCalculatorImpl extends UnicastRemoteObject implements PriceCalculator {
public PriceCalculatorImpl() throws RemoteException {
super();
}
@Override
public double calculateSellingPrice(double cost, double discount) {
return cost - discount;
}
}
Step 3: Client Call
Registry registry = LocateRegistry.getRegistry("localhost", 1099);
PriceCalculator stub = (PriceCalculator) registry.lookup("PriceCalculator");
double sellingPrice = stub.calculateSellingPrice(5000, 500);
System.out.println("Selling Price: Rs. " + sellingPrice); // Output: Rs. 4500.0
11. Common Pitfalls and Debugging
ClassNotFoundException:
- Cause: The client cannot find the remote object’s class.
- Fix: Ensure both client and server have the same
.classfiles (or use-classpathinrmic).
NoSuchMethodError:
- Cause: The remote interface method is not implemented correctly.
- Fix: Verify the method signature matches exactly.
Connection Refused:
- Cause: The RMI registry is not running (
rmiregistrynot started). - Fix: Start the registry first:
rmiregistry 1099
- Cause: The RMI registry is not running (
12. Exam Tip
- For definitions: Always include stub, skeleton, and marshalling in your answer.
- For code questions:
- Server: Extend
UnicastRemoteObject, implementRemoteinterface, bind to registry. - Client: Use
LocateRegistry.getRegistry(), calllookup(), cast to remote interface.
- Server: Extend
- For comparisons: Highlight language neutrality (CORBA vs. Java-only RMI) and proxy generation (automatic vs. manual).
- For security: Mention policy files and permission checks in your answer.
- For real-world links: Tie RMI to e-commerce (Daraz), banking (eSewa), or stock markets (NEPSE) in your explanations.
Visual Summary:
mindmap
root((RMI))
Client
Stub
Marshalls args
Network
Transmits byte stream
Server
Skeleton
Unmarshalls args
Remote Object
Executes method
Registry
Binds/lookups objects
Security
Policy files
Permission checks
Real-world
E-commerce (Daraz)
Banking (eSewa)
Stock markets (NEPSE)Based on the TU BCA syllabus for Advance Java Programming (CACS354), unit 6.
Discussion
Loading…