Remote Method Invocation (RMI) là một cơ chế trong Java cho phép gọi phương thức từ xa (trên một JVM khác) giống như cách gọi phương thức cục bộ. RMI giúp các đối tượng ở các JVM khác nhau giao tiếp với nhau, qua mạng hoặc trên cùng một máy tính. Để xây dựng và triển khai một ứng dụng RMI, cần thực hiện một số bước cụ thể.

Dưới đây là các bước cơ bản để một chương trình RMI hoạt động:


1. Tạo một Interface cho các phương thức từ xa

  • Interface này sẽ khai báo các phương thức mà client có thể gọi từ xa. Interface phải kế thừa từ java.rmi.Remote, và các phương thức cần khai báo phải ném ra ngoại lệ RemoteException.

Ví dụ:

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

public interface MyRemoteInterface extends Remote {
    // Phương thức từ xa phải ném RemoteException
    public String sayHello() throws RemoteException;
}

2. Cài đặt Interface từ xa (Remote Object)

  • Bạn cần tạo một lớp cài đặt interface từ xa và lớp này phải kế thừa từ java.rmi.server.UnicastRemoteObject.
  • Trong lớp cài đặt, các phương thức từ xa được triển khai đầy đủ logic cần thiết.

Ví dụ:

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

public class MyRemoteImpl extends UnicastRemoteObject implements MyRemoteInterface {

    // Constructor bắt buộc phải ném RemoteException
    protected MyRemoteImpl() throws RemoteException {
        super();
    }

    // Cài đặt phương thức từ xa
    @Override
    public String sayHello() throws RemoteException {
        return "Hello from RMI Server!";
    }
}

3. Tạo và khởi chạy RMI Registry

  • RMI Registry là một máy chủ trung gian dùng để quản lý các đối tượng từ xa. Nó cần được khởi động trước khi client có thể truy cập vào các phương thức từ xa.
  • Có thể khởi động RMI registry từ dòng lệnh bằng lệnh rmiregistry hoặc thông qua mã Java bằng cách sử dụng LocateRegistry.createRegistry().

Ví dụ khởi động RMI Registry từ mã Java:

import java.rmi.registry.LocateRegistry;

public class RMIServer {
    public static void main(String[] args) {
        try {
            // Tạo RMI registry trên cổng mặc định 1099
            LocateRegistry.createRegistry(1099);
            System.out.println("RMI Registry is running on port 1099...");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4. Đăng ký đối tượng từ xa với RMI Registry

  • Sau khi khởi tạo RMI registry, ta cần bind đối tượng từ xa (remote object) vào registry để nó có thể được truy cập bởi các client.
  • Sử dụng lớp Naming để đăng ký đối tượng từ xa với RMI registry.

Ví dụ:

import java.rmi.Naming;

public class RMIServer {
    public static void main(String[] args) {
        try {
            // Tạo RMI registry
            LocateRegistry.createRegistry(1099);
            System.out.println("RMI Registry is running on port 1099...");

            // Tạo đối tượng từ xa
            MyRemoteInterface remoteObject = new MyRemoteImpl();

            // Đăng ký đối tượng với RMI registry
            Naming.rebind("rmi://localhost:1099/RemoteHello", remoteObject);
            System.out.println("Remote object is bound to the registry...");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

5. Tạo Client để gọi các phương thức từ xa

  • Client sẽ tìm và gọi các phương thức từ xa qua RMI registry.
  • Sử dụng lớp Naming.lookup() để lấy đối tượng từ xa từ RMI registry, sau đó gọi các phương thức như một đối tượng cục bộ.

Ví dụ:

import java.rmi.Naming;

public class RMIClient {
    public static void main(String[] args) {
        try {
            // Tìm đối tượng từ xa thông qua RMI registry
            MyRemoteInterface remoteObject = (MyRemoteInterface) Naming.lookup("rmi://localhost:1099/RemoteHello");

            // Gọi phương thức từ xa
            String response = remoteObject.sayHello();
            System.out.println("Response from server: " + response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

6. Khởi động Server và Client

  • Khởi động RMI Server:
    • Chạy RMIServer.java để khởi tạo RMI registry và đăng ký đối tượng từ xa.
  • Chạy Client:
    • Sau khi server đã khởi động, chạy RMIClient.java để gọi phương thức từ xa từ server.

7. Sử dụng rmic để biên dịch stub (nếu cần)

  • Trong phiên bản Java trước đây, bạn cần phải chạy lệnh rmic để tạo stubskeleton cho các đối tượng từ xa. Tuy nhiên, từ Java 5 trở đi, Java đã tự động xử lý quá trình tạo stub. Bạn không cần thực hiện bước này nữa trừ khi sử dụng phiên bản Java cũ.

8. Một số lưu ý khi sử dụng RMI:

  • RemoteException: Mọi phương thức từ xa trong RMI phải khai báo ném ngoại lệ RemoteException, vì nó xử lý các vấn đề liên quan đến mạng.
  • Serializability: Các đối tượng truyền qua RMI (các đối số hoặc kết quả của phương thức từ xa) phải là các đối tượng serializable, nghĩa là các đối tượng đó phải cài đặt giao diện Serializable.

Kết luận

Để tạo một chương trình RMI hoạt động, cần thực hiện các bước chính như thiết kế interface từ xa, triển khai interface, đăng ký đối tượng với RMI registry, và tạo client để gọi các phương thức từ xa. Quá trình này cho phép các JVM khác nhau có thể giao tiếp và trao đổi dữ liệu, đồng thời thực hiện các thao tác từ xa thông qua mạng.