代码之家  ›  专栏  ›  技术社区  ›  Grumblesaurus

C++中的Java JNI启动器:在没有JavaFX的情况下工作,使用JavaFX进行核心转储

  •  1
  • Grumblesaurus  · 技术社区  · 7 年前

    我已经编写了一个C++ JNI java启动程序。如果我启动一个不使用JavaFX的java程序,它会工作,但是如果我尝试启动一个JavaFX程序,它会创建一个核心转储。代码如下:

    Without JavaFX - launch.cpp

    With JavaFX - launch.ccp

    只有使用本机启动器时,才会发生核心转储。如果我使用相同的参数运行JavaFX程序 java

    Here's the content of the hs_err file, in a pastebin.

    我创建了一个包含两个分支的存储库,其中包含完整的可运行示例,而不是从少数几个文件中粘贴代码。

    Full Example - No JavaFX

    Full Example - With JavaFX

    您可以通过编辑来运行示例 build.sh run-native.sh 换线 jdk="/usr/lib/jvm/java-11-oracle" 为您的系统准确。然后:

    ./build.sh          #compiles the java program and cpp program
    ./run-native.sh     #Sets LD_LIBRARY_PATH and runs the compiled cpp program
       or
    ./run-with-java.sh  #only on "withjfx" branch, runs via java at cli. 
    

    No JavaFX JavaFX 版本仅通过调用 可执行,如果通过本机启动器执行,则会转储内核。

    最后,这里是我尝试使用本机启动器运行JavaFX版本时得到的转储:

    #
    # A fatal error has been detected by the Java Runtime Environment:
    #
    #  SIGSEGV (0xb) at pc=0x00007f77513575d8, pid=15281, tid=15301
    #
    # JRE version: Java(TM) SE Runtime Environment (11.0.1+13) (build 11.0.1+13-LTS)
    # Java VM: Java HotSpot(TM) 64-Bit Server VM (11.0.1+13-LTS, mixed mode, tiered, compressed oops, g1 gc, linux-amd64)
    # Problematic frame:
    # j  java.util.Arrays$ArrayList.<init>([Ljava/lang/Object;)V+6 java.base@11.0.1
    #
    # Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport %p %s %c %d %P" (or dumping to /home/joshua/work/javalaunch/core.15281)
    #
    # An error report file with more information is saved as:
    # /home/joshua/work/javalaunch/hs_err_pid15281.log
    Compiled method (c2)     326  208       4       java.util.Objects::requireNonNull (14 bytes)
     total in heap  [0x00007f7758e10d90,0x00007f7758e10fc8] = 568
     relocation     [0x00007f7758e10f08,0x00007f7758e10f18] = 16
     main code      [0x00007f7758e10f20,0x00007f7758e10f60] = 64
     stub code      [0x00007f7758e10f60,0x00007f7758e10f78] = 24
     metadata       [0x00007f7758e10f78,0x00007f7758e10f80] = 8
     scopes data    [0x00007f7758e10f80,0x00007f7758e10f90] = 16
     scopes pcs     [0x00007f7758e10f90,0x00007f7758e10fc0] = 48
     dependencies   [0x00007f7758e10fc0,0x00007f7758e10fc8] = 8
    Could not load hsdis-amd64.so; library not loadable; PrintAssembly is disabled
    #
    # If you would like to submit a bug report, please visit:
    #   http://bugreport.java.com/bugreport/crash.jsp
    #
    ./run-native.sh: line 6: 15281 Aborted                 (core dumped) ./bin/launch
    

    根据这里一位用户的建议,基于之前的崩溃,我在系统上安装了hsdis-amd64.so,并指出 LD_LIBRARY_PATH

    #
    # A fatal error has been detected by the Java Runtime Environment:
    #
    #  SIGSEGV (0xb) at pc=0x00007f9e6e2015d8, pid=17530, tid=17550
    #
    # JRE version: Java(TM) SE Runtime Environment (11.0.1+13) (build 11.0.1+13-LTS)
    # Java VM: Java HotSpot(TM) 64-Bit Server VM (11.0.1+13-LTS, mixed mode, tiered, compressed oops, g1 gc, linux-amd64)
    # Problematic frame:
    # j  java.util.Arrays$ArrayList.<init>([Ljava/lang/Object;)V+6 java.base@11.0.1
    #
    # Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport %p %s %c %d %P" (or dumping to /home/joshua/work/so-question/core.17530)
    #
    # An error report file with more information is saved as:
    # /home/joshua/work/so-question/hs_err_pid17530.log
    Compiled method (c2)     372  187       4       java.util.Objects::requireNonNull (14 bytes)
     total in heap  [0x00007f9e75cbb890,0x00007f9e75cbbac8] = 568
     relocation     [0x00007f9e75cbba08,0x00007f9e75cbba18] = 16
     main code      [0x00007f9e75cbba20,0x00007f9e75cbba60] = 64
     stub code      [0x00007f9e75cbba60,0x00007f9e75cbba78] = 24
     metadata       [0x00007f9e75cbba78,0x00007f9e75cbba80] = 8
     scopes data    [0x00007f9e75cbba80,0x00007f9e75cbba90] = 16
     scopes pcs     [0x00007f9e75cbba90,0x00007f9e75cbbac0] = 48
     dependencies   [0x00007f9e75cbbac0,0x00007f9e75cbbac8] = 8
    Loaded disassembler from hsdis-amd64.so
    #
    # If you would like to submit a bug report, please visit:
    #   http://bugreport.java.com/bugreport/crash.jsp
    #
    ./run-native.sh: line 6: 17530 Aborted                 (core dumped) ./bin/launch
    

    更新:我在Ubuntu18.04和Windows7上都复制了这个问题。

    1 回复  |  直到 7 年前
        1
  •  0
  •   Grumblesaurus    7 年前

    我想出来了。问题出现在第35行,其中的参数传递给JVM的主方法:

    env->CallStaticVoidMethod( cls, main, " ");

    我们正在向Java传递一个c字符串,其中Java需要Java.lang.string[]。一旦有人试图读取该参数,JVM就会崩溃。JavaFX必须在main和start()之间的某个点读取参数,并因此崩溃。

    env->CallStaticVoidMethod( cls, main, "(I)V"); (我还没有测试过这个,但这是java人员提供的示例代码中的一行常见代码)

    或:

    jclass classString = env->FindClass("java/lang/String");
    jobjectArray argsToJava = env->NewObjectArray(0, classString, NULL);
    env->CallStaticVoidMethod( cls, main, argsToJava );
    
    推荐文章