An open API service indexing awesome lists of open source software.

https://github.com/maulingmonkey/jerk

JERK: Java Embedding Rust Kit
https://github.com/maulingmonkey/jerk

java jvm metabuild rust

Last synced: about 1 year ago
JSON representation

JERK: Java Embedding Rust Kit

Awesome Lists containing this project

README

          

# **jerk**: **J**ava **E**mbedding **R**ust **K**it

[![Crates.io](https://img.shields.io/crates/v/jerk.svg)](https://crates.io/crates/jerk)
[![Docs](https://docs.rs/jerk/badge.svg)](https://docs.rs/jerk/)
[![GitHub](https://img.shields.io/github/stars/MaulingMonkey/jerk.svg?label=GitHub&style=social)](https://github.com/MaulingMonkey/jerk)
[![unsafe: yes](https://img.shields.io/github/search/MaulingMonkey/jerk/unsafe%2bextension%3Ars?color=yellow&label=unsafe)](https://github.com/MaulingMonkey/jerk/search?q=unsafe+extension%3Ars)
[![rust: 1.54.0+](https://img.shields.io/badge/rust-1.54.0%2B-green.svg)](https://gist.github.com/MaulingMonkey/c81a9f18811079f19326dac4daa5a359#minimum-supported-rust-versions-msrv)
[![License](https://img.shields.io/crates/l/jerk.svg)](https://github.com/MaulingMonkey/jerk)

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](https://github.com/MaulingMonkey/jerk/tree/publish) | [![Open issues](https://img.shields.io/github/issues-raw/MaulingMonkey/jerk.svg)](https://github.com/MaulingMonkey/jerk/issues) | Stable/published version
| [master](https://github.com/MaulingMonkey/jerk/tree/master) | [![Build Status](https://github.com/MaulingMonkey/jerk/workflows/Rust/badge.svg)](https://github.com/MaulingMonkey/jerk/actions?query=workflow%3Arust) | "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](https://github.com/MaulingMonkey/jerk/wiki/Installing-the-JDK) if you haven't already.

Add this to your [Cargo.toml](https://github.com/MaulingMonkey/jerk/blob/master/example-hello-world-jar/Cargo.toml#L10-L20):

```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](https://github.com/MaulingMonkey/jerk/blob/master/example-hello-world-jar/build.rs):

```rust
fn main() {
jerk::metabuild();
}
```

You can then write Java ([src/Adder.java](https://github.com/MaulingMonkey/jerk/blob/master/example-hello-world-jar/src/Adder.java)) code:

```java
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](https://github.com/MaulingMonkey/jerk/blob/master/example-hello-world-jar/src/Adder.rs)) code:

```rust
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](https://github.com/MaulingMonkey/jerk/blob/master/example-hello-world-jar/tests/test.rs)):

```rust
#[test] fn test() {
jerk::run_test!("com.maulingmonkey.jerk.example_hello_world_jar", "Adder", "test");
}
```

...and then build and run the test!

```text
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](LICENSE-APACHE) or )
* MIT license ([LICENSE-MIT](LICENSE-MIT) or )

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.

[cc]: https://crates.io/crates/cc
[`kotlinc`]: https://kotlinlang.org/docs/tutorials/command-line.html
[build.rs]: https://doc.rust-lang.org/cargo/reference/build-scripts.html
[metabuild]: https://github.com/rust-lang/rfcs/blob/master/text/2196-metabuild.md