rust-jnilisted
Install: claude install-skill po4yka/rust-skills
# Rust JNI
## Purpose
Use this skill for every Rust function that the JVM calls directly, and for the
Kotlin or Java code that declares it. The JNI boundary has no compiler that
checks both sides. A wrong symbol name, an unguarded panic, an unattached
thread, or one local reference too many is a process abort at run time, not a
build error.
The rules below apply to any workspace. Derive the current export inventory
from the source tree before you change it. Do not trust a memory of which
symbols exist:
```bash
# Every JNI export in the workspace.
rg -n 'pub extern "system" fn Java_' --type rust
# Every native declaration on the JVM side.
rg -n 'external fun|System\.loadLibrary' --type kotlin
```
## When to consult
- You add, rename, or remove any `#[unsafe(no_mangle)] pub extern "system" fn Java_*` export.
- You add a callback from Rust back into Java that needs `JavaVM::attach_current_thread`.
- You decide between the raw `jni` crate and UniFFI for a new binding surface.
- You review a diff that touches a `cdylib` crate or its Kotlin binding class.
- You triage `UnsatisfiedLinkError`, `JNI DETECTED ERROR IN APPLICATION`, or a
native abort with no Rust panic message.
## jni crate API versions
The `jni` crate changed its API at 0.22. Code that compiles on 0.21 does not
compile on 0.22. Read the version from your `Cargo.toml` before you copy any
snippet:
```bash
cargo tree --invert jni
```
| Task | `jni` 0.21 | `jni` 0.22 |
|------|------------|------------|
| Env