[Go to site: main page, start]

0% found this document useful (0 votes)
16 views19 pages

Java RMI

Java RMI (Remote Method Invocation) is a Java API that enables method invocation on remote objects across different JVMs, facilitating distributed object-oriented programming. The document outlines RMI architecture, implementation steps, serialization, security considerations, and examples of RMI applications, including a basic Hello service and a Calculator service. Key components include the RMI registry for locating remote objects, and the importance of serialization for transmitting objects over a network.

Uploaded by

helina3leul
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views19 pages

Java RMI

Java RMI (Remote Method Invocation) is a Java API that enables method invocation on remote objects across different JVMs, facilitating distributed object-oriented programming. The document outlines RMI architecture, implementation steps, serialization, security considerations, and examples of RMI applications, including a basic Hello service and a Calculator service. Key components include the RMI registry for locating remote objects, and the importance of serialization for transmitting objects over a network.

Uploaded by

helina3leul
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Java RMI (Remote Method Invocation)

Lecture Notes
Table of Contents

Contents
Table of Contents .................................................................................................................................... 2
1. Introduction to RMI .............................................................................................................................. 3
2. RMI Architecture ................................................................................................................................... 4
3. Local vs. Remote Objects ...................................................................................................................... 4
4. Java RMI in a Nutshell ........................................................................................................................... 5
5. Locating Remote Objects ...................................................................................................................... 6
6. RMI Implementation Steps ................................................................................................................... 7
7. Serialization......................................................................................................................................... 11
Java RMI Using Serialization................................................................................................................ 11
8. Security Considerations ...................................................................................................................... 16
9. Advantages and Disadvantages .......................................................................................................... 18
10. Best Practices .................................................................................................................................. 19
[Link] to RMI
Remote Method Invocation (RMI) is a Java API that allows an object running in one Java
Virtual Machine (JVM) to invoke methods on an object running in another JVM, even if both
JVMs are on different machines.

Key characteristics:

 Part of Java's core API since JDK 1.1


 Enables distributed object-oriented programming
 Uses Java's serialization mechanism for parameter passing
 Provides location transparency (client doesn't need to know where the remote object is)

Why RMI?

 In socket programming, programmers have to make explicit connections between clients


and servers and manage data transmission.
 Thus, it’s hard and error-prone to write socket programs.
 Can the connection and data transmission be managed by JVM?
[Link] Architecture
RMI has a layered architecture:

1. Stub/Skeleton Layer:
o Stub (client-side proxy)
o Skeleton (server-side dispatcher, deprecated since Java 1.2)
2. Remote Reference Layer: Handles reference semantics (unicast, multicast)
3. Transport Layer: TCP-based network connections

Components:

 Client: Invokes remote methods


 Server: Hosts remote objects
 RMI Registry: Naming service for remote objects (default port 1099)

3. Local vs. Remote Objects


 Local objects
o Objects accessible only within the local hosts
 Remote objects
o Objects accessible from remote hosts
o Instances of classes that implements a marker interface [Link]
 Property of remote objects
o Similar to local objects (arguments, downcasting, instanceof, etc)
o Clients of remote objects interact with stubs
o Passing arguments and results for RMI calls
 Call by value for local objects (through serialization and deserialization)
 Call by reference for remote objects
4. Java RMI in a Nutshell/Summary of RMI/
[Link] Remote Objects
 RMI registry
o Directory service mapping RMI servers (or objects) to their names
o Server: register itself to make it available to remote clients
o Client: locate a server by looking up an RMI registry with a URL protocol rmi,
e.g.,
 rmi://host:port/name
o The programming interface by the class [Link]

Method Description

bind(name, obj) Bind obj to name

rebind(name, obj) Bind obj to name even if already bound

unbind(name) Remove the binding

lookup(url) Return object bound to url

list(url) Return a list of all bindings


[Link] Implementation Steps
1. Define the remote interface (extends [Link])
2. Implement the remote interface
3. Create a server instance and register to an RMI Registry
4. Create and start the RMI registry
5. Register the remote object with the registry
6. Develop the client to lookup and invoke remote methods

Example 1: Basic RMI Application

Steps 1: Define a remote interface


import [Link].*;

public interface Hello extends Remote {


String sayHello() throws RemoteException;
}

Steps 2: Define a service implementation class/Remote Object Implementation/


import [Link].*;
import [Link].*;

public class HelloImpl extends UnicastRemoteObject implements Hello {


public HelloImpl() throws RemoteException {
super(); // calls UnicastRemoteObject constructor
}

public String sayHello() throws RemoteException {


return "Hello, RMI World!";
}
}
Steps 2: Create a server instance and register to an RMI Registry/Server/
import [Link].*;

public class HelloServer {


public static void main(String[] args) {
try {
// Create remote object
HelloImpl obj = new HelloImpl();

// Bind the remote object to the registry


Registry registry = [Link](1099);
[Link]("HelloService", obj);

[Link]("Server ready");
} catch (Exception e) {
[Link]("Server exception: " + [Link]());
[Link]();
}
}
}
Step 4: Generate the stub and skeleton classes by using the RMI compiler (rmic), before jdk 1.5
% rmic HelloImpl
The command produces:

HelloImpl_Stub.class and HelloImpl_Skel.class


After jdk>=1.5, automatic export of stub at run time
HelloService stub = (HelloService) [Link](service, 0);
Step 5: Write a client program/ Client/
import [Link].*;

public class HelloClient {


public static void main(String[] args) {
try {
// Get reference to the registry
Registry registry = [Link]("localhost", 1099);

// Lookup the remote object


Hello stub = (Hello) [Link]("HelloService");

// Invoke remote method


String response = [Link]();
[Link]("Response: " + response);
} catch (Exception e) {
[Link]("Client exception: " + [Link]());
[Link]();
}
}
}
Compiling and Running
Compile the server and client programs, e.g.,

% javac *.java

Generates the stubs and skeletons, e.g.,

% rmic HelloImpl // cmd, before jdk 1.5

HelloService stub = (HelloService) [Link](service, 0);jdk>=1.5

Start the RMI registry on the server host, e.g.,

% rmiregistry
Optionally, we can use the following line of code to automatically launch an in-
memory RMI registry

Registry registry = [Link](1099);

Run the server on the server host, e.g.,

% java HelloServer

Runt the client on the client host, e.g.,

% java HelloClient

Example 2: Calculator Service

Remote Interface

import [Link].*;

public interface Calculator extends Remote {


double add(double a, double b) throws RemoteException;
double subtract(double a, double b) throws RemoteException;
double multiply(double a, double b) throws RemoteException;
double divide(double a, double b) throws RemoteException;
}
Implementation
import [Link].*;
import [Link].*;

public class CalculatorImpl extends UnicastRemoteObject implements Calculator


{
public CalculatorImpl() throws RemoteException {
super();
}
public double add(double a, double b) throws RemoteException {
return a + b;
}
public double subtract(double a, double b) throws RemoteException {
return a - b;
}
public double multiply(double a, double b) throws RemoteException {
return a * b;
}
public double divide(double a, double b) throws RemoteException {
if (b == 0) throw new RemoteException("Cannot divide by zero");
return a / b;
}
}
Server
import [Link].*;

public class CalculatorServer {


public static void main(String[] args) {
try {
CalculatorImpl calculator = new CalculatorImpl();
Registry registry = [Link](1099);
[Link]("CalculatorService", calculator);
[Link]("Calculator Service is running...");
} catch (Exception e) {
[Link]("Server exception: " + [Link]());
[Link]();
}
}
}
Client
import [Link].*;
import [Link];

public class CalculatorClient {


public static void main(String[] args) {
try {
Registry registry = [Link]("localhost");
Calculator calculator = (Calculator)
[Link]("CalculatorService");

Scanner scanner = new Scanner([Link]);


[Link]("Enter first number:");
double a = [Link]();
[Link]("Enter second number:");
double b = [Link]();

[Link]("Addition: " + [Link](a, b));


[Link]("Subtraction: " + [Link](a, b));
[Link]("Multiplication: " + [Link](a,
b));
[Link]("Division: " + [Link](a, b));
[Link]();
} catch (Exception e) {
[Link]("Client exception: " + [Link]());
[Link]();
}
}
}
[Link]
Java RMI Using Serialization

Serialization is an essential concept in Java RMI (Remote Method Invocation) because it allows
the transmission of objects over a network. In RMI, remote objects and the parameters they
accept must be serializable because RMI requires that objects be converted into a byte stream
(serialized) so they can be transmitted across the network, and then reconstructed on the
receiving side (deserialized).

Let’s break down the concept of serialization in the context of RMI and how it works.

1. Why Serialization is Important in RMI

When you invoke a remote method in Java RMI, the following steps happen:

Object Passing: When a client calls a method on a remote object, the arguments passed to the
remote method are sent across the network to the server, and the return value is sent back to
the client.

Serialization: Both the arguments and the return values must be converted into a byte stream,
so they can be transmitted over the network. This process is called serialization.

Deserialization: On the receiving side (either the client or the server), the byte stream is
converted back into the original object via deserialization.

If an object is not serializable, it cannot be passed as a parameter to a remote method, and the
RMI system will throw a [Link].

How to make objects serializable?

By implementing the marker interface [Link]

A default implementation for (de) serialization is automatically provided.

Can customize the process by implementing readObject() and writeObject() methods:

private void writeObject([Link] out) throws IOException;

private void readObject([Link] in) throws IOException,


ClassNotFoundException;
To use a Student class with RMI, you'll need to ensure that the Student class is serializable.
This means the Student class should implement the Serializable interface so that instances
of Student can be sent over the network between the client and server in an RMI application.

Step-by-Step Guide to Serialize the Student Class in RMI

Let’s walk through how to serialize the Student class and use it in an RMI example.

1. Create the Student Class

First, you’ll need to make sure that the Student class implements the Serializable interface.

Here’s an example of a simple Student class:

import [Link];

public class Student implements Serializable {


private static final long serialVersionUID = 1L; // Optional, but recommended for version
control
private String name;
private int age;
private String studentId;

// Constructor
public Student(String name, int age, String studentId) {
[Link] = name;
[Link] = age;
[Link] = studentId;
}

// Getter methods
public String getName() {
return name;
}

public int getAge() {


return age;
}
public String getStudentId() {
return studentId;
}

// toString method for displaying student info


@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", studentId=" + studentId + "]";
}
}

In this Student class:

Serializable is implemented, which makes it eligible for serialization in RMI.

serialVersionUID is added for version control of the class during deserialization, which is
recommended when the class may change over time.

2. Define the Remote Interface

Next, you’ll need to define a remote interface that will allow the RMI client to call a method
that uses the Student class.

import [Link].*;

public interface StudentService extends Remote {


String getStudentDetails(Student student) throws RemoteException;
}

3. Implement the Remote Interface

The server implementation of the remote interface will implement the StudentService
interface. It will define the method that takes a Student object as a parameter.

import [Link].*;
import [Link].*;

public class StudentServiceImpl extends UnicastRemoteObject implements StudentService {


public StudentServiceImpl() throws RemoteException {
super();
}

@Override
public String getStudentDetails(Student student) throws RemoteException {
// Just return some info about the student as a string
return "Student Details: " + [Link]();
}
}
4. Create the Server Program

In the server program, you will create an instance of StudentServiceImpl, which implements
the remote service, and then bind it to the RMI registry so that clients can lookup and invoke it
remotely.

import [Link].*;
import [Link].*;

public class StudentServer {

public static void main(String[] args) {


try {
// Create the remote object
StudentServiceImpl studentService = new StudentServiceImpl();

// Bind the remote object to the RMI registry


[Link]("//localhost/StudentService", studentService);

[Link]("StudentService is ready.");
} catch (Exception e) {
[Link]("Server failed: " + e);
}
}
}
5. Create the Client Program

In the client program, you'll lookup the StudentService from the RMI registry, create a
Student object, and call the remote method getStudentDetails() with the Student object
as the parameter.

import [Link].*;

public class StudentClient {

public static void main(String[] args) {


try {
// Lookup the remote service in the RMI registry
StudentService studentService = (StudentService)
[Link]("//localhost/StudentService");

// Create a Student object


Student student = new Student("Alice", 20, "S12345");

// Call the remote method with the Student object


String result = [Link](student);
[Link](result);
} catch (Exception e) {
[Link]("Client failed: " + e);
}
}
}
[Link] Considerations
When using Java RMI (Remote Method Invocation) to build distributed systems, security is
vital to ensure that the communication between clients and servers is safe and that malicious
actors cannot interfere with the system. Below are the main security considerations for RMI:

1. Security Manager & Policy Files

 Security Manager: Use a security manager to restrict the actions that remote objects and
clients can perform. This protects against potentially malicious code.
 Policy Files: Define permissions for remote objects in a security policy file to control
access to sensitive resources (e.g., files, network connections).
 Create a file with filename security_policy
o grant {
o permission [Link];
o };
 Configure Project Properties
o Right-click your project → Properties
o Select Run in the left panel
o In the VM Options field, add:
 -[Link] -[Link]=[Link]

2. RMI Registry Security

 Registry Security: The RMI registry can be a target for unauthorized access, so it should
be secured behind firewalls or using secure network configurations. Avoid exposing the
registry to the internet.
 Custom Registries: Consider creating custom registries to enforce stricter security
policies for binding remote objects.

3. Authentication & Access Control

 Authentication: Implement custom authentication mechanisms (e.g., username/password


or IP address verification) to ensure that only authorized clients can invoke remote
methods.
 Access Control: Use Java's security model to enforce access control, ensuring only
permitted clients can access sensitive services.

4. Encryption for Confidentiality

 SSL/TLS Encryption: Use SSL/TLS to encrypt communication between RMI clients


and servers, preventing eavesdropping and tampering with data in transit.
 Custom Socket Factories: Implement custom socket factories to enforce encrypted
communication or use secure protocols (e.g., SSL).
5. Data Integrity

 Message Authentication: Use techniques like Message Authentication Codes (MACs)


or digital signatures to ensure the integrity of data transmitted between clients and
servers, preventing tampering.

6. Codebase Security

 Trusted Codebase: If RMI involves downloading classes from a remote server, ensure
the server is trusted and the code is secured (e.g., using digital signatures or hashes).
 Code Integrity: Verify that downloaded classes haven't been tampered with before
execution.

7. Security Vulnerabilities

 Man-in-the-Middle (MITM): Without encryption (e.g., SSL/TLS), attackers can


intercept and alter communication. Use SSL/TLS to prevent MITM attacks.
 Denial of Service (DoS): RMI servers can be susceptible to DoS attacks. Mitigate this by
rate-limiting and ensuring proper resource management.
 Code Injection: Prevent execution of malicious code by securing the codebase and
implementing checks to validate the integrity of remote objects.

8. RMI with Java Security Manager

 Security Manager Enabling: Always use the security manager with the appropriate
policy files to define which operations are allowed for the RMI server and clients. This
provides a robust layer of protection from malicious actions.
9. Advantages and Disadvantages
Advantages:

 Simple to use (Java-native)


 Object-oriented approach
 Automatic garbage collection of remote objects
 Type safety (compile-time checking)

Disadvantages:

 Java-only (not suitable for heterogeneous systems)


 Can be slower than other RPC mechanisms
 Firewall issues with dynamic port allocation
 Security concerns with serialization
10. Best Practices
1. Design remote interfaces carefully (minimize remote calls)
2. Handle RemoteException properly
3. Consider using connection pooling for performance
4. Use version UIDs for serializable classes
5. Document remote methods thoroughly
6. Consider alternatives (REST, gRPC) for cross-platform needs

// Example of version UID


public class MyRemoteObject implements Serializable {
private static final long serialVersionUID = 1L;
// ...
}

These notes cover the fundamental aspects of Java RMI with practical examples. The calculator
example demonstrates a more complex scenario than the basic "Hello World", showing how to
pass parameters and return values in RMI applications.

You might also like