用wasmer-java编写第一个WebAssembly应用:从Rust源码编译.wasm到Java调用的完整教程
【免费下载链接】wasmer-java☕ WebAssembly runtime for Java项目地址: https://gitcode.com/gh_mirrors/wa/wasmer-java
wasmer-java 是运行在 Java 上的 WebAssembly 运行时,让你只需三步就能把 Rust 源码编译成.wasm文件,并在 Java 中像调用普通函数一样安全地执行它,性能接近原生、运行完全沙箱化。本文带你完成从写 Rust 到 Java 调用的全流程。
为什么选择 wasmer-java?🚀
| 特性 | 说明 |
|---|---|
| 易用 | API 模仿标准 WebAssembly 接口,几行代码即可运行.wasm |
| 快速 | 底层由 Wasmer 引擎驱动,执行速度接近原生 |
| 安全 | 所有 WebAssembly 调用都在沙箱中执行,内存安全 |
它的核心原理(见 DEVELOPMENT.md):Java 侧通过 JNI 声明native方法,Rust 侧实现同名导出函数,动态链接库完成桥接。对你来说只需记住两个 Java 类:
Module:编译.wasm字节码,支持验证与序列化(src/java/org/wasmer/Module.java)Instance:实例化模块,调用导出的函数和内存(src/java/org/wasmer/Instance.java)
一键准备开发环境 🛠️
需要安装三个工具:
- Java(JDK 8 及以上)
- Rust(提供
cargo和rustup) - Gradle(项目已自带
gradlew包装器)
然后克隆仓库并编译整个项目(make build会依次生成 JNI 头文件、编译 Rust 动态库、构建 Java 代码):
git clone https://gitcode.com/gh_mirrors/wa/wasmer-java cd wasmer-java make build多平台构建命令统一收在 Makefile 中,支持amd64-linux、amd64-darwin、amd64-windows等目标架构。
第一步:编写 Rust 源码并编译出 .wasm 🦀
最简单的入门程序是一个加法函数。打开 examples/simple.rs 看看源码,只有 3 行:
#[no_mangle] pub extern fn sum(x: i32, y: i32) -> i32 { x + y }关键点:#[no_mangle]宏让函数名原样导出,成为 WebAssembly 模块的接口。
用wasm32-wasi目标编译即可得到.wasm二进制文件(项目已附带编译好的 examples/simple.wasm,可直接跳过此步):
rustup target add wasm32-wasi cargo build --release --target wasm32-wasi产物位于target/wasm32-wasi/release/目录下,拷贝为simple.wasm放在 Java 程序能找到的路径即可。
第二步:在 Java 项目中引入 wasmer-jni 依赖
项目按"架构-系统"发布 JAR,命名规则为wasmer-jni-$(architecture)-$(os)-$(version).jar。在 Gradle 中声明依赖:
dependencies { implementation "org.wasmer:wasmer-jni-amd64-linux:0.3.0" }💡 小贴士:build.gradle 中的
inferWasmerJarAppendix()函数可以根据当前平台自动推导架构后缀,避免手填出错。
第三步:Java 调用 .wasm,3 行代码跑通 🎉
对照 examples/SimpleExample.java,核心逻辑非常简洁:
// 1. 读取 .wasm 字节码 byte[] bytes = Files.readAllBytes(Paths.get("simple.wasm")); // 2. 实例化模块 Instance instance = new Instance(bytes); // 3. 调用导出的 sum 函数 Integer result = (Integer) instance.exports.getFunction("sum").apply(1, 2)[0]; System.out.println(result); // 3 instance.close();就这么简单——读文件、实例化、取函数、传参调用。返回值是Object[],按类型强转即可(Integer、Long、Float、Double均受支持)。
用项目自带的 Makefile 可以直接运行示例,无需手动配置类路径和动态库路径:
make run-example EXAMPLE=Simple进阶:跨语言传递字符串 🔗
如果函数需要传字符串或读写数据,就要用到 WebAssembly 线性内存。项目的 examples/GreetExample.java 演示了完整套路:
- 调用 Rust 侧导出的
allocate在 Wasm 内存中分配一块空间,拿到指针 - 通过
Memory.buffer()获得ByteBuffer,把 Java 字符串写进去 - 调用
greet函数,传入指针,读回结果
Rust 源码见 examples/greet.rs。相关类:
Memory:线性内存的读写与grow扩容(src/java/org/wasmer/Memory.java)Exports/Function:导出项的只读映射与函数句柄(src/java/org/wasmer/exports/)
想跳过编译环节、多次复用模块时,还可以用module.serialize()/Module.deserialize()把编译结果缓存下来,省掉二次编译时间。
验证你的作品:跑一遍测试 ✅
项目内置了完整的 JUnit 测试,覆盖 i32/i64/f32/f64 等全部参数类型和内存字符串读写:
make test测试源码位于tests/java/org/wasmer/目录,如InstanceTest、MemoryTest、ModuleTest,都是很好的 API 参考。
写在最后
至此,你已经掌握了 wasmer-java 的完整开发链路:Rust 写逻辑 → 编译成 .wasm → Java 一行apply调用。WebAssembly 让你在 JVM 里安全地跑任意语言编译的高性能代码,无论是插件系统、脚本引擎还是混合架构服务,这套组合都值得尝试。建议接着阅读 README.md 了解 API 全貌,以及 DEVELOPMENT.md 深入 Java 与 Rust 的 JNI 通信细节。
【免费下载链接】wasmer-java☕ WebAssembly runtime for Java项目地址: https://gitcode.com/gh_mirrors/wa/wasmer-java
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考