我想在我的Java應用程序中加載自己的本地庫。這些本地庫依賴於第三方庫(當我的應用程序安裝在客戶端計算機上時,可能會或可能不存在)。Java:加載依賴於其他庫的庫
在我的java應用程序中,我要求用戶指定依賴庫的位置。獲得這些信息後,我使用它來使用JNI代碼更新「LD_LIBRARY_PATH」環境變量。以下是我用來更改「LD_LIBRARY_PATH」環境變量的代碼片段。
Java代碼
public static final int setEnv(String key, String value) { if (key == null) { throw new NullPointerException("key cannot be null"); } if (value == null) { throw new NullPointerException("value cannot be null"); } return nativeSetEnv(key, value); } 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; const char *nativeValue = NULL; nativeKey = (*env)->GetStringUTFChars(env, key, NULL); nativeValue = (*env)->GetStringUTFChars(env, value, NULL); int result = setenv(nativeKey, nativeValue, 1); return (jint) result; }
我也有相應的天然方法來獲取環境變量。
我可以成功地更新LD_LIBRARY_PATH(這種說法是基於C例程getenv()
。
我仍然無法加載我的本地庫的輸出。仍不能檢測的依賴第三方庫。
任何幫助/指針讚賞我使用Linux 64位
編輯:。
我寫了一個SSCE(C語言)來測試,如果動態加載程序是在這裏工作是SSCE
#include #include #include #include int main(int argc, const char* const argv[]) { const char* const dependentLibPath = "...:"; const char* const sharedLibrary = "..."; char *newLibPath = NULL; char *originalLibPath = NULL; int l1, l2, result; void* handle = NULL; originalLibPath = getenv("LD_LIBRARY_PATH"); fprintf(stdout,"\nOriginal library path =%s\n",originalLibPath); l1 = strlen(originalLibPath); l2 = strlen(dependentLibPath); newLibPath = (char *)malloc((l1+l2)*sizeof(char)); strcpy(newLibPath,dependentLibPath); strcat(newLibPath,originalLibPath); fprintf(stdout,"\nNew library path =%s\n",newLibPath); result = setenv("LD_LIBRARY_PATH", newLibPath, 1); if(result!=0) { fprintf(stderr,"\nEnvironment could not be updated\n"); exit(1); } newLibPath = getenv("LD_LIBRARY_PATH"); fprintf(stdout,"\nNew library path from the env =%s\n",newLibPath); handle = dlopen(sharedLibrary, RTLD_NOW); if(handle==NULL) { fprintf(stderr,"\nCould not load the shared library: %s\n",dlerror()); exit(1); } fprintf(stdout,"\n The shared library was successfully loaded.\n"); result = dlclose(handle); if(result!=0) { fprintf(stderr,"\nCould not unload the shared library: %s\n",dlerror()); exit(1); } return 0; }
C代碼也不起作用。顯然,動態加載器不會重讀LD_LIBRARY_PATH環境變量。我需要弄清楚如何強制動態加載器重新讀取LD_LIBRARY_PATH環境變量。
我真的不明白爲什麼它不起作用,因爲我已經做了一些非常相似的事情(在Windows下),它的功能就像一個魅力。順便說一下,你是否嘗試過(僅用於調試目的),將System.load(...)加載到一個「默認」lib目錄中,以查看庫是否損壞(而不是nativeSetEnv代碼) 。然而,很好的問題(+1) – gd1 2011-04-29 22:42:23
..這是主題,但我認爲你應該釋放由GetStringUTFChars分配的內存 – gd1 2011-04-29 22:42:56
@Giacomo:它起作用,如果我啓動我的應用程序時設置LD_LIBRARY_PATH。我將釋放分配的內存。感謝您指出。 :) – 2011-05-02 19:04:56