我想在我的 java 应用程序中加载我自己的本机库。这些本机库依赖于第三方库(当我的应用程序安装在客户端计算机上时,这些库可能存在也可能不存在)。
在我的 java 应用程序中,我要求用户指定依赖库的位置。获得此信息后,我将使用它来使用 JNI 代码更新“LD_LIBRARY_PATH”环境变量。以下是我用来更改“LD_LIBRARY_PATH”环境变量的代码片段。
Java 代码
public static final int setEnv(String key, String value) { 如果(键==空){ throw new NullPointerException("key 不能为 null"); } 如果(值 == 空){ throw new NullPointerException("值不能为空"); } 返回nativeSetEnv(键,值); } public static final native int nativeSetEnv(String key, String value);
Jni 代码 (C)
JNIEXPORT jint JNICALL Java_Test_nativeSetEnv(JNIEnv *env, jclass cls, jstring key, jstring value) { const char *nativeKey = NULL; 常量字符 *nativeValue = NULL; nativeKey = (*env)->GetStringUTFChars(env, key, NULL); nativeValue = (*env)->GetStringUTFChars(env, value, NULL); int result = setenv(nativeKey, nativeValue, 1); 返回(jint)结果; }
我也有相应的本地方法来获取环境变量。
我可以成功更新 LD_LIBRARY_PATH(此断言基于 C 例程的输出getenv()
。
我仍然无法加载我的本机库。仍然没有检测到依赖的第三方库。
任何帮助/指针表示赞赏。我正在使用 Linux 64 位。
编辑:
我写了一个 SSCE(用 C 语言)来测试动态加载器是否工作。这里是 SSCE
#包括 #包括 #包括 #包括 int main(int argc, const char* const argv[]) { const char* constdependentLibPath = "...:"; const char* const sharedLibrary = "..."; 字符 *newLibPath = NULL; 字符 *originalLibPath = NULL; int l1,l2,结果; 无效*句柄 = NULL; originalLibPath = getenv("LD_LIBRARY_PATH"); fprintf(stdout,"\n原始库路径 =%s\n",originalLibPath); l1 = strlen(originalLibPath); l2 = strlen(dependentLibPath); newLibPath = (char *)malloc((l1+l2)*sizeof(char)); strcpy(newLibPath,dependentLibPath); strcat(newLibPath,originalLibPath); fprintf(stdout,"\n新库路径 =%s\n",newLibPath); 结果 = setenv("LD_LIBRARY_PATH", newLibPath, 1); 如果(结果!= 0){ fprintf(stderr,"\n环境无法更新\n"); 退出(1); } newLibPath = getenv("LD_LIBRARY_PATH"); fprintf(stdout,"\n来自 env 的新库路径 =%s\n",newLibPath); 句柄 = dlopen(sharedLibrary, RTLD_NOW); 如果(句柄==NULL){ fprintf(stderr,"\n无法加载共享库:%s\n",dlerror()); 退出(1); } fprintf(stdout,"\n 共享库加载成功。\n"); 结果 = dlclose(句柄); 如果(结果!= 0){ fprintf(stderr,"\n无法卸载共享库:%s\n",dlerror()); 退出(1); } 返回0; }
C 代码也不起作用。显然,动态加载程序没有重新读取 LD_LIBRARY_PATH 环境变量。我需要弄清楚如何强制动态加载器重新读取 LD_LIBRARY_PATH 环境变量。