培訓(xùn)公司網(wǎng)站建設(shè)圖片外鏈生成
真正的救贖,并非廝殺后的勝利,而是能在苦難之中,找到生的力量和內(nèi)心的安寧。
——加繆Albert Camus
一、Rust + Java = ??
Java 和 Rust 是兩種現(xiàn)代編程語言,各自具有獨(dú)特的優(yōu)勢(shì),適用于不同的應(yīng)用場(chǎng)景。
1、Java 的優(yōu)勢(shì)
- 跨平臺(tái)性:Java 的“寫一次,運(yùn)行到處”的理念使得它能夠在各種操作系統(tǒng)上運(yùn)行,只要有 JVM(Java Virtual Machine)支持即可。
- 豐富的生態(tài)系統(tǒng):Java 擁有龐大的標(biāo)準(zhǔn)庫和第三方庫生態(tài)系統(tǒng),涵蓋了幾乎所有的開發(fā)需求,從 web 開發(fā)、數(shù)據(jù)庫訪問到大數(shù)據(jù)處理等。
- 成熟的工具鏈:Java 具有成熟的開發(fā)工具鏈,包括 IDE(如 IntelliJ IDEA、Eclipse)、構(gòu)建工具(如 Maven、Gradle)和調(diào)試工具,這些工具極大地提高了開發(fā)效率。
- 強(qiáng)大的社區(qū)支持:Java 社區(qū)非?;钴S,有大量的開源項(xiàng)目、文檔和教程,可以幫助開發(fā)者快速解決問題。
- 垃圾回收機(jī)制:Java 的自動(dòng)垃圾回收機(jī)制簡(jiǎn)化了內(nèi)存管理,減少了內(nèi)存泄漏和其他內(nèi)存相關(guān)錯(cuò)誤的風(fēng)險(xiǎn)。
- 企業(yè)級(jí)應(yīng)用:Java 在企業(yè)級(jí)應(yīng)用開發(fā)中占據(jù)重要地位,特別是在金融、電信和大型分布式系統(tǒng)中,Java 被廣泛使用。
- 多線程支持:Java 提供了強(qiáng)大的多線程支持,方便開發(fā)并發(fā)和并行程序。
2、Rust 的優(yōu)勢(shì)
- 內(nèi)存安全:Rust 的所有權(quán)系統(tǒng)和借用檢查器在編譯時(shí)保證了內(nèi)存安全,防止了常見的內(nèi)存錯(cuò)誤,如空指針引用、懸掛指針和緩沖區(qū)溢出。
- 高性能:Rust 生成的代碼接近 C 和 C++ 的性能,同時(shí)提供了更高的安全性和更少的運(yùn)行時(shí)開銷。
- 無畏并發(fā):Rust 的所有權(quán)模型使得編寫并發(fā)代碼更加安全和簡(jiǎn)單,避免了數(shù)據(jù)競(jìng)爭(zhēng)和死鎖等問題。
- 現(xiàn)代語言特性:Rust 支持模式匹配、閉包、泛型、trait 等現(xiàn)代編程語言特性,使得代碼更加簡(jiǎn)潔和可維護(hù)。
- 強(qiáng)類型系統(tǒng):Rust 的強(qiáng)類型系統(tǒng)在編譯時(shí)捕獲更多的錯(cuò)誤,提高了代碼的可靠性和可維護(hù)性。
- 零成本抽象:Rust 提供了高層次的抽象,但這些抽象在編譯后不會(huì)引入額外的運(yùn)行時(shí)開銷,實(shí)現(xiàn)了所謂的“零成本抽象”。
- 良好的文檔和工具鏈:Rust 提供了優(yōu)秀的文檔和工具鏈,包括 Cargo(包管理和構(gòu)建工具)、rustfmt(代碼格式化工具)和 Clippy(代碼審查工具),這些工具極大地提高了開發(fā)體驗(yàn)。
- 嵌入式和系統(tǒng)編程:Rust 非常適合嵌入式和系統(tǒng)級(jí)編程,能夠直接操作硬件,同時(shí)保持高安全性和性能。
3、Rust + Java 的應(yīng)用思路
Java 和 Rust 各有其獨(dú)特的優(yōu)勢(shì),適用于不同的應(yīng)用場(chǎng)景:
- Java?適合需要跨平臺(tái)兼容性、豐富生態(tài)系統(tǒng)和成熟工具鏈的企業(yè)級(jí)應(yīng)用和大型分布式系統(tǒng)。
- Rust?則適合需要高性能、內(nèi)存安全和并發(fā)控制的系統(tǒng)級(jí)編程、嵌入式開發(fā)以及對(duì)性能和安全性要求極高的應(yīng)用。
通過結(jié)合 Java 和 Rust 的優(yōu)勢(shì),可以在實(shí)際項(xiàng)目中實(shí)現(xiàn)更高效、安全和功能強(qiáng)大的解決方案。例如,可以使用 Java 實(shí)現(xiàn)業(yè)務(wù)邏輯和用戶界面,而使用 Rust 實(shí)現(xiàn)性能關(guān)鍵的底層模塊和系統(tǒng)組件。
4、應(yīng)用場(chǎng)景
- 性能關(guān)鍵模塊:在 Java 應(yīng)用中,某些性能關(guān)鍵的部分可以用 Rust 編寫,以提高執(zhí)行效率。例如,計(jì)算密集型算法、數(shù)據(jù)處理或圖像處理等任務(wù)可以用 Rust 實(shí)現(xiàn),然后通過 JNI(Java Native Interface)調(diào)用這些 Rust 函數(shù)。
- 內(nèi)存安全和并發(fā)控制:Rust 的所有權(quán)機(jī)制和借用檢查器可以幫助避免內(nèi)存泄漏和數(shù)據(jù)競(jìng)爭(zhēng)問題。在需要嚴(yán)格內(nèi)存管理和并發(fā)控制的場(chǎng)景下,可以用 Rust 編寫核心邏輯,并通過 FFI(Foreign Function Interface)與 Java 進(jìn)行交互。
- 系統(tǒng)級(jí)編程:對(duì)于需要直接操作系統(tǒng)資源或硬件的功能,例如文件系統(tǒng)操作、網(wǎng)絡(luò)通信或設(shè)備驅(qū)動(dòng)程序,可以用 Rust 編寫這些底層代碼,然后通過 JNI 或 JNA(Java Native Access)與 Java 應(yīng)用進(jìn)行交互。
- 跨平臺(tái)開發(fā):Rust 可以編譯成多種平臺(tái)的二進(jìn)制文件,而 Java 本身具有良好的跨平臺(tái)特性。在需要支持多種操作系統(tǒng)的應(yīng)用中,可以利用 Rust 編寫跨平臺(tái)的庫,并通過 Java 調(diào)用這些庫,從而實(shí)現(xiàn)跨平臺(tái)兼容性。
- 安全性要求高的應(yīng)用:在金融、醫(yī)療等對(duì)安全性要求極高的領(lǐng)域,可以用 Rust 編寫關(guān)鍵的安全模塊,如加密算法、身份驗(yàn)證等,然后通過 JNI 與 Java 應(yīng)用集成,以確保系統(tǒng)的整體安全性。
- 微服務(wù)架構(gòu):在微服務(wù)架構(gòu)中,不同的服務(wù)可以用不同的語言實(shí)現(xiàn)。如果某些微服務(wù)用 Rust 編寫,而其他服務(wù)用 Java 編寫,可以通過 RESTful API 或 gRPC 等方式進(jìn)行通信,實(shí)現(xiàn)互操作。
- 游戲開發(fā):游戲引擎或性能要求高的游戲邏輯可以用 Rust 編寫,而游戲的業(yè)務(wù)邏輯、界面等可以用 Java 編寫,通過 JNI 調(diào)用 Rust 實(shí)現(xiàn)高效的游戲運(yùn)行。
二、JNI:實(shí)現(xiàn) Rust 與 Java 互調(diào)的橋梁
1、如何理解 JNI
Java Native Interface(JNI)是 Java 平臺(tái)的一部分,它允許 Java 代碼與用其他編程語言(如 C、C++ )編寫的本地代碼進(jìn)行交互。JNI 的角色可以理解為橋梁或接口,連接了 Java 虛擬機(jī)(JVM)和本地代碼庫,使得兩者能夠相互調(diào)用和通信。
跨語言調(diào)用:JNI 使得 Java 程序能夠調(diào)用本地代碼中的函數(shù),也使得本地代碼能夠調(diào)用 Java 方法。這種雙向調(diào)用能力使得開發(fā)者可以在 Java 應(yīng)用中利用其他語言的特性和性能優(yōu)勢(shì)。
性能優(yōu)化:在某些情況下,Java 代碼可能無法提供足夠的性能,例如在處理大量數(shù)據(jù)或執(zhí)行復(fù)雜計(jì)算時(shí)。通過 JNI,可以將這些性能關(guān)鍵的部分用更高效的語言(如 C、C++)實(shí)現(xiàn),然后在 Java 中調(diào)用,從而提升整體應(yīng)用的性能。
訪問底層系統(tǒng)資源:Java 本身是一個(gè)高級(jí)語言,通常不直接提供對(duì)底層系統(tǒng)資源(如硬件設(shè)備、操作系統(tǒng) API)的訪問。通過 JNI,Java 程序可以調(diào)用本地代碼來訪問這些底層資源,實(shí)現(xiàn)系統(tǒng)級(jí)編程。
復(fù)用現(xiàn)有庫和代碼:很多已有的庫和代碼是用其他語言編寫的。通過 JNI,Java 程序可以直接調(diào)用這些現(xiàn)有的庫,而無需重新實(shí)現(xiàn),從而節(jié)省開發(fā)時(shí)間和成本。
內(nèi)存管理:JNI 提供了一套機(jī)制來管理 Java 和本地代碼之間的內(nèi)存交互。雖然 Java 有自動(dòng)垃圾回收機(jī)制,但本地代碼需要手動(dòng)管理內(nèi)存。JNI 提供了必要的工具和方法來確保內(nèi)存安全和有效管理。
錯(cuò)誤處理和調(diào)試:JNI 提供了一些工具和方法來處理和調(diào)試 Java 與本地代碼之間的交互問題。例如,通過 JNI 可以捕獲和處理本地代碼中的異常,并將其轉(zhuǎn)換為 Java 異常,從而在 Java 層面進(jìn)行處理。
平臺(tái)獨(dú)立性:盡管 JNI 允許調(diào)用本地代碼,這些本地代碼往往是平臺(tái)相關(guān)的。然而,JNI 本身作為一個(gè)標(biāo)準(zhǔn)接口,使得開發(fā)者可以編寫跨平臺(tái)的 Java 代碼,同時(shí)針對(duì)不同的平臺(tái)編寫相應(yīng)的本地代碼庫,從而實(shí)現(xiàn)一定程度的跨平臺(tái)兼容性。
總結(jié)來說,JNI 的角色是充當(dāng) Java 和本地代碼之間的橋梁,提供了一種機(jī)制,使得 Java 應(yīng)用能夠利用其他語言的特性和性能優(yōu)勢(shì),同時(shí)保持一定的靈活性和擴(kuò)展性。JNI 既然是 C 語言接口,那么理論上支持 C ABI 的語言都可以和 Java 語言互相調(diào)用,Rust 就是其中之一。
關(guān)于 JNI 的歷史背景以及更詳細(xì)的介紹可以參考?官方文檔
2、JNI 相關(guān)概念
Java 本地方法:在 Java 中聲明但由本地代碼實(shí)現(xiàn)的方法。
JNI 環(huán)境指針 (JNIEnv *
):用于訪問 JNI 提供的函數(shù)和 Java 虛擬機(jī)(JVM)的接口。
本地庫:包含本地方法實(shí)現(xiàn)的共享庫或動(dòng)態(tài)鏈接庫(如?.dll
、.so
?文件)。
Java 本地方法(Native Method)、JNI 環(huán)境指針(JNIEnv *)和本地庫在一起工作時(shí),通常遵循以下流程:
-
聲明本地方法:
在 Java 代碼中,你需要聲明一個(gè)本地方法。這個(gè)方法使用?native
?關(guān)鍵字,并且沒有方法體。例如:public class MyClass {public native void myNativeMethod();static {System.loadLibrary("MyNativeLib");} }
System.loadLibrary("MyNativeLib")
?用于加載包含本地方法實(shí)現(xiàn)的本地庫。 -
生成頭文件:
使用?javac
?編譯 Java 文件,然后使用?javah
?工具生成對(duì)應(yīng)的 C/C++ 頭文件。例如:javac MyClass.java javah -jni MyClass
這會(huì)生成一個(gè)名為?
MyClass.h
?的頭文件,其中包含 JNI 函數(shù)簽名。 -
實(shí)現(xiàn)本地方法:
在生成的頭文件基礎(chǔ)上,用 C 或 C++ 實(shí)現(xiàn)本地方法。例如:#include <jni.h> #include "MyClass.h"JNIEXPORT void JNICALL Java_MyClass_myNativeMethod(JNIEnv *env, jobject obj) {// 本地方法的實(shí)現(xiàn) }
-
編譯本地庫:
將實(shí)現(xiàn)本地方法的 C/C++ 代碼編譯成共享庫或動(dòng)態(tài)鏈接庫。例如,在 Linux 上可以使用?gcc
:gcc -shared -o libMyNativeLib.so -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux MyClass.c
在 Windows 上可以使用類似的命令生成?
.dll
?文件。 -
加載本地庫:
當(dāng) Java 程序運(yùn)行并調(diào)用?System.loadLibrary("MyNativeLib")
?時(shí),JVM 會(huì)加載指定的本地庫。 -
調(diào)用本地方法:
當(dāng) Java 代碼調(diào)用?myNativeMethod()
?時(shí),JVM 通過 JNI 調(diào)用對(duì)應(yīng)的本地方法實(shí)現(xiàn)。此時(shí),JNI 環(huán)境指針 (JNIEnv *
) 被傳遞給本地方法,允許它訪問 JNI 提供的函數(shù)和 JVM 的接口。 -
執(zhí)行本地代碼:
本地方法在本地庫中執(zhí)行,可以進(jìn)行各種操作,包括調(diào)用底層系統(tǒng) API、處理硬件設(shè)備、執(zhí)行高性能計(jì)算等。 -
返回結(jié)果:
如果本地方法有返回值,它會(huì)將結(jié)果返回給 Java 層。如果發(fā)生異常,本地方法可以通過?JNIEnv *
?拋出 Java 異常。
整個(gè)流程如下圖所示:
Java 層:MyClass.java (聲明本地方法)|v編譯 -> MyClass.class|v生成頭文件 -> MyClass.h|v
C/C++ 層:MyClass.c (實(shí)現(xiàn)本地方法)|v編譯 -> libMyNativeLib.so / MyNativeLib.dll|v
Java 層:System.loadLibrary("MyNativeLib")|v調(diào)用本地方法 -> JNI 調(diào)用 -> 執(zhí)行本地代碼|v返回結(jié)果 / 拋出異常
通過這種方式,Java 程序可以與本地代碼進(jìn)行交互,實(shí)現(xiàn)更底層的功能或優(yōu)化性能。
3、JNI 的 Rust 綁定
在 Rust 中和 Java 互相調(diào)用,可以使用原始的 JNI 接口,也就是自己聲明 JNI 的 C 函數(shù)原型,在Rust 里按照 C 的方式去調(diào)用,但這樣寫起來會(huì)很繁瑣,而且都是 unsafe 的操作。不過 Rust 社區(qū)里已經(jīng)有人基于原始的 JNI 接口,封裝好了一套 safe 的接口,crate 的名字就叫?jni?,用這個(gè)庫來開發(fā)就方便多了。
三、互調(diào)示例
Step1、定義一個(gè)異步耗時(shí)操作 CostTimeOption
Step2、Java 端調(diào)用 Rust 端,由 Rust 端執(zhí)行一個(gè)異步耗時(shí)操作?CostTimeOption
Step3、Rust 端調(diào)用 Java 端報(bào)告操作已消耗時(shí)長(zhǎng)和進(jìn)度
Step 1、創(chuàng)建一個(gè) Maven 項(xiàng)目
import java.time.Duration;
import java.time.LocalDateTime;/*** @version: V1.0* @author: 余衫馬* @description: MyJobAgent* @data: 2024-11-12 15:58**/
public class MyJobAgent {/*** 聲明一個(gè)本地方法* 將 MyJobAgent 實(shí)例作為參數(shù)傳遞給 Rust 端*/private static native void runCostTimeFuncAsync(MyJobAgent callback);/*** 開始執(zhí)行時(shí)間*/private static LocalDateTime startDatetime;// 用于加載包含本地方法實(shí)現(xiàn)的本地庫。static {System.loadLibrary("rust_jni_bingding_demo");}public static void main(String[] args) {startDatetime = LocalDateTime.now();runCostTimeFuncAsync(new MyJobAgent());}/*** 回調(diào)方法,由 Rust 端回調(diào) progress 進(jìn)度*/public void asyncCallback(float progress) {// 計(jì)算兩個(gè)時(shí)間點(diǎn)之間的 DurationDuration duration = Duration.between(startDatetime, LocalDateTime.now());// 獲取分鐘、秒和毫秒long minutes = duration.toMinutes();long seconds = duration.getSeconds();long millis = duration.toMillis();System.out.printf("當(dāng)前進(jìn)度:%f,已耗時(shí):%d 分 %d 秒 %d 毫秒\n", progress, minutes, seconds, millis);}
}
我們創(chuàng)建了一個(gè) MyJobAgent? 代理工作類,聲明了一個(gè)本地方法 runCostTimeFuncAsync ,參數(shù)是 MyJobAgent 實(shí)例是為了讓 Rust 端能調(diào)用該實(shí)例的回調(diào)方法 asyncCallback,
private static native void runCostTimeFuncAsync(MyJobAgent callback);
?而回調(diào)方法 asyncCallback 需要接收一個(gè)參數(shù)?progress 輸出進(jìn)度,并計(jì)算目前已耗時(shí)多久,
/*** 回調(diào)方法,由 Rust 端回調(diào) progress 進(jìn)度*/public void asyncCallback(float progress) {// 計(jì)算兩個(gè)時(shí)間點(diǎn)之間的 DurationDuration duration = Duration.between(startDatetime, LocalDateTime.now());// 獲取分鐘、秒和毫秒long minutes = duration.toMinutes();long seconds = duration.getSeconds();long millis = duration.toMillis();System.out.printf("當(dāng)前進(jìn)度:%f,已耗時(shí):%d 分 %d 秒 %d 毫秒", progress, minutes, seconds, millis);}
Linux 下的動(dòng)態(tài)庫 librust_jni_bingding_demo.so 只需要填?rust_jni_bingding_demo,
// 用于加載包含本地方法實(shí)現(xiàn)的本地庫。static {System.loadLibrary("rust_jni_bingding_demo");}
Step 2、創(chuàng)建一個(gè) Rust 項(xiàng)目
cargo new rust_jni_bingding_demo --lib
修改 Cargo.toml,添加 Rust jni 綁定庫,并且設(shè)置?crate_type = ["cdylib"]
[dependencies]
jni = "0.21.1"[lib]
crate_type = ["cdylib"]
修改 lib.rs,
use std::sync::mpsc; // 引入多生產(chǎn)者單消費(fèi)者通道模塊
use std::thread::{self}; // 引入線程模塊
use std::time::Duration; // 引入時(shí)間模塊use jni::objects::*; // 引入JNI對(duì)象模塊
use jni::sys::jfloat; // 引入JNI浮點(diǎn)數(shù)類型
use jni::JNIEnv; // 引入JNI環(huán)境模塊// 定義一個(gè)外部函數(shù),供Java調(diào)用
#[no_mangle]
pub extern "system" fn Java_MyJobAgent_runCostTimeFuncAsync<'local>(mut env: JNIEnv<'local>, // JNI環(huán)境參數(shù)_class: JClass<'local>, // 調(diào)用該方法的Java類callback: JObject<'local>, // 回調(diào)對(duì)象
) {// 獲取當(dāng)前Java虛擬機(jī)實(shí)例let jvm = env.get_java_vm().unwrap();// 創(chuàng)建全局引用,以便在其他線程中使用回調(diào)對(duì)象let mycallback = env.new_global_ref(callback).unwrap();// 創(chuàng)建一個(gè)多生產(chǎn)者單消費(fèi)者通道let (tx, rx) = mpsc::channel();// 啟動(dòng)一個(gè)新線程let _ = thread::spawn(move || {// 在線程中發(fā)送一個(gè)信號(hào),表示線程已經(jīng)啟動(dòng)tx.send(()).unwrap();// 將當(dāng)前線程附加到JVMlet mut myenv = jvm.attach_current_thread().unwrap();// 模擬一個(gè)耗時(shí)操作,并定期調(diào)用回調(diào)函數(shù)報(bào)告進(jìn)度for i in 0..100 {let progress = i as jfloat; // 將進(jìn)度轉(zhuǎn)換為JNI浮點(diǎn)數(shù)類型// 調(diào)用回調(diào)方法,將進(jìn)度傳遞給Java層 // 函數(shù)簽名為(float)voidmyenv.call_method(&mycallback, "asyncCallback", "(F)V", &[progress.into()]).unwrap();// 休眠100毫秒,模擬耗時(shí)操作thread::sleep(Duration::from_millis(100));}});// 接收線程啟動(dòng)信號(hào),確保線程已成功啟動(dòng)rx.recv().unwrap();
}
代碼解析:
- 引入必要的模塊:首先引入了標(biāo)準(zhǔn)庫中的
mpsc
、thread
和time
模塊,以及JNI相關(guān)的模塊。 - 定義外部函數(shù):定義了一個(gè)外部函數(shù)
Java_MyJobAgent_runCostTimeFuncAsync
,這個(gè)函數(shù)將被Java代碼調(diào)用。 - 獲取JVM實(shí)例:通過
env.get_java_vm()
獲取當(dāng)前的Java虛擬機(jī)實(shí)例。 - 創(chuàng)建全局引用:將回調(diào)對(duì)象創(chuàng)建為全局引用,以便在線程中使用。
- 創(chuàng)建通道:創(chuàng)建一個(gè)多生產(chǎn)者單消費(fèi)者通道,用于線程間通信。
- 啟動(dòng)新線程:啟動(dòng)一個(gè)新線程,在新線程中執(zhí)行耗時(shí)操作。
- 附加線程到JVM:將新線程附加到JVM,以便在新線程中調(diào)用Java方法。
- 模擬耗時(shí)操作:在循環(huán)中模擬一個(gè)耗時(shí)操作,每次循環(huán)都會(huì)調(diào)用一次回調(diào)方法,將當(dāng)前進(jìn)度傳遞給Java層,并休眠100毫秒。
- 接收線程啟動(dòng)信號(hào):主線程等待接收子線程發(fā)送的啟動(dòng)信號(hào),確保子線程已成功啟動(dòng)。
這樣,通過上述步驟,我們實(shí)現(xiàn)了一個(gè)異步任務(wù),并在任務(wù)執(zhí)行過程中定期向Java層報(bào)告進(jìn)度。
Step 3、編譯代碼
編譯 Rust 庫
cargo build
我這里用的 linux 系統(tǒng),動(dòng)態(tài)庫文件名為 librust_jni_bingding_demo.so,如果是 Windows 系統(tǒng),文件名為 librust_jni_bingding_demo.dll,
編譯 Java 代碼
修改 pom.xml,在構(gòu)建配置文件中指定主類,
<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>3.2.0</version><configuration><archive><manifest><addDefaultImplementationEntries>true</addDefaultImplementationEntries><mainClass>MyJobAgent</mainClass></manifest></archive></configuration></plugin></plugins></build>
然后執(zhí)行 maven 打包指令,?
mvn package
在 target 目錄下生成 classes 字節(jié)碼文件與 RustJniDemo-1.0-SNAPSHOT.jar 。?
Step 4、運(yùn)行效果
這里使用的是 Open JDK8,
(base) sam@sam-PC:~/AwesomeWorkSpace/RustStudy/jni/rust_jni_bingding_demo$ java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-8u212-b01-1~deb9u1-b01)
OpenJDK 64-Bit Server VM (build 25.212-b01, mixed mode)
# 臨時(shí)添加環(huán)境變量,否則會(huì)報(bào)錯(cuò)找不到庫文件
# export PATH=$PATH:~/AwesomeWorkSpace/RustStudy/rust_jni_binding_demo/target/debug
java -Djava.library.path=target/debug -classpath target/classes MyJobAgent
# 或者直接跑 jar 包
java -Djava.library.path=target/debug -jar target/RustJniDemo-1.0-SNAPSHOT.jar
-
-Djava.library.path=target/debug
:這是一個(gè)系統(tǒng)屬性設(shè)置,-D
選項(xiàng)用于定義系統(tǒng)屬性。在這里,java.library.path
屬性被設(shè)置為target/debug
,這通常是用來指定本地庫(如JNI庫)的搜索路徑。 -
-classpath target/classes
:這是指定類路徑的選項(xiàng),-classpath
或-cp
用于告訴JVM在哪里可以找到用戶定義的類和包。在這個(gè)例子中,類路徑被設(shè)置為target/classes
,這意味著JVM會(huì)在target/classes
目錄下查找需要的類文件。 -
MyJobAgent
:這是要運(yùn)行的主類的名稱。這個(gè)類應(yīng)該包含一個(gè)public static void main(String[] args)
方法,這是Java應(yīng)用程序的入口點(diǎn)。
四、總結(jié)
通過以上示例,我們成功實(shí)現(xiàn)了 Rust 與 Java 的互調(diào)。利用 JNI 技術(shù),可以充分發(fā)揮 Rust 的性能優(yōu)勢(shì),同時(shí)保持 Java 的跨平臺(tái)特性。這種技術(shù)組合適用于對(duì)性能要求較高的應(yīng)用場(chǎng)景,如圖像處理、數(shù)據(jù)分析和系統(tǒng)級(jí)編程等。
參考資料
Rust與Java交互-JNI模塊編寫-實(shí)踐總結(jié) - Rust語言中文社區(qū)
Leveraging Rust in our high-performance Java database
https://docs.oracle.com/javase/8/docs/technotes/guides/jni/
jni - Rust
https://github.com/jni-rs/jni-rs