一文解秘Rust如何与Java互操作

本博客所有文章除特别声明外,均采用CC BY-NC-SA 4.0许可协议。转载请注明来自 唯你
使用场景
JAVA 与 Rust 互操作让 Rust 可以背靠 Java 大生态来做更多事情,而 Java 也可以享受 Rust 语言特性的内存安全,所有权机制,无畏并发。
互操作的典型场景包括:
- 性能优化:利用 Rust 处理计算密集型任务,提高 Java 应用的整体性能。
- 系统级编程:结合 Rust 的底层控制能力与 Java 的高级抽象,实现更高效的系统交互。
- 跨平台开发:使用 Rust 编写核心逻辑,通过 JNI 在不同平台上与 Java 交互,实现高效跨平台开发。
- 安全关键应用:在金融、医疗等领域,利用 Rust 处理敏感数据和核心功能,保证高度安全性。
- 实时系统:在游戏引擎、音频处理等延迟敏感的应用中,使用 Rust 处理时间关键部分。
背景知识
JNI

- 全称 Java Native Interface,它允许 Java 代码与其他语言(如 C 或 C++)编写的应用程序进行互操作。
- JNI Specification:这是 JNI 的官方规范,详细描述了 JNI 的使用方法、接口和功能。
Java 虚拟机(JVM)

JNI 是 Java 虚拟机的一部分,JVM 在启动时为每个线程创建一个 JNI 环境。JNI 环境包括指向 JVM 内部数据结构的指针,这些数据结构用于存储 Java 对象、方法和字段的信息。
JNIEnv (JNI 环境)

JNIEnv是一个指向结构体的指针,代表当前线程的 JNI 环境。它包含所有 JNI 相关函数的指针,让你能在本地代码中使用这些函数。每个线程都有自己独立的JNIEnv,所以不能在不同线程间传递这个指针。- 可以将
JNIEnv视为一个"翻译器"。当 Rust 代码需要与 Java 交互时,它通过这个"翻译器"发送请求,当调用 Java 方法或获取 Java 对象的属性。每个线程都拥有自己独立的"翻译器",这确保了各线程与 Java 交互时的独立性。
另外
- 当 Java 代码调用本地方法时,JVM 会加载相应的本地库并创建一个
JNIEnv指针。 - 本地代码可以使用这个指针访问 JNI 提供的函数,进行 Java 对象的操作。
- 每个线程有独立
JNIEnv,保证线程安全。新线程需调用AttachCurrentThread获取对应JNIEnv。 - JNI 提供了数据类型转换机制,实现 Java 与 C/C++之间的数据传递。
在 Rust 生态中使用 jni 0.21.1 库可以实现与 Java 代码的交互。
JNI 0.21.1 简介
该项目为 Rust 提供了完整的 JNI 绑定,允许:
-
使用 Rust 代码与 Java 库进行交互,调用 Java 方法和访问 Java 对象。
-
从 Rust 代码中使用 Java 类和接口。
-
实现跨语言的高效数据交换。
-
利用 Rust 的性能优势和 Java 的成熟生态系统
跨平台 UI 框架 Flutter 源码中的 MethodChannel 实现了 Dart 与 Android 层的通信,其底层 C++也是通过 JNI 调用插件中的 onMethodCall 来实现的。这与上述 jni 0.21.1 采用了相同的思路,但存在以下不同点:
- 语言特性和类型安全:
Rust 的jni库提供了一种更安全的方式来处理 Java 对象和方法调用。它利用 Rust 的所有权系统来减少潜在的内存错误,使得在 Rust 中使用 JNI 时更易于管理资源和避免常见错误。 - 多平台支持:jni 0.21.1 提供了更广泛的跨平台支持。
如何运行示例
示例源码请阅读原文,见原文底部源码获取
在 Windows 11 环境下运行示例时,笔者遇到了两个问题:
- Windows 自带的 PowerShell 无法直接执行 Makefile
- 由于 Rust 配置了特定目标平台,出现了不明原因的编译错误
以下是解决这些问题的方法:
在 MinGW-w64 中执行 Makefile
- 确保已在 MinGW-w64 环境中安装
mingw32-make工具(通常随 MinGW-w64 一起安装) - 打开 MinGW-w64 命令行
- 导航至 Makefile 所在目录
- 执行以下命令
//当前示例中是makefile,直接执行mingw32-make -f makefile即可
mingw32-make -f YourMakefileName
确认当前 Rust 环境
举例来说,笔者在 C:\Users\xxx.cargo 目录下配置了 config.toml 文件:
[build]
target = "aarch64-linux-android"
这导致在 Windows 上使用 mingw32-make 来编译针对 Android 平台的 Rust .so 文件,造成了混乱并引发了莫名其妙的编译错误。解决方法是删除不必要的 config.toml 文件,确保当前运行环境与目标平台(如 Windows)一致。。
输出结果:
Hello, josh!
[B@2f92e0f4
factCallback: res = 720
counterCallback: count = 1
counterCallback: count = 2
counterCallback: count = 3
counterCallback: count = 4
counterCallback: count = 5
Invoking asyncComputation (thread id = 1)
asyncCallback: thread id = 23, progress = 0%
asyncCallback: thread id = 23, progress = 10%
asyncCallback: thread id = 23, progress = 20%
asyncCallback: thread id = 23, progress = 30%
asyncCallback: thread id = 23, progress = 40%
asyncCallback: thread id = 23, progress = 50%
asyncCallback: thread id = 23, progress = 60%
asyncCallback: thread id = 23, progress = 70%
asyncCallback: thread id = 23, progress = 80%
asyncCallback: thread id = 23, progress = 90%
asyncCallback: thread id = 23, progress = 100%
示例简析
让我们深入分析示例中 asyncComputation 的流程。其核心目的是在 Rust 端执行一个异步计算,同时 Rust 端会调用 Java 端来报告计算进度。

整体流程图说明:
- Java 的 main()方法调用 asyncComputation()。
- asyncComputation()通过 JNI 调用 Rust 的 Java_HelloWorld_asyncComputation()函数。
- Rust 函数创建一个新线程来执行异步计算。
- 在新线程中,Rust 执行计算并周期性地调用 Java 的 asyncCallback()方法报告进度。
- 当 Rust 完成计算后,控制权返回到 Java 的主线程。
这个过程展示了 Java 调用 Rust(步骤 1)和 Rust 回调 Java(步骤 4)的双向交互。
源码如下

#1 将一个 HelloWorld 类实例传递给 Rust 端,这对应下方 Rust 侧实现中 #3 处的 callback 对象

Rust 实现说明
JNIEnv参数:详见上述相关概念中的解释。JClass:代表调用此本地方法的 Java 类引用,主要用于访问类级别的静态方法和字段。callback:Java 中新创建的 HelloWorld 对象实例。- 获取 JVM 对象:因为
env对象不支持线程间传递和共享(仅实现了 Send),而 JVM 支持。通过 JVM 对象可在线程间传递,并最终获得env。 - 创建全局引用:获取 HelloWorld() 实例对象的全局引用,防止被垃圾回收。
- 线程安全:每个线程都有自己的
JNIEnv,确保线程安全。在新线程中需调用AttachCurrentThread获取对应的JNIEnv。 - 反向调用 Java:通过
env反向调用 Java 代码。调用对象是新创建的 HelloWorld 实例,回调方法是其中的 asyncCallback。在 JNI 中,"(I)V"是方法签名,描述了 Java 方法的参数和返回类型。"(I)V"表示接受一个整数参数并返回void的方法。在这里,asyncCallback 方法接收一个整数(progress)作为参数,无返回值。
总结
- Java 与 Rust 互操作让两种语言优势互补,提高性能和安全性,适用于多种场景如性能优化、系统级编程和跨平台开发。
- JNI(Java Native Interface)是实现 Java 与 Rust 互操作的关键技术,允许 Java 代码与其他语言编写的应用程序进行交互。
- 通过示例分析,我们了解了 Java 调用 Rust 函数和 Rust 回调 Java 方法的双向交互过程,展示了两种语言之间的无缝协作。
参考链接
https://github.com/jni-rs/jni-rs
JNI APIs and Developer Guides
Leveraging Rust in our high-performance Java database
相关文章:
一文解秘Rust如何与Java互操作
本博客所有文章除特别声明外,均采用CC BY-NC-SA 4.0许可协议。转载请注明来自 唯你 使用场景 JAVA 与 Rust 互操作让 Rust 可以背靠 Java 大生态来做更多事情,而 Java 也可以享受 Rust 语言特性的内存安全,所有权机制,无畏并发。…...
手机发展史介绍
手机,这个曾经在电影和科幻小说中出现的高科技产品,如今已经渗透进了我们生活的每个角落。从单纯的通讯工具到如今集成了通讯、娱乐、工作、社交等多种功能的智能终端,手机的发展史也是人类科技进步的缩影。本文将从手机的发展历程、技术革新…...
【ArcGISPro】单次将自己建立的工具箱添加至Arcpy中
新建工具箱 添加至Arcpy中 调用刚添加的工具箱...
docker镜像仓库常用命令
docker镜像仓库常用命令 docker logindocker logoutdocker pulldocker pushdocker searchdocker imagesdocker image inspectdocker tagdocker rmidocker image prunedocker savedocker loaddocker history docker login 语法: docker login [options] [server] 功能ÿ…...
springboot 传统应用程序,适配云原生改造
概述 2024年传统应用程序上云,改造方案 1、mysql 云环境高可用方案 2、redis 云环境高可用方案 3、nginx 云环境高可用方案 4、应用 云环境高可用方案1、mysql 云环境高可用方案 1.1 你先了解 1.1.1 你先了解“mysql高可用方案” 主从复制(Master-S…...
D61【python 接口自动化学习】- python基础之数据库
day61 数据库定义 学习日期:20241107 学习目标:MySQL数据库-- 130:MySQL入门使用 学习笔记: 在命令提示符内先试用MySQL 使用图形化工具操作MySQL DBeaver安装 DBeaver连接MySQL 总结 MySQL安装成功后,可以使用命…...
数据库期末考试简答题
1.试述数据、数据库、数据库管理系统、数据库系统的概念。 答:(1)数据是数据库中存储的基本对象,是描述事物的符号记录。数据有多种表现形式,它们都可以经过数字化后存入计算机。数据的种类有数字、文字、…...
Java[面试题]-真实面试
1.什么是IOC和AOP?了解么? IOC(控制反转)和AOP(面向切面编程) 1. IOC(控制反转) 概念 IOC(Inversion of Control)是面向对象编程中的一个设计原则…...
HTML5新增多媒体支持
一、引言 在当今数字化时代,丰富的多媒体内容对于网页的吸引力和用户体验至关重要。HTML5 的出现为网页带来了强大的多媒体支持,尤其是在音频和视频方面,为开发者和用户带来了全新的可能性。 二、音频audio标签 2.1 定义与属性详解 <a…...
K8S群集调度二
一、污点(Taint) 和 容忍(Tolerations) 1.1、污点(Taint) 设置在node上是对pod的一种作用 节点的亲和性,是Pod的一种属性(偏好或硬性要求),它使Pod被吸引到一类特定的节点 而Taint 则相反,它使节点能够排斥一类特…...
43.第二阶段x86游戏实战2-提取游戏里面的lua
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 本次游戏没法给 内容参考于:微尘网络安全 本人写的内容纯属胡编乱造,全都是合成造假,仅仅只是为了娱乐,请不要…...
debian系统安装qt的时候 显示xcb相关文件缺失
如果是安装之后的问题 我们可以选择使用ldd的命令查看当前依赖的so那些文件确实 ldd /home/yinsir/Qt/5.15.2/gcc_64/plugins/platforms/libqxcb.so 本人在进行打包的时候 出现则会个报错 ERROR: ldd outputLine: “libxcb-util.so.1 > not found” ERROR: for binary: “/…...
得物多模态大模型在重复商品识别上的应用和架构演进
重复商品治理介绍 根据得物的平台特性,同一个商品在平台上不能出现多个链接,原因是平台需要保证一品一链的特点,以保障商品的集中竞价,所以说一个商品在整个得物平台上只能有一个商详链接,因此我们需要对一品多链的情…...
基于 SSM(Spring + Spring MVC + MyBatis)框架构建电器网上订购系统
基于 SSM(Spring Spring MVC MyBatis)框架构建电器网上订购系统可以为用户提供一个方便快捷的购物平台。以下将详细介绍该系统的开发流程,包括需求分析、技术选型、数据库设计、项目结构搭建、主要功能实现以及前端页面设计。 需求分析 …...
应用插件化及其进程关系梳理
插件应用的AndroidManifest.xml <manifest xmlns:android"http://schemas.android.com/apk/res/android"coreApp"true"package"com.demo.phone"android:sharedUserId"android.uid.phone"><uses-sdk android:minSdkVersion&q…...
Odoo:免费开源的医药流通行业信息化解决方案
文 / 开源智造Odoo亚太金牌服务 方案概述 开源智造Odoo免费开源ERP提供面向医药批发采、供、销业财一体化,及直接面向消费者的门店终端、全渠道管理、营销管理以及GSP合规管理解决方案,提升企业运营效率和全业务链条的数字化管控、追溯能力。 行业的最新…...
系统架构设计师论文:大数据Lambda架构
论文一:大数据Lambda架构 1简要说明你参与开发的软件项目,以及你所承担的主要工作 2 lamada体系架构将数据流分为批处理层(Batch Layer)、加速层(Speed Layer)、服务层(Serving Layer)。简要叙述这三个层次的用途和特点 3 详细阐述你参与开发的软件项目是如何基于lamada…...
亚信安全新一代WAF:抵御勒索攻击的坚固防线
近年来,勒索攻击已成为黑客的主要攻击手段。新型勒索攻击事件层出不穷,勒索攻击形势愈发严峻,已经对全球制造、金融、能源、医疗、政府组织等关键领域造成严重危害。如今,勒索攻击手段日趋成熟、攻击目标愈发明确,模式…...
Flutter 中的那些设计模式的写法(持续更新)
前言 我们都知道设计模式是相同的,同一种设计模式的理念不会因为语言不同而会有所改变,但是由于语法的差异,设计模式的写法也有所差异,本文会介绍一些flutter中常用设计模式的写法以及使用场景。 常见的设计模式有23种࿰…...
【提效工具开发】Python功能模块执行和 SQL 执行 需求整理
需求梳理 背景 当前我们在IDE或MySQL查询工具中只能进行个人使用,缺乏共享功能,且在查询及数据统计上有一定的不便。为了改善这种情况,计划搭建一个Web平台,通过后台交互来提升效率。此平台需要兼容Python工具和SQL工具的管理、执…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...
