# Jni Rs Bindings

> jni-rs conventions for exposing a Rust core to Java/JVM: JNI export naming, JNIEnv usage, string conversion, exception checks/throws, global references, and library loading. Load when generating or reviewing jni-rs Java/JVM bindings for a Rust library.

- Skill: `goldziher/jni-rs-bindings` (Agent Skill)
- Install (CLI): `npx skillmds@latest add goldziher/jni-rs-bindings`
- Raw SKILL.md: https://api.skillmd.com/api/skills/goldziher/jni-rs-bindings/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: goldziher (https://skillmd.com/u/goldziher)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/goldziher/jni-rs-bindings

---


- Use `jni` crate for Rust-Java/JVM interop. Functions must be `#[no_mangle] pub extern "system"`.
- Follow JNI naming: `Java_com_example_ClassName_methodName`. Match Java native method signatures exactly.
- Use `JNIEnv` for all JNI operations. Access Java types via `JObject`, `JString`, `JClass` wrappers.
- String conversion: `env.get_string(&jstring)` to read, `env.new_string("value")` to create.
- Error handling: check `env.exception_check()` after JNI calls. Throw Java exceptions via `env.throw_new()`.
- Global references (`env.new_global_ref()`) for objects accessed across threads or native calls.
- Build with `cargo build --release` to produce shared library. Load in Java with `System.loadLibrary()`.
- Test Java side with JUnit, Rust core logic with standard `#[test]`. Integration tests via JNI calls.
- Keep JNI layer thin — business logic in Rust, Java provides API surface.
- Memory: JNI local references are auto-freed on native return. Use `env.delete_local_ref()` in loops.
- Anti-patterns: holding JNI references across threads without global refs, ignoring exception checks, `unwrap()` in JNI functions.

