JavaWithRust-Lib

Transfer function calls between Rust and Java in a rust-like (ish) way.

Features

Limitations

Setup

Create a dynamic library crate. ```bash

Bash

cargo init . --lib toml

Cargo.toml

[dependencies] javawithrust = "0.1" serde = {version = "1.0", features = ["derive"]}

[lib] crate_type = ["cdylib"] ```

Usage

Get the needed stuff. ```rust // Rust

use javawithrust::prelude::*; ```

Link a new Java class. This will link JavaObject (in Rust) and io.example.JavaClassName (in Java). ```rust // Rust

[jclass(io.example.JavaClassName)]

pub struct JavaObject; ```

Link the functions. ```rust // Rust

[jfuncs]

impl JavaObject {

} ```

Examples

```rust // Rust

use javawithrust::prelude::*;

[jclass(io.example.CustomJavaClass)]

pub struct CustomRustStruct;

[jfuncs]

impl CustomRustStruct {

fn hello() { // Will return `Result<(), String>`
    println!("hello");
    CustomRustStruct::world()?;
    return Ok(());
}

// Will call `io.example.CustomJavaClass.world()`.
fn world();

// Callable from java.
fn sum(a : i32, b : i32) -> i32 { // Will return `Result<i32, String>`
    return Ok(a + b);
}

} java // Java

package io.example;

import org.astonbitecode.j4rs.api.Instance; import org.astonbitecode.j4rs.api.dtos.InvocationArg; import org.astonbitecode.j4rs.api.java2rust.Java2RustUtils; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper;

public class ConvHelper {

public static <T> Instance<T> j2rs(T from) {
    return Java2RustUtils.createInstance(from);
}

@SuppressWarnings("unchecked")
public static <T> T rs2j(Instance<T> from) {
    if (from instanceof InvocationArg) {
        InvocationArg from_ia = ((InvocationArg)from);
        if (from_ia.isSerialized()) {
            ObjectMapper mapper = new ObjectMapper();
            try {
                return mapper.<T>readValue(from_ia.getJson(), (Class<T>)(Class.forName(from_ia.getClassName())));
            } catch (JsonProcessingException | ClassNotFoundException e) {
                e.printStackTrace();
                System.exit(1);
            }
        }
    }
    return Java2RustUtils.getObjectCasted(from);
}

} java // Java

package io.example;

import org.astonbitecode.j4rs.api.Instance; import org.astonbitecode.j4rs.api.java2rust.Java2RustUtils;

public class CustomJavaClass { // Load the dynamic library. // The library is loaded from the same directory as the jar. static { String os=System.getProperty("os.name").toLowerCase();String path=J2RS.class.getProtectionDomain().getCodeSource().getLocation().getPath();path=path.substring(0,path.lastIndexOf("/")).replaceAll("%20"," ")+"/"+ "robot"; // Name of the dynamic library file. .so and .dll are added automatically. if (os.contains("linux") || os.contains("unix") || os.contains("android")) { path += ".so"; } else if (os.contains("win")) { path += ".dll"; } else {throw new UnsatisfiedLinkError("Can not load dynamic library in unknown operating system " + os + "");} System.load(path); }

public static native void hello();

public static void world() {
    System.out.println("world!");
}

private static native Instance<Integer> sum(Instance<Integer> i1, Instance<Integer> i2);
public static Integer sumFromRust(Integer a, Integer b) {
    // Convert the objects.
    return ConvHelper.rs2j(J2RS.sum(
        ConvHelper.j2rs(a),
        ConvHelper.j2rs(b)
    ));
}

} ```