我想在我的 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 环境变量。