尝试在使用JNI的c ++代码中使用jar时出错:找不到libjvm.so

时间:2018-01-02 23:48:35

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

我有一个名为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文件名是 main.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

当我回复$ 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的问题。

2 个答案:

答案 0 :(得分:1)

问题出现了,因为我没有正确设置LD_LIBRARY_PATH。现在我将它设置为$ JAVA_HOME / lib / amd64:$ JAVA_HOME / jre / lib / amd64 / server这解决了找不到libjvm.so的问题。

答案 1 :(得分:0)

我已经开始使用简单的代码了:

#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,以确保在运行代码时始终找到您的lib。