【问题标题】:error while trying to use jar inside c++ code using JNI : libjvm.so not found尝试使用 JNI 在 C++ 代码中使用 jar 时出错:找不到 libjvm.so
【发布时间】:2018-06-12 15:45:58
【问题描述】:

我有一个名为 Untitled.jar 的 jar 文件,它会打印一些文本消息。它有一个void函数调用giveMeString(),类名是xegerImplementation。

giveMeString() 为在 giveMeString() 中定义的正则表达式生成字符串。我需要在给定 c++ 中的正则表达式的情况下生成字符串。由于 java 有一个名为 xeger 的库来执行此操作,所以我想创建一个 jar,然后将其导入 c++ 代码中。

我已经实现了从https://docs.oracle.com/javase/9/docs/specs/jni/invocation.html 获得的以下代码,并对其进行了调整以匹配我的 jar 文件。

cpp文件名为ma​​in.cpp,代码如下。

#include <iostream>
#include "jni.h"
int main(){
    JavaVM *jvm;       /* denotes a Java VM */
    JNIEnv *env;       /* pointer to native method interface */
    JavaVMInitArgs vm_args; /* JDK/JRE 9 VM initialization arguments */
    JavaVMOption* options = new JavaVMOption[1];
    options[0].optionString = "-Djava.class.path=/home/aaa/Desktop/Untitled.jar";
    vm_args.version = JNI_VERSION_1_8;
    vm_args.nOptions = 1;
    vm_args.options = options;
    vm_args.ignoreUnrecognized = false;
/* load and initialize a Java VM, return a JNI interface
 * pointer in env */
    JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
    delete options;
/* invoke the Main.test method using the JNI */
    jclass cls = env->FindClass("xegerImplementation");
    jmethodID mid = env->GetStaticMethodID(cls, "giveMeString", "(I)V");
    env->CallStaticVoidMethod(cls, mid);
/* We are done. */
    jvm->DestroyJavaVM();
}

当我使用 g++ main.cpp -o main 来生成可执行的主文件时。但它给了我以下错误:

/tmp/ccf3LtdA.o: In function `main':
main.cpp:(.text+0x5d): undefined reference to `JNI_CreateJavaVM'
collect2: error: ld returned 1 exit status

然后在stackoverflow的帮助下,我能够通过使用以下代码编译它来解决这个错误:

g++ -g -I/usr/lib/jvm/java-8-oracle/include/ -I/usr/lib/jvm/java-8-oracle/include/linux/ -L/usr/bin/java -L/usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/ main.cpp -o main -ljvm

它生成可执行的主文件。

然后,我尝试使用以下命令运行可执行主文件

./main

它给了我以下错误:

./main: error while loading shared libraries: libjvm.so: cannot open shared object file: No such file or directory

我尝试将 libjvm.so 的路径添加到 LD_LIBRARY_PATH。但是还是不行。

我做错了什么?任何帮助将不胜感激。

更新 1: 我将 libjvm.so 文件复制到 ubuntu 的 /lib 文件夹中。现在它找到了错误 libjvm.so 文件并且错误消失了。 现在出现了一种新型错误:

Error occurred during initialization of VM
java/lang/NoClassDefFoundError: java/lang/Object

当我 echo $JAVA_HOME 它给了我以下信息:

/usr/lib/jvm/java-8-oracle

java -version 也可以正常工作。

更新 2: 出现问题是因为我没有正确设置 LD_LIBRARY_PATH。现在我设置为$JAVA_HOME/lib/amd64:$JAVA_HOME/jre/lib/amd64/server 这样就解决了libjvm.so not found的问题。

【问题讨论】:

  • 你是如何设置LD_LIBRARY_PATH的?
  • @AlexCohn 我做了导出 LD_LIBRARY_PATH 并且当我回显时它似乎是空白的。所以我将libjvm.so文件复制到linux内核的lib文件夹中。现在,它找到了 libjvm.so,但问题是它给了我错误错误发生在 VM java/lang/NoClassDefFoundError: java/lang/Object 的初始化期间
  • 确保安装 JDK 而不仅仅是 JRE。看起来您的课程路径以某种方式混淆了。

标签: java c++11 makefile java-native-interface ubuntu-16.04


【解决方案1】:

出现问题是因为我没有正确设置 LD_LIBRARY_PATH。现在我将它设置为 $JAVA_HOME/lib/amd64:$JAVA_HOME/jre/lib/amd64/server 这样就解决了 libjvm.so not found 的问题。

【讨论】:

    【解决方案2】:

    我会从简单的代码开始:

    #include <iostream>
    #include "jni.h"
    int main(){
        JavaVM *jvm;       /* denotes a Java VM */
        JNIEnv *env;       /* pointer to native method interface */
        JavaVMInitArgs vm_args; /* JDK/JRE 9 VM initialization arguments */
        JavaVMOption* options = new JavaVMOption[1];
        options[0].optionString = "-Djava.class.path=.";
        vm_args.version = JNI_VERSION_1_8;
        vm_args.nOptions = 1;
        vm_args.options = options;
        vm_args.ignoreUnrecognized = false;
        JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
        delete options;
        jvm->DestroyJavaVM();
    }
    

    确保您的 JVM 配置正确。

    从错误信息来看,rt.jar 文件似乎不在类路径中。

    我会小心将libjvm.so 移动到/usr/lib/lib

    在此处查看从 C 调用 Java 的示例代码:

    http://jnicookbook.owsiak.org/recipe-no-027/

    您还可以在链接 C++ 时使用-rpath,以确保在运行代码时始终可以找到您的库。

    【讨论】:

    • 我不是在寻找多线程应用程序。我有一个 jar 文件,我想在 c++ 中使用它。该问题恰好发生在 JNI_CreateJavaVM 函数中。我尝试在类路径中提供 jar 文件位置。为了确保它找到我什至从终端运行了 jar 文件并且它运行但不知何故它没有在这个 JNI 中运行
    • 但是——你能运行上面的代码吗?类路径中没有 JAR?它有效吗?上面的代码至少会提示您问题是否与 JAR 或 JDK 的类路径有关。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-02
    • 1970-01-01
    • 1970-01-01
    • 2022-10-05
    • 1970-01-01
    相关资源
    最近更新 更多