Skip to content

Repository files navigation

Zenoh Flat JNI

CI Maven Central License

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.

Overview

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 from prebindgen

Features

  • 🦀 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

Installation

Maven Central

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.

Usage

Kotlin Example

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()
}

Development

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.

Prerequisites

  • 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)

Build from Source

# 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 build

Local Development with Workspace

To 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

Testing

# Run Rust tests
cargo test --all

# Run Kotlin tests
./gradlew jvmTest

# Lint
cargo clippy --all-targets --all-features -- -D warnings
cargo fmt --check

Building for Android

./gradlew assembleRelease verifyAndroidArtifact

That 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-r26

verifyAndroidArtifact 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.)

Architecture

The generated bindings are created via prebindgen in the build process:

  1. Rust source (zenoh-flat) marked with #[prebindgen] annotations
  2. Proc-macro captures annotated items to JSONL format
  3. prebindgen_jni::JniGen reads JSONL and generates:
    • Rust JNI wrapper functions
    • Kotlin data classes and enums
  4. Gradle packages Rust dylib + Kotlin sources into a JAR
  5. Maven Central publishes three modules: the root zenoh-flat-jni (Gradle module metadata), zenoh-flat-jni-jvm (the desktop natives) and zenoh-flat-jni-android (the AAR)

Integration with zenoh-java

zenoh-flat-jni is a standalone library that can be consumed by:

Both projects depend on zenoh-flat-jni as a Maven artifact, enabling independent versioning and release cycles.

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

License

This project is licensed under either of

at your option.

Acknowledgments

This project is part of the Eclipse Zenoh ecosystem and is maintained by the ZettaScale team.

About

Common JNI library for zenoh-java and zenoh-kotlin autogenerated from zenoh-flat

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages