从Rust

时间:2017-11-01 14:56:47

标签: java rust java-native-interface

我想启动一个JVM并从Rust调用一个静态Java方法。最初一切正常,我在控制台中看到了预期的输出。但是,在Java方法结束之前,我遇到了分段错误。

这是输出:

Hello World!
Segmentation fault (core dumped)

这是Java类(打包在胖罐子里):

public class HelloWorld {
    public static void greetings() {
        System.out.println("Hello World!");
    }
}

这是我执行的Rust代码:

extern crate rucaja;

use rucaja::{Jvm, jvalue};

fn main() {

    // The class path must contain the fat JAR.
    let class_path = "-Djava.class.path=./java/target/hello-0.1.0.jar";

    let jvm_options = [class_path];

    unsafe {
        // Instantiate the embedded JVM.
        let jvm = Jvm::new(&jvm_options);

        // Resolve the Java wrapper class from the fat JAR.
        let main_class = jvm.get_class("HelloWorld").expect("Could not find Java class");

        // Resolve Java methods in that wrapper class.
        let greetings_method = jvm.get_static_method(
            &main_class,
            "greetings",
            "()V"
        ).expect("Could not find Java method");

        // Prepare (no) arguments
        let args: Vec<jvalue> = vec![
        ];

        // Call the method
        jvm.call_static_object_method(
            &main_class,
            &greetings_method,
            args.as_ptr()
        );
    }

    println!("Done");
}

我尝试使用gdb运行它,但堆栈看起来很糟糕:

Program received signal SIGSEGV, Segmentation fault.
0x00007fffe575d2b4 in ?? ()
(gdb) bt
#0  0x00007fffe575d2b4 in ?? ()
#1  0x0000000000000246 in ?? ()
#2  0x00007fffe575d160 in ?? ()
#3  0x00007fffffffd530 in ?? ()
#4  0x00007fffffffd4e0 in ?? ()
#5  0x00007ffff790a6ad in ?? () from /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

您认为分段错误的原因是什么?

1 个答案:

答案 0 :(得分:2)

Java方法不返回对象,因此必须使用jvm.call_static_void_method(...)而不是jvm.call_static_object_method(...)

正确的代码:

// Call the method
jvm.call_static_void_method(
    &main_class,
    &greetings_method,
    args.as_ptr()
);

然后程序运行良好:

Hello World!
Done