什么是 libJvm.so,何时建造?

What is libJvm.so, and when is it built?

本文关键字:何时建 so libJvm 什么      更新时间:2023-10-16

我有点惊讶我不得不发布一个看起来相当琐碎且易于查找的问题......但显然不是。

因为看起来我的jni.hlibJvm.so库不同步(或者我怀疑),这出现在试图将我的 Java 应用程序作为库加载到 Linux 上的C++环境中(带有JNI_CreateJVM()等等),我想知道哪个可能是罪魁祸首。jni.h只是标准配置,包含所有普通模块。然而libJvm.so...我看不出内容是什么....我什至不知道它到底是什么以及如何/在哪里建造的。

任何人都可以给我一个解释/答案吗?

附言问题与库路径和相关问题无关......可以找到libJvm.so。只要我不完全知道我正在使用的所有组件,就很难理解出了什么问题......

下面是一个更新,以下是对我的问题的反应中的评论(这是一个很长的更新,因为我决定包含我正在使用的代码可能会很有见地)......

我正在使用的代码(并遇到问题),在代码之后,我还说了一些关于环境/设置和环境的信息......

#include <jni.h>
#include "jvm.h"
#include <iostream>
#include <stdlib.h>
#include <dlfcn.h>
using namespace std;
//Create type for pointer to the JNI_CreateJavaVM function
typedef jint (*CreateJvmFuncPtr) (JavaVM**, void**, JavaVMInitArgs*); 
//New method returns pointer to the JNI_CreateJavaVM function
CreateJvmFuncPtr findCreateJvm() { 
CreateJvmFuncPtr createJvm = NULL;
void* jvmLib = dlopen("/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.71.x86_64/jre/lib/amd64/server/libjvm.so", RTLD_LAZY); //Get handle to jvm shared library
char* error = dlerror(); //Check for errors on dlopen
if(jvmLib == NULL || error != NULL) {
printf("FailedToLoadJVMn");
}
//Load pointer to the function within the shared library
createJvm = (CreateJvmFuncPtr) dlsym(jvmLib, "JNI_CreateJavaVM");
error = dlerror();
if(error != NULL) {
printf("Successn");
}
return createJvm;

}

int main() {
// load and initialize JVM and JNI interface, in a test setting where JVM is "passive"
// (called/loaded as .dll) and the JNI env is not available yet from a Java/JVM call
// (which would be the caste in the normal setup/configuration).
//int jniLoadJvmAsDll()
//{
JavaVM *jvm;                      // Pointer to the JVM (Java Virtual Machine)
JNIEnv *env;                      // Pointer to native interface
//======== prepare loading of Java VM: assign init arguments for JVM init =========
JavaVMInitArgs vm_args;                        // Initialization arguments
//       JavaVMOption* vmOptions = new JavaVMOption[1];   // JVM invocation options
JavaVMOption vmOptions[4];
// (=> comparable to lib path for System.load(libPath/libName)
vmOptions[0].optionString = "-Djava.compiler=NONE";           /* disable JIT */
vmOptions[1].optionString = "-Djava.class.path=/home/adminuser/workspace_Unit_Test_Java_Cpp/Unit_Test_Jni_Java/bin"; // which Java class to load
vmOptions[2].optionString = "-Djava.library.path=/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.71.x86_64/jre/lib/amd64/;/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.71.x86_64/jre/lib/amd64/server";
vmOptions[3].optionString = "-verbose:jni";                   /* print JNI-related messages */
vm_args.version = JNI_VERSION_1_6;             // minimum Java version
vm_args.nOptions = 1;                          // number of options
vm_args.options = vmOptions;
vm_args.ignoreUnrecognized = false;     // invalid options make the JVM init fail
//=============== load and initialize Java VM and JNI interface =============
// old code: jint retCrJvm = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);  // YES !!
//New code:
CreateJvmFuncPtr createJVM = findCreateJvm();
printf("findCreateJVM() returned 0x%xn", createJVM);
jint retCrJvm = createJVM(&jvm, (void**)&env, &vm_args);
//End new code
delete vmOptions;    // we then no longer need the initialization options.
if (retCrJvm != JNI_OK) {
// TO DO: error processing...
cin.get();
exit(EXIT_FAILURE);
}
//====================handle multithread situatiation ========================
JavaVM * curVM = NULL;           // JVM in current thread, should contain loaded VM
// otherwise we're not in the main thread
JNIEnv *curEnv;
int jvmLoadFailed = 1;
// handle situation that we're not in the main thread (current thread isnt't main thread)
if (jvm == NULL) {
env->GetJavaVM( &curVM ); // JVM should contain current/main thread JVM, otherwise
// we're not in the main thread
int vmStat = curVM->GetEnv((void **)&curEnv, JNI_VERSION_1_6);
if (vmStat == JNI_EDETACHED)  //We are on a different thread, attach
curVM->AttachCurrentThread((void **) &curVM, NULL);
if( curVM == NULL )
return jvmLoadFailed;  //Can't attach to java, bail out
}
//=============== Display JVM version =======================================
cout << "JVM load (as .so/.dll) succeeded: Version ";
jint ver = env->GetVersion();
std::cout << ((ver>>16)&0x0f) << "."<<(ver&0x0f) << endl;
// TO DO: add the code that will use JVM <============  (see next steps)
// insert the JNITools separate methods here.... for each separate graphical structure
// initially a test class is inserted.....
jclass clsTestPrint = env->FindClass("TestPrint");  // try to find the class
if(clsTestPrint == NULL) {
cerr << "ERROR: class not found !";
}
jmethodID ctor = env->GetMethodID(clsTestPrint, "<init>", "()V");  // find an object constructor for this class
if(ctor == NULL) {
cerr << "ERROR: constructor not found !" << endl;
}
else {
cout << "Object succesfully constructed !"<<endl;
jobject prtObj = env->NewObject(clsTestPrint, ctor); // invoke the object constructor: create print object
if (prtObj) {
jmethodID show = env->GetMethodID(clsTestPrint, "showId", "()V");
if(show == NULL)
cerr << "No showId method !!" << endl;
else env->CallVoidMethod(prtObj, show);
}
}

jvm->DestroyJavaVM();
cin.get();
return 0;

//}

}

其中"dlopen"和"dlsym"当然取代了你在Windows上使用的"loadLibrary()"和"getProcaddress()"调用1。 加载.dll并获取相应 JNI 过程的句柄...但我是在 Linux 上这样做的,因此是"等效翻译"......

"多线程"装饰在这里并不真正相关......添加它以备将来可能的目的。

经过一些实验,我成功地配置了构建设置,以便也找到了 libjvm.so,并在其中找到了API JNI方法JNI_CreateJavaVM().... 为此,我添加了(在Linux上,使用Eclipse)以下"GCC C++ Linker"设置: -- => "库" => "库 (-l)" => "Jvm" 和 => "库搜索路径 (-L)" => "/usr/lib/jvm/java-1.7.0.openjdk-1.7.0.71.x86_64/jre/lib/amd64/server">

-- => "共享库设置" => ">

共享对象名称" => "libjvm.so">

其他设置在编译/链接期间出错。

有了这个,就可以构建环境。调试器在 main 中启动和停止,我可以像往常一样逐步执行C++代码,直到......我到达 JNI_CreateJavaVM() 调用。此时将发生以下错误。

重新定位错误:/home/adminuser/workspace_Unit_Test_Java_Cpp/Unit_Test_Jni_Cpp/Debug/Unit_Test_Jni_Cpp:符号 JNI_CreateJavaVM,版本 SUNWprivate_1.1 未在具有链接时间引用的文件 libjvm.so 中定义

我在此强烈怀疑: 1. JNI 标头和库 (libJvm.so) 不同步,或 2. 类路径或 lib 路径不包含正确的值 3. 加载的 Java .so (.dll) (带有 "dlopen") 不是它应该的样子....

知道要使用哪个值吗?

这就是"我问题的背景:要确定 jni 和 libJvm.so 内容是否不同步,知道它是什么以及它在哪里非常方便......

a) 确保/usr/lib/jvm/java-1.7.0.openjdk-1.7.0.71.x86_64/jre/lib/amd64/在你的LD_LIBRARY_PATH

b) 切换回"旧代码",在没有 DLOPEN 和其他东西的情况下隐式加载libjvm.so