Expand description
§Extra Utilities for JNI in Rust
This crate builds on top of the jni
crate and provides
higher-level concepts to more easily deal with JNI. While the
jni
crate implements low-level bindings to JNI,
jni-utils
is more focused on higher-level constructs that get
used frequently. Some of the features provided by jni-utils
include:
- Asynchronous calls to Java code using the
JFuture
andJStream
types - Conversion between various commonly-used Rust types and their corresponding Java types
- Emulation of
try
/catch
blocks with thetry_block
function
The overriding principle of jni-utils
is that switches between
Rust and Java code should be minimized, and that it is easier to call Java
code from Rust than it is to call Rust code from Java. Calling Rust from
Java requires creating a class with a native
method and exporting it from
Rust, either by a combination of #[nomangle]
and extern "C"
to export
the function as a symbol in a shared library, or by calling
JNIEnv::register_native_methods()
.
In contrast, calling Java from Rust only requires calling
JNIEnv::call_method()
(though you can cache
the method ID and use
JNIEnv::call_method_unchecked()
for a performance improvement.)
To that end, jni-utils
seeks to minimize the number of holes
that must be poked through the Rust-Java boundary, and the number of
native
exported-to-Java Rust functions that must be written. In
particular, the async API has been developed to minimize such exports by
allowing Java code to wake an await
without creating a new native
function.
Some features of jni-utils
require the accompanying Java support
library, which includes some native methods. Therefore,
jni_utils::init()
should be called before using
jni-utils
.