Java RMI - Panduan Cepat
RMI adalah singkatan dari Remote Method Invocation. Ini adalah mekanisme yang memungkinkan objek yang berada di satu sistem (JVM) untuk mengakses / memanggil objek yang berjalan di JVM lain.
RMI digunakan untuk membangun aplikasi terdistribusi; itu menyediakan komunikasi jarak jauh antara program Java. Itu sudah disediakan dalam paketjava.rmi.
Arsitektur Aplikasi RMI
Dalam aplikasi RMI, kami menulis dua program, a server program (berada di server) dan a client program (berada di klien).
Di dalam program server, objek jarak jauh dibuat dan referensi objek itu tersedia untuk klien (menggunakan registri).
Program klien meminta objek jarak jauh di server dan mencoba menjalankan metodenya.
Diagram berikut menunjukkan arsitektur aplikasi RMI.
Sekarang mari kita bahas komponen dari arsitektur ini.
Transport Layer- Lapisan ini menghubungkan klien dan server. Ini mengelola koneksi yang ada dan juga mengatur koneksi baru.
Stub- Stub adalah representasi (proxy) dari objek jarak jauh di klien. Itu berada di sistem klien; itu bertindak sebagai pintu gerbang untuk program klien.
Skeleton - Ini adalah objek yang berada di sisi server. stub berkomunikasi dengan kerangka ini untuk meneruskan permintaan ke objek jarak jauh.
RRL(Remote Reference Layer) - Ini adalah lapisan yang mengelola referensi yang dibuat oleh klien ke objek jarak jauh.
Bekerja dari Aplikasi RMI
Poin-poin berikut meringkas cara kerja aplikasi RMI -
Ketika klien membuat panggilan ke objek jarak jauh, itu diterima oleh rintisan yang akhirnya meneruskan permintaan ini ke RRL.
Saat RRL sisi klien menerima permintaan, itu memanggil metode yang disebut invoke() dari objek remoteRef. Ini meneruskan permintaan ke RRL di sisi server.
RRL di sisi server meneruskan permintaan ke Skeleton (proxy di server) yang akhirnya memanggil objek yang diperlukan di server.
Hasilnya diteruskan kembali ke klien.
Marshalling dan Unmarshalling
Setiap kali klien memanggil metode yang menerima parameter pada objek jarak jauh, parameter tersebut digabungkan ke dalam pesan sebelum dikirim melalui jaringan. Parameter ini mungkin tipe atau objek primitif. Dalam kasus tipe primitif, parameter disatukan dan sebuah header dilampirkan padanya. Jika parameternya adalah objek, maka mereka akan diserialkan. Proses ini dikenal sebagaimarshalling.
Di sisi server, parameter yang dikemas dipisahkan dan kemudian metode yang diperlukan dipanggil. Proses ini dikenal sebagaiunmarshalling.
Registri RMI
Registri RMI adalah namespace tempat semua objek server ditempatkan. Setiap kali server membuat objek, itu mendaftarkan objek ini dengan RMIregistry (menggunakanbind() atau reBind()metode). Ini didaftarkan menggunakan nama unik yang dikenal sebagaibind name.
Untuk memanggil objek jarak jauh, klien membutuhkan referensi dari objek itu. Pada saat itu, klien mengambil objek dari registri menggunakan nama pengikatnya (menggunakanlookup() metode).
Ilustrasi berikut menjelaskan keseluruhan proses -
Tujuan RMI
Berikut adalah tujuan RMI -
- Untuk meminimalkan kompleksitas aplikasi.
- Untuk menjaga keamanan tipe.
- Pengumpulan sampah yang didistribusikan.
- Minimalkan perbedaan antara bekerja dengan objek lokal dan jarak jauh.
Untuk menulis aplikasi Java RMI, Anda harus mengikuti langkah-langkah di bawah ini -
- Tentukan antarmuka jarak jauh
- Kembangkan kelas implementasi (objek jarak jauh)
- Kembangkan program server
- Kembangkan program klien
- Kompilasi aplikasi
- Jalankan aplikasi
Mendefinisikan Antarmuka Jarak Jauh
Antarmuka jarak jauh menyediakan deskripsi semua metode objek jarak jauh tertentu. Klien berkomunikasi dengan antarmuka jarak jauh ini.
Untuk membuat antarmuka jarak jauh -
Buat antarmuka yang memperluas antarmuka yang telah ditentukan sebelumnya Remote yang termasuk dalam paket.
Deklarasikan semua metode bisnis yang dapat dipanggil oleh klien di antarmuka ini.
Karena ada kemungkinan masalah jaringan selama panggilan jarak jauh, pengecualian bernama RemoteExceptionmungkin terjadi; buang itu.
Berikut adalah contoh antarmuka jarak jauh. Di sini kami telah mendefinisikan antarmuka dengan namaHello dan memiliki metode yang disebut printMsg().
import java.rmi.Remote;
import java.rmi.RemoteException;
// Creating Remote interface for our application
public interface Hello extends Remote {
void printMsg() throws RemoteException;
}
Mengembangkan Kelas Implementasi (Objek Jarak Jauh)
Kita perlu mengimplementasikan antarmuka jarak jauh yang dibuat pada langkah sebelumnya. (Kita bisa menulis kelas implementasi secara terpisah atau kita bisa langsung membuat program server mengimplementasikan antarmuka ini.)
Untuk mengembangkan kelas implementasi -
- Implementasikan antarmuka yang dibuat pada langkah sebelumnya.
- Menyediakan implementasi untuk semua metode abstrak dari antarmuka jarak jauh.
Berikut adalah kelas implementasi. Di sini, kami telah membuat kelas bernamaImplExample dan mengimplementasikan antarmuka Hello dibuat pada langkah sebelumnya dan disediakan body untuk metode ini yang mencetak pesan.
// Implementing the remote interface
public class ImplExample implements Hello {
// Implementing the interface method
public void printMsg() {
System.out.println("This is an example RMI program");
}
}
Mengembangkan Program Server
Program server RMI harus mengimplementasikan antarmuka jarak jauh atau memperluas kelas implementasi. Di sini, kita harus membuat objek jarak jauh dan mengikatnya keRMIregistry.
Untuk mengembangkan program server -
Buat kelas klien dari mana Anda ingin memanggil objek jarak jauh.
Create a remote object dengan membuat instance kelas implementasi seperti yang ditunjukkan di bawah ini.
Ekspor objek jarak jauh menggunakan metode ini exportObject() dari kelas bernama UnicastRemoteObject yang termasuk dalam paket java.rmi.server.
Dapatkan registri RMI menggunakan file getRegistry() metode dari LocateRegistry kelas yang termasuk dalam paket java.rmi.registry.
Ikat objek jarak jauh yang dibuat ke registri menggunakan ekstensi bind() metode kelas bernama Registry. Untuk metode ini, berikan string yang mewakili nama bind dan objek yang diekspor, sebagai parameter.
Berikut adalah contoh program server RMI.
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class Server extends ImplExample {
public Server() {}
public static void main(String args[]) {
try {
// Instantiating the implementation class
ImplExample obj = new ImplExample();
// Exporting the object of implementation class
// (here we are exporting the remote object to the stub)
Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);
// Binding the remote object (stub) in the registry
Registry registry = LocateRegistry.getRegistry();
registry.bind("Hello", stub);
System.err.println("Server ready");
} catch (Exception e) {
System.err.println("Server exception: " + e.toString());
e.printStackTrace();
}
}
}
Mengembangkan Program Klien
Tulis program klien di dalamnya, ambil objek jarak jauh dan panggil metode yang diperlukan menggunakan objek ini.
Untuk mengembangkan program klien -
Buat kelas klien dari tempat Anda ingin memanggil objek jarak jauh.
Dapatkan registri RMI menggunakan file getRegistry() metode dari LocateRegistry kelas yang termasuk dalam paket java.rmi.registry.
Ambil objek dari registri menggunakan metode ini lookup() dari kelas Registry yang termasuk dalam paket java.rmi.registry.
Untuk metode ini, Anda perlu meneruskan nilai string yang mewakili nama bind sebagai parameter. Ini akan mengembalikan Anda objek jarak jauh.
Lookup () mengembalikan sebuah objek berjenis remote, lalu transmisikan ke tipe Hello.
Terakhir, panggil metode yang diperlukan menggunakan objek jarak jauh yang diperoleh.
Berikut adalah contoh program klien RMI.
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
private Client() {}
public static void main(String[] args) {
try {
// Getting the registry
Registry registry = LocateRegistry.getRegistry(null);
// Looking up the registry for the remote object
Hello stub = (Hello) registry.lookup("Hello");
// Calling the remote method using the obtained object
stub.printMsg();
// System.out.println("Remote method invoked");
} catch (Exception e) {
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}
}
Menyusun Aplikasi
Untuk mengkompilasi aplikasi -
- Kompilasi antarmuka Remote.
- Kompilasi kelas implementasi.
- Kompilasi program server.
- Kompilasi program klien.
Atau,
Buka folder tempat Anda menyimpan semua program dan kompilasi semua file Java seperti yang ditunjukkan di bawah ini.
Javac *.java
Menjalankan Aplikasi
Step 1 - Mulai rmi registri menggunakan perintah berikut.
start rmiregistry
Ini akan memulai rmi registri pada jendela terpisah seperti yang ditunjukkan di bawah ini.
Step 2 - Jalankan file kelas server seperti yang ditunjukkan di bawah ini.
Java Server
Step 3 - Jalankan file kelas klien seperti yang ditunjukkan di bawah ini.
java Client
Verification - Segera Anda memulai klien, Anda akan melihat output berikut di server.
Pada bab sebelumnya, kami membuat contoh aplikasi RMI. Dalam bab ini, kami akan menjelaskan cara membuat aplikasi RMI di mana klien memanggil metode yang menampilkan jendela GUI (JavaFX).
Mendefinisikan Antarmuka Jarak Jauh
Di sini, kami mendefinisikan antarmuka jarak jauh bernama Hello dengan metode bernama animation() di dalamnya.
import java.rmi.Remote;
import java.rmi.RemoteException;
// Creating Remote interface for our application
public interface Hello extends Remote {
void animation() throws RemoteException;
}
Mengembangkan Kelas Implementasi
Di kelas Implementasi (Remote Object) dari aplikasi ini, kami mencoba membuat jendela yang menampilkan konten GUI, menggunakan JavaFX.
import javafx.animation.RotateTransition;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;
// Implementing the remote interface
public class FxSample extends Application implements Hello {
@Override
public void start(Stage stage) {
// Drawing a Box
Box box = new Box();
// Setting the properties of the Box
box.setWidth(150.0);
box.setHeight(150.0);
box.setDepth(100.0);
// Setting the position of the box
box.setTranslateX(350);
box.setTranslateY(150);
box.setTranslateZ(50);
// Setting the text
Text text = new Text(
"Type any letter to rotate the box, and click on the box to stop the rotation");
// Setting the font of the text
text.setFont(Font.font(null, FontWeight.BOLD, 15));
// Setting the color of the text
text.setFill(Color.CRIMSON);
// Setting the position of the text
text.setX(20);
text.setY(50);
// Setting the material of the box
PhongMaterial material = new PhongMaterial();
material.setDiffuseColor(Color.DARKSLATEBLUE);
// Setting the diffuse color material to box
box.setMaterial(material);
// Setting the rotation animation to the box
RotateTransition rotateTransition = new RotateTransition();
// Setting the duration for the transition
rotateTransition.setDuration(Duration.millis(1000));
// Setting the node for the transition
rotateTransition.setNode(box);
// Setting the axis of the rotation
rotateTransition.setAxis(Rotate.Y_AXIS);
// Setting the angle of the rotation
rotateTransition.setByAngle(360);
// Setting the cycle count for the transition
rotateTransition.setCycleCount(50);
// Setting auto reverse value to false
rotateTransition.setAutoReverse(false);
// Creating a text filed
TextField textField = new TextField();
// Setting the position of the text field
textField.setLayoutX(50);
textField.setLayoutY(100);
// Handling the key typed event
EventHandler<KeyEvent> eventHandlerTextField = new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
// Playing the animation
rotateTransition.play();
}
};
// Adding an event handler to the text feld
textField.addEventHandler(KeyEvent.KEY_TYPED, eventHandlerTextField);
// Handling the mouse clicked event(on box)
EventHandler<javafx.scene.input.MouseEvent> eventHandlerBox =
new EventHandler<javafx.scene.input.MouseEvent>() {
@Override
public void handle(javafx.scene.input.MouseEvent e) {
rotateTransition.stop();
}
};
// Adding the event handler to the box
box.addEventHandler(javafx.scene.input.MouseEvent.MOUSE_CLICKED, eventHandlerBox);
// Creating a Group object
Group root = new Group(box, textField, text);
// Creating a scene object
Scene scene = new Scene(root, 600, 300);
// Setting camera
PerspectiveCamera camera = new PerspectiveCamera(false);
camera.setTranslateX(0);
camera.setTranslateY(0);
camera.setTranslateZ(0);
scene.setCamera(camera);
// Setting title to the Stage
stage.setTitle("Event Handlers Example");
// Adding scene to the stage
stage.setScene(scene);
// Displaying the contents of the stage
stage.show();
}
// Implementing the interface method
public void animation() {
launch();
}
}
Program Server
Program server RMI harus mengimplementasikan antarmuka jarak jauh atau memperluas kelas implementasi. Di sini, kita harus membuat objek jarak jauh dan mengikatnya keRMIregistry.
Berikut adalah program server dari aplikasi ini. Di sini, kami akan memperluas kelas yang dibuat di atas, membuat objek jarak jauh, dan mendaftarkannya ke registri RMI dengan nama bindhello.
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class Server extends FxSample {
public Server() {}
public static void main(String args[]) {
try {
// Instantiating the implementation class
FxSample obj = new FxSample();
// Exporting the object of implementation class
// (here we are exporting the remote object to the stub)
Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);
// Binding the remote object (stub) in the registry
Registry registry = LocateRegistry.getRegistry();
registry.bind("Hello", stub);
System.err.println("Server ready");
} catch (Exception e) {
System.err.println("Server exception: " + e.toString());
e.printStackTrace();
}
}
}
Program Klien
Berikut adalah program klien dari aplikasi ini. Di sini, kami mengambil objek jarak jauh dan menjalankan metode bernamaanimation().
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
private Client() {}
public static void main(String[] args) {
try {
// Getting the registry
Registry registry = LocateRegistry.getRegistry(null);
// Looking up the registry for the remote object
Hello stub = (Hello) registry.lookup("Hello");
// Calling the remote method using the obtained object
stub.animation();
System.out.println("Remote method invoked");
} catch (Exception e) {
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}
}
Langkah-langkah untuk Menjalankan Contoh
Berikut adalah langkah-langkah menjalankan Contoh RMI kami.
Step 1 - Buka folder tempat Anda menyimpan semua program dan kompilasi semua file Java seperti yang ditunjukkan di bawah ini.
Javac *.java
Step 2 - Mulai rmi registri menggunakan perintah berikut.
start rmiregistry
Ini akan memulai rmi registri pada jendela terpisah seperti yang ditunjukkan di bawah ini.
Step 3 - Jalankan file kelas server seperti yang ditunjukkan di bawah ini.
Java Server
Step 4 - Jalankan file kelas klien seperti yang ditunjukkan di bawah ini.
java Client
Verification - Segera Anda memulai klien, Anda akan melihat output berikut di server.
Pada bab sebelumnya, kami membuat contoh aplikasi RMI di mana klien memanggil metode yang menampilkan jendela GUI (JavaFX).
Pada bab ini, kita akan mengambil contoh untuk melihat bagaimana program klien dapat mengambil record dari sebuah tabel di database MySQL yang berada di server.
Asumsikan kita memiliki tabel bernama student_data di database details seperti gambar dibawah.
+----+--------+--------+------------+---------------------+
| ID | NAME | BRANCH | PERCENTAGE | EMAIL |
+----+--------+--------+------------+---------------------+
| 1 | Ram | IT | 85 | [email protected] |
| 2 | Rahim | EEE | 95 | [email protected] |
| 3 | Robert | ECE | 90 | [email protected] |
+----+--------+--------+------------+---------------------+
Asumsikan nama pengguna adalah myuser dan kata sandinya adalah password.
Membuat Kelas Siswa
Membuat Student kelas dengan setter dan getter metode seperti yang ditunjukkan di bawah ini.
public class Student implements java.io.Serializable {
private int id, percent;
private String name, branch, email;
public int getId() {
return id;
}
public String getName() {
return name;
}
public String getBranch() {
return branch;
}
public int getPercent() {
return percent;
}
public String getEmail() {
return email;
}
public void setID(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setBranch(String branch) {
this.branch = branch;
}
public void setPercent(int percent) {
this.percent = percent;
}
public void setEmail(String email) {
this.email = email;
}
}
Mendefinisikan Antarmuka Jarak Jauh
Tentukan antarmuka jarak jauh. Di sini, kami mendefinisikan antarmuka jarak jauh bernamaHello dengan metode bernama getStudents ()di dalamnya. Metode ini mengembalikan daftar yang berisi objek kelasStudent.
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.*;
// Creating Remote interface for our application
public interface Hello extends Remote {
public List<Student> getStudents() throws Exception;
}
Mengembangkan Kelas Implementasi
Buat kelas dan implementasikan yang dibuat di atas interface.
Di sini kami menerapkan getStudents() metode dari Remote interface. Ketika Anda memanggil metode ini, itu mengambil catatan dari tabel bernamastudent_data. Menyetel nilai-nilai ini ke kelas Student menggunakan metode penyetelnya, menambahkannya ke objek daftar dan mengembalikan daftar itu.
import java.sql.*;
import java.util.*;
// Implementing the remote interface
public class ImplExample implements Hello {
// Implementing the interface method
public List<Student> getStudents() throws Exception {
List<Student> list = new ArrayList<Student>();
// JDBC driver name and database URL
String JDBC_DRIVER = "com.mysql.jdbc.Driver";
String DB_URL = "jdbc:mysql://localhost:3306/details";
// Database credentials
String USER = "myuser";
String PASS = "password";
Connection conn = null;
Statement stmt = null;
//Register JDBC driver
Class.forName("com.mysql.jdbc.Driver");
//Open a connection
System.out.println("Connecting to a selected database...");
conn = DriverManager.getConnection(DB_URL, USER, PASS);
System.out.println("Connected database successfully...");
//Execute a query
System.out.println("Creating statement...");
stmt = conn.createStatement();
String sql = "SELECT * FROM student_data";
ResultSet rs = stmt.executeQuery(sql);
//Extract data from result set
while(rs.next()) {
// Retrieve by column name
int id = rs.getInt("id");
String name = rs.getString("name");
String branch = rs.getString("branch");
int percent = rs.getInt("percentage");
String email = rs.getString("email");
// Setting the values
Student student = new Student();
student.setID(id);
student.setName(name);
student.setBranch(branch);
student.setPercent(percent);
student.setEmail(email);
list.add(student);
}
rs.close();
return list;
}
}
Program Server
Program server RMI harus mengimplementasikan antarmuka jarak jauh atau memperluas kelas implementasi. Di sini, kita harus membuat objek jarak jauh dan mengikatnya keRMI registry.
Berikut adalah program server dari aplikasi ini. Di sini, kami akan memperluas kelas yang dibuat di atas, membuat objek jarak jauh dan mendaftarkannya ke registri RMI dengan nama bindhello.
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class Server extends ImplExample {
public Server() {}
public static void main(String args[]) {
try {
// Instantiating the implementation class
ImplExample obj = new ImplExample();
// Exporting the object of implementation class (
here we are exporting the remote object to the stub)
Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);
// Binding the remote object (stub) in the registry
Registry registry = LocateRegistry.getRegistry();
registry.bind("Hello", stub);
System.err.println("Server ready");
} catch (Exception e) {
System.err.println("Server exception: " + e.toString());
e.printStackTrace();
}
}
}
Program Klien
Berikut adalah program klien dari aplikasi ini. Di sini, kami mengambil objek jarak jauh dan menjalankan metode bernamagetStudents(). Ini mengambil catatan tabel dari objek daftar dan menampilkannya.
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.*;
public class Client {
private Client() {}
public static void main(String[] args)throws Exception {
try {
// Getting the registry
Registry registry = LocateRegistry.getRegistry(null);
// Looking up the registry for the remote object
Hello stub = (Hello) registry.lookup("Hello");
// Calling the remote method using the obtained object
List<Student> list = (List)stub.getStudents();
for (Student s:list)v {
// System.out.println("bc "+s.getBranch());
System.out.println("ID: " + s.getId());
System.out.println("name: " + s.getName());
System.out.println("branch: " + s.getBranch());
System.out.println("percent: " + s.getPercent());
System.out.println("email: " + s.getEmail());
}
// System.out.println(list);
} catch (Exception e) {
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}
}
Langkah-langkah untuk Menjalankan Contoh
Berikut adalah langkah-langkah menjalankan Contoh RMI kami.
Step 1 - Buka folder tempat Anda menyimpan semua program dan kompilasi semua file Java seperti yang ditunjukkan di bawah ini.
Javac *.java
Step 2 - Mulai rmi registri menggunakan perintah berikut.
start rmiregistry
Ini akan memulai rmi registri pada jendela terpisah seperti yang ditunjukkan di bawah ini.
Step 3 - Jalankan file kelas server seperti yang ditunjukkan di bawah ini.
Java Server
Step 4 - Jalankan file kelas klien seperti yang ditunjukkan di bawah ini.
java Client