簡體   English   中英

使用java.library.path和LD_LIBRARY_PATH之間的區別

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM