Expand description
High-level wrapper of jni
, making Java & Rust FFI easy & fun
Globals
toad_jni::global
offers the option to use a global JVM handle .
toad_jni::global::jvm()
must be initialized with
toad_jni::global::init()
in order to use Rust trait
impls on java types. Some examples include:
Iterator
ontoad_jni::java::util::ArrayList
core::fmt::Debug
ontoad_jni::java::lang::Throwable
toad::net::Socket
ontoad_jni::java::nio::channels::DatagramChannel
Types
All java type signatures can be represented by rust types
that implement the toad_jni::java::Type
trait, which is automatically
implemented for all toad_jni::java::Class
es.
Classes
Classes are represented in toad_jni
by implementing 2 traits:
Fields and Methods
There are several high-level lens-style structs for interacting with fields, methods and constructors:
toad_jni::java::Constructor
toad_jni::java::StaticField
toad_jni::java::StaticMethod
toad_jni::java::Field
toad_jni::java::Method
All of these types use toad_jni::java::Type
to transform nice Rust types into the corresponding
JVM type signatures.
For example, the StaticMethod
representation of java.lang.String.format(String, ..Object)
would be:
use toad_jni::java::lang::Object;
use toad_jni::java::StaticMethod;
static STRING_FORMAT: StaticMethod<String, fn(String, Vec<Object>) -> String> =
StaticMethod::new("format");
It is recommended that these structs are stored in local static
variables so that they can cache
the internal JNI IDs of the class and methods, but this is not required.
Example
Consider the following java class:
package com.foo.bar;
public class Foo {
public final static long NUMBER = 123;
public String bingus = "bingus";
public Foo() { }
public static String bar() {
return "bar";
}
public void setBingus(String newBingus) {
this.bingus = newBingus;
}
}
A Rust API to this class would look like:
use toad_jni::java;
pub struct Foo(java::lang::Object);
java::object_newtype!(Foo);
impl java::Class for Foo {
const PATH: &'static str = "com/foo/bar/Foo";
}
impl Foo {
pub fn new(e: &mut java::Env) -> Self {
static CTOR: java::Constructor<Foo, fn()> = java::Constructor::new();
CTOR.invoke(e)
}
pub fn number(e: &mut java::Env) -> i64 {
static NUMBER: java::StaticField<Foo, i64> = java::StaticField::new("NUMBER");
NUMBER.get(e)
}
pub fn bar(e: &mut java::Env) -> String {
static BAR: java::StaticMethod<Foo, fn() -> String> = java::StaticMethod::new("bar");
BAR.invoke(e)
}
pub fn bingus(&self, e: &mut java::Env) -> String {
static BINGUS: java::Field<Foo, String> = java::Field::new("bingus");
BINGUS.get(e, self)
}
pub fn set_bingus(&self, e: &mut java::Env, s: String) {
static SET_BINGUS: java::Method<Foo, fn(String)> = java::Method::new("setBingus");
SET_BINGUS.invoke(e, self, s)
}
}
Modules
- Global JVM handles
- java language features and class shims
Macros
- Derive
crate::java::Object
for a tuple struct with 1crate::java::lang::Object
field.