[英]Difference between using java.library.path and LD_LIBRARY_PATH
設置JVM參數之間是否存在差異
-Djava.library.path=/path
在JVM啟動並設置Linux環境變量
export LD_LIBRARY_PATH=/path
在JVM啟動之前?
這兩種方法有哪些優點/缺點?
第一種形式
-Djava.library.path=/path
將在java字節碼級別處理, System.loadLibrary
將調用Runtime.loadLibary
,然后將調用java/lang/ClassLoader.loadLibrary
。 在函數調用ClassLoader.loadLibrary
,將檢查系統屬性java.library.path
以獲取庫的完整路徑,並將此完整路徑傳遞給本機代碼以調用系統api dlopen/dlsym
,最終使庫加載。 您可以從OpenJDK存儲庫瀏覽源代碼。 以下代碼段是我從鏈接中復制的段。
此表單的優點是,如果庫路徑存在一些問題,您將在Java代碼中收到錯誤或警告或異常。
// Invoked in the java.lang.Runtime class to implement load and loadLibrary.
static void loadLibrary(Class fromClass, String name,
boolean isAbsolute) {
ClassLoader loader =
(fromClass == null) ? null : fromClass.getClassLoader();
if (sys_paths == null) {
usr_paths = initializePath("java.library.path");
sys_paths = initializePath("sun.boot.library.path");
}
if (isAbsolute) {
if (loadLibrary0(fromClass, new File(name))) {
return;
}
throw new UnsatisfiedLinkError("Can't load library: " + name);
}
// ....
第二種形式
export LD_LIBRARY_PATH=/path
根據dlopen/dlsym
的文件,將以原生方式處理
dlopen()
The function dlopen() loads the dynamic library file named by the null-terminated string filename and returns an opaque "handle" for the
dynamic library. If filename is NULL, then the returned handle is for the main program. If filename contains a slash ("/"), then it is
interpreted as a (relative or absolute) pathname. Otherwise, the dynamic linker searches for the library as follows (see ld.so(8) for fur‐
ther details):
o (ELF only) If the executable file for the calling program contains a DT_RPATH tag, and does not contain a DT_RUNPATH tag, then the
directories listed in the DT_RPATH tag are searched.
o If, at the time that the program was started, the environment variable LD_LIBRARY_PATH was defined to contain a colon-separated list of
directories, then these are searched. (As a security measure this variable is ignored for set-user-ID and set-group-ID programs.)
以這種方式,如果您的庫路徑存在一些問題,並且系統無法加載您的庫,系統將不會給出太多線索會發生什么,並且會無聲地失敗(我猜)。 這取決於是否實現LD_LIBRARY_PATH
,Android沒有使用LD_LIBRARY_PATH
來確定庫的位置,你可以從這里看到Android的實現。
Java可以明確地加載使用-Djava.library.path=...
列出的庫,如alijandro所述。
例如,如果在綁定模式下使用mq系列,則可以使用-Djava.library.path=/opt/mq/java/lib
指定必需庫的路徑,並且mqseries將加載庫。
如果庫沒有從java中明確加載,即必須使用依賴庫,則必須使用LD_LIBRARY_PATH
在jvm中使該庫可用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.