Expand description
jerk: Java Embedding Rust Kit
Libraries to compile/embed/test Java alongside a Rust library/application. Similar to cc, but for Java. This is not an official project of Google, Oracle, Sun Microsystems, or anyone else.
Branch | Badges | Notes |
---|---|---|
publish | Stable/published version | |
master | “Completed” stuff that hasn’t been published. | |
wip/* | “Work In Progress” - incomplete, use at your own risk. | |
dead/* | Abandoned threads of work |
Goals
- Minimal dependencies
- Compile small amounts of Java before/alongside your Rust code via
javac
,jar
, etc. - TODO?: Compile small amounts of Kotlin before/alongside your Rust code via
kotlinc
etc. - TODO?: Compile small amounts of whatever JVM language before/alongside your Rust code via Ant, Groovy, etc.
- TODO?: Auto-locate tools based on env vars, common paths, etc.
- TODO?: Auto-install missing tools for you.
Non-Goals
- Directly compete with Ant, Groovy, etc. as a fully fledged Java build tool.
Quick Start
Install the JDK if you haven’t already.
Add this to your Cargo.toml:
[lib]
crate-type = ["rlib", "dylib"]
[dependencies]
jni-sys = "0.3"
[build-dependencies]
jerk = "0.2"
[dev-dependencies]
jerk = "0.2"
And this to your build.rs:
fn main() {
jerk::metabuild();
}
You can then write Java (src/Adder.java) code:
package com.maulingmonkey.jerk.example_hello_world_jar;
public class Adder {
public native int add(int a, int b);
public static void test() {
System.loadLibrary("example_hello_world_jar");
assert adder.add(1, 2) == 3;
}
}
…alongside your Rust (src/Adder.rs) code:
use jni_sys::{JNIEnv, jobject, jint};
#[no_mangle] pub extern "stdcall" fn Java_com_maulingmonkey_jerk_example_1hello_1world_1jar_Adder_add__II(_env: *mut JNIEnv, _this: jobject, a: jint, b: jint) -> jint {
a + b
}
…and write Java integration tests (tests/test.rs):
#[test] fn test() {
jerk::run_test!("com.maulingmonkey.jerk.example_hello_world_jar", "Adder", "test");
}
…and then build and run the test!
C:\local\jerk>cargo t
Finished dev [unoptimized + debuginfo] target(s) in 0.06s
Running target\debug\deps\example_hello_world_jar-2997df28c387b743.exe
running 1 tests
test adder::test ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Java <-> Rust Interop Pontificating
Rust code may sanely depend on Java code to build, but not vicea versa:
- Java’s ABI has great metadata (classes, methods, doc info, etc.), Rust doesn’t even have a stable ABI.
- Local Java <- Rust <- Java dependency cycles at compile time would be terrible to manage.
You can still have:
- Java call into Rust, it should just be through
native
methods declared in Java. - Rust-driven packaging bundle Java JARs (e.g. when creating Android APKs) as a final step.
- Rust define runtime classes implementing interfaces, they just wouldn’t be visible to Java at compile time.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Modules
Macros
Execute a Java unit test. The method must be static, return void, and take no arguments.