動態鏈接庫搜索規則
1、java 中加載 native library
java 中 System.loadLibrary 會調用 Runtime.loadLibary,後者調用 java/lang/ClassLoader.loadLibrary。
在 ClassLoader.loadLibrary 中,會檢查系統屬性 java.library.path ,在其指定的目錄(多個)中搜索 native loadLibrary。
java 啓動參數 -Djava.library.path=/path 可以設置搜索目錄
2、C 庫中加載動態鏈接庫
C 庫中 dlopen() 如果參數中不包含“/”,那麼用下面的規則搜索動態鏈接庫
a、如果加載鏈中存在 rpath,則在 rpath 中搜索 (僅 linux ELF)
b、在 LD_LIBRARY_PATH 中搜索
c、在系統 lib 目錄中搜索
d、如果加載鏈中存在 runpath,則在 runpath 中搜索(僅 linux ELF)
兩者幾乎完全獨立,但是 java 是依賴 C 的,所以 java 搜索沒有找到時,也會使用 C 庫搜索機制。
針對鏈接庫找不到的問題,建議:
a、在構建JNI庫時指定 rpath 參數
g++ -shared -rpath . -L xxx -l yyy -o sss.so
b、次優方案是啓動時使用 LD_LIBRARY_PATH 環境變量
LD_LIBRARY_PATH=xxxx java -jar aaa.jar