├── .gitignore ├── README.md ├── lib-rust ├── Cargo.toml └── src │ └── lib.rs └── use-java ├── libdummymath.dylib ├── pom.xml └── src └── main └── java └── ch └── frankel └── blog └── rust └── Main.java /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | target 4 | Cargo.lock 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # How to call rust from java 2 | 3 | 4 | ## Building rust 5 | 6 | Ensure you have maven and rust installed. 7 | 8 | For example on macos with apple silicon: 9 | 10 | ```bash 11 | cd lib-rust 12 | rustup target add x86_64-apple-darwin 13 | cargo build --target x86_64-apple-darwin 14 | cp target/x86_64-apple-darwin/debug/libdummymath.dylib ../use-java/ 15 | ``` 16 | 17 | You can adjust this for you platform, but what this does is install the x86_64 builder and build a rust binary for x86_64. The binary will be loaded by the `use-java` code. 18 | 19 | ## Building and running from java 20 | 21 | ```bash 22 | cd ../use-java 23 | mvn package 24 | ``` 25 | 26 | You can then run the Main class from your IDE or from the command line. 27 | 28 | This will load the libdummymath.dylib and call the rust code. 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /lib-rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dummymath" 3 | version = "0.1.0" 4 | authors = ["Nicolas Frankel "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | jni = "0.19.0" 9 | 10 | [lib] 11 | crate_type = ["cdylib"] 12 | -------------------------------------------------------------------------------- /lib-rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | use jni::JNIEnv; 2 | use jni::sys::jint; 3 | use jni::objects::JObject; 4 | 5 | #[no_mangle] 6 | pub extern "system" fn Java_ch_frankel_blog_rust_Main_doubleRust(_env: JNIEnv, _obj: JObject, x: jint) -> jint { 7 | x * 2 8 | } 9 | 10 | #[no_mangle] 11 | pub extern "system" fn Java_ch_frankel_blog_rust_Main_timesRust(env: JNIEnv, obj: JObject, x: jint) -> jint { 12 | let state = env.get_field(obj, "state", "I"); 13 | state.unwrap().i().unwrap() * x 14 | } 15 | -------------------------------------------------------------------------------- /use-java/libdummymath.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajavageek/rust-jvm/737216dd1089a049a2a87c615ad7914b515fae25/use-java/libdummymath.dylib -------------------------------------------------------------------------------- /use-java/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | ch.frankel.blog 7 | use-java 8 | 1.0-SNAPSHOT 9 | 10 | 11 11 | ${maven.compiler.source} 12 | UTF-8 13 | 14 | 15 | 16 | 17 | maven-compiler-plugin 18 | 3.8.1 19 | 20 | 21 | -h 22 | target/headers 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /use-java/src/main/java/ch/frankel/blog/rust/Main.java: -------------------------------------------------------------------------------- 1 | package ch.frankel.blog.rust; 2 | 3 | public class Main { 4 | 5 | private int state; 6 | 7 | static { 8 | System.loadLibrary("dummymath"); 9 | } 10 | 11 | public Main(int state) { 12 | this.state = state; 13 | } 14 | 15 | public Main() { 16 | this(-1); 17 | } 18 | 19 | public static void main(String[] args) { 20 | args = new String[2]; 21 | args[0] = "double"; 22 | args[1] = "2"; 23 | if (args.length == 0) { 24 | throw new IllegalArgumentException("You must provide a method and its parameters"); 25 | } 26 | var arg = args[0]; 27 | switch (arg) { 28 | case "double": 29 | double_(args); 30 | break; 31 | case "times": 32 | times(args); 33 | break; 34 | } 35 | } 36 | 37 | public static void double_(String[] args) { 38 | if (args.length < 2) { 39 | throw new IllegalArgumentException("You must provide an int parameter"); 40 | } 41 | try { 42 | var arg = Integer.parseInt(args[1]); 43 | var result = new Main().doubleRust(arg); 44 | System.out.println(arg + "x2 = " + result); 45 | } catch (NumberFormatException e) { 46 | throw new IllegalArgumentException("Argument must be an int"); 47 | } 48 | } 49 | 50 | public static void times(String[] args) { 51 | if (args.length < 3) { 52 | throw new IllegalArgumentException("You must provide two int parameters"); 53 | } 54 | try { 55 | var arg1 = Integer.parseInt(args[1]); 56 | var arg2 = Integer.parseInt(args[2]); 57 | var result = new Main(arg1).timesRust(arg2); 58 | System.out.println(arg1 + "x" + arg2 + " = " + result); 59 | } catch (NumberFormatException e) { 60 | throw new IllegalArgumentException("Arguments must be ints"); 61 | } 62 | } 63 | 64 | public native int doubleRust(int input); 65 | public native int timesRust(int input); 66 | } 67 | --------------------------------------------------------------------------------