rust jni environment test setup on mac

85 Views Asked by At

I am using crate jni = { version = "0.20.0", features = ["invocation"] } and was trying to setup a test that could run JNI stuff.

my boot code is as follows

        let jvm_args = InitArgsBuilder::new()
            .version(JNIVersion::V8)
            .option("-Xcheck:jni")
            .build()
            .unwrap();

        let jvm = JavaVM::new(jvm_args).unwrap();
        let _guard = jvm.attach_current_thread().unwrap();
        let env = jvm.get_env().unwrap();
        JavaClasses::init(&env);

I cant seem to get this running on mac, as when the IDE RustRover lauches the binary, it always have problems finding the dynamic linked libs, complaining

Error: could not find libjava.dylib
Failed to GetJREPath()

tried to lookup the rpath names, seems nothing returned

➜  blaze git:(tests) ✗ otool -l xxxlaze/target/debug/deps/blaze_tests-b310798913eec8e4 | ag -C 5 LC_RPATH       
➜  blaze git:(tests) ✗ 

I did try to set them though in build.rs

    println!("cargo:rustc-link-search=native={}", libjvm_path.display());
    // println!("cargo:rustc-link-arg=-Wl,-rpath={}", libjvm_path.display());
    println!("cargo:rustc-env=LD_LIBRARY_PATH={}", libjvm_path.display());
1

There are 1 best solutions below

0
On

I send up doing something similar to JNI crate, with a build.rs build script to locate jvm path like this (exactly the same as the version in JNI crate)

fn find_libjvm<S: AsRef<Path>>(path: S) -> Option<PathBuf> {
    let walker = walkdir::WalkDir::new(path).follow_links(true);

    for entry in walker {
        let entry = match entry {
            Ok(entry) => entry,
            Err(_e) => continue,
        };

        let file_name = entry.file_name().to_str().unwrap_or("");

        if file_name == EXPECTED_JVM_FILENAME {
            return entry.path().parent().map(Into::into);
        }
    }

    None
}

then the following is the key, setting the rpath which is used to locate the dylib.

println!("cargo:rustc-link-arg=-Wl,-rpath,{}", libjvm_path.display());

this makes the tests run.