Zenoh JNI bindings and Kotlin wrappers for the Zenoh pub/sub, store/query and compute framework.
This project provides low-level JNI bindings (Rust) and high-level Kotlin wrappers generated from the zenoh-flat Rust crate using prebindgen.
The Zenoh Flat JNI library generates multi-language FFI bindings from a single annotated Rust source (zenoh-flat). It consists of:
- Rust JNI layer (
src/) - Native bindings to Zenoh APIs - Kotlin wrappers (
kotlin/) - Type-safe Kotlin classes for JVM and Android - Generated Kotlin (
generated-kotlin/) - Auto-generated Kotlin sources fromprebindgen
- 🦀 Native Rust performance - Direct JNI binding to Zenoh
- 🎯 Type-safe API - Kotlin data classes and enums for type safety
- 📱 Multi-platform - Support for JVM (Linux, macOS, Windows) and Android
- 🔒 Memory-safe - Automatic resource management via Kotlin classes
- 🚀 Zero-copy - Efficient data transfer between Rust and JVM
Add the dependency to your build.gradle.kts:
dependencies {
implementation("org.eclipse.zenoh:zenoh-flat-jni:1.9.0")
}Or in pom.xml:
<dependency>
<groupId>org.eclipse.zenoh</groupId>
<artifactId>zenoh-flat-jni-jvm</artifactId>
<version>1.9.0</version>
</dependency>Note the -jvm suffix. Gradle consumers depend on the plain zenoh-flat-jni
coordinate and are redirected to the right variant by Gradle module metadata;
Maven ignores that metadata, so a Maven build must name the platform module
directly — the root artifact carries metadata only, not the classes or the
native libraries.
import io.zenoh.jni.*
fun main() {
// Initialize Zenoh
val config = ZConfig()
val session = config.openSession()
// Put a key-value pair
val keyExpr = ZKeyExpr.from("demo/example")
session.put(keyExpr, "Hello, Zenoh!")
// Close resources
keyExpr.drop()
session.drop()
}Local setup is documented in DEVELOPMENT.md; the Maven Central release pipeline, artifact layouts, verification gates and dry-run procedure are documented in PUBLISHING.md.
- Rust — the version is pinned by
rust-toolchain.toml(currently 1.97.1) and rustup installs it automatically - JDK 11+ (Gradle comes from the committed wrapper)
- Android NDK r26 and
cargo-ndk(for Android builds)
# Clone the repository with dependencies
git clone https://github.com/eclipse-zenoh/zenoh-flat-jni.git
cd zenoh-flat-jni
# Build Rust library
cargo build --release
# Build Kotlin (optional, for local development)
./gradlew buildTo use local versions of zenoh-flat and prebindgen:
# Ensure you have the PREBINDGEN workspace checked out locally
mkdir -p ~/zenoh-workspace
cd ~/zenoh-workspace
git clone https://github.com/milyin/prebindgen.git
git clone https://github.com/eclipse-zenoh/zenoh-flat-jni.git
cd zenoh-flat-jni
# To build against a local checkout instead of the published/Git sources,
# point Cargo at it without editing this repository's manifest — e.g. in a
# workspace-level .cargo/config.toml:
# [patch."https://github.com/eclipse-zenoh/zenoh-flat.git"]
# zenoh-flat = { path = "../zenoh-flat" }
cargo build --release# Run Rust tests
cargo test --all
# Run Kotlin tests
./gradlew jvmTest
# Lint
cargo clippy --all-targets --all-features -- -D warnings
cargo fmt --check./gradlew assembleRelease verifyAndroidArtifactThat cross-compiles all four ABIs and packages the AAR. One-time prerequisites, as for any cross-compilation:
rustup target add armv7-linux-androideabi aarch64-linux-android \
i686-linux-android x86_64-linux-android
cargo install cargo-ndk --locked --version 4.1.2
export ANDROID_NDK_HOME=/path/to/android-ndk-r26verifyAndroidArtifact fails unless the AAR carries a manifest, classes.jar,
R.txt and all four ABI libraries. The release runs the same
buildAndroidLibs task, so this is not a parallel developer-only path — see
PUBLISHING.md.
The cross-compilation runs every time — Cargo decides what is actually stale, so
a Rust change is always picked up. (The release's publish job passes
-PprebuiltAndroidLibs=true to package libraries it downloaded as build
artifacts; that is the only path that skips it.)
The generated bindings are created via prebindgen in the build process:
- Rust source (
zenoh-flat) marked with#[prebindgen]annotations - Proc-macro captures annotated items to JSONL format
prebindgen_jni::JniGenreads JSONL and generates:- Rust JNI wrapper functions
- Kotlin data classes and enums
- Gradle packages Rust dylib + Kotlin sources into a JAR
- Maven Central publishes three modules: the root
zenoh-flat-jni(Gradle module metadata),zenoh-flat-jni-jvm(the desktop natives) andzenoh-flat-jni-android(the AAR)
zenoh-flat-jni is a standalone library that can be consumed by:
- zenoh-java - Higher-level Zenoh API for JVM/Android
- zenoh-kotlin - Kotlin-first Zenoh API
Both projects depend on zenoh-flat-jni as a Maven artifact, enabling independent versioning and release cycles.
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
This project is licensed under either of
- Eclipse Public License 2.0 (LICENSE or http://www.eclipse.org/legal/epl-2.0)
- Apache License, Version 2.0 (LICENSE or https://www.apache.org/licenses/LICENSE-2.0)
at your option.
This project is part of the Eclipse Zenoh ecosystem and is maintained by the ZettaScale team.