【发布时间】: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文件名为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
当我 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