您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關java中library.path和LD_LIBRARY_PATH有什么區別,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
Java的基本數據類型分為:1、整數類型,用來表示整數的數據類型。2、浮點類型,用來表示小數的數據類型。3、字符類型,字符類型的關鍵字是“char”。4、布爾類型,是表示邏輯值的基本數據類型。
官方文檔的定義是:List of paths to search when loading libraries
從定義我們可以發現,首先是一個list,也就是說可以包括多個地址,然后這些地址是用來幫助jvm搜索需要加載的庫文件的。
最簡單的辦法就是在啟動jvm前通過java -Djava.library.path=path-to-your-libs
設置這個全局變量。
那么這個地址具體是如何被使用的呢?
當我們調用System.loadLibrary(libname)
時,會調用Runtime.loadLibary
,然后調用java/lang/ClassLoader.loadLibrary
。在ClassLoader.loadLibrary中,系統屬性java.library.path
將會被獲取,并用來生成需要加載的庫的絕對路徑,然后將這個絕對路徑傳給本地方法來調用dlopen/dlsym
并最終加載這個庫。
如果加載失敗,會根據實際情況返回三個異常值:
SecurityException ? if a security manager exists and its checkLink method doesn't allow loading of the specified dynamic library
UnsatisfiedLinkError ? if the library does not exist
NullPointerException ? if libname is null
可以參考OpenJDK的倉庫:
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); } if (loader != null) { String libfilename = loader.findLibrary(name); if (libfilename != null) { File libfile = new File(libfilename); if (!libfile.isAbsolute()) { throw new UnsatisfiedLinkError( "ClassLoader.findLibrary failed to return an absolute path: " + libfilename); } if (loadLibrary0(fromClass, libfile)) { return; } throw new UnsatisfiedLinkError("Can't load " + libfilename); } } for (int i = 0 ; i < sys_paths.length ; i++) { File libfile = new File(sys_paths[i], System.mapLibraryName(name)); if (loadLibrary0(fromClass, libfile)) { return; } } if (loader != null) { for (int i = 0 ; i < usr_paths.length ; i++) { File libfile = new File(usr_paths[i], System.mapLibraryName(name)); if (loadLibrary0(fromClass, libfile)) { return; } } } // Oops, it failed throw new UnsatisfiedLinkError("no " + name + " in java.library.path"); }
為了搞清楚這個變量的作用,我們先說明一下Unix系統是如何加載動態庫的,然后自然就明白為什么要有LD_LIBRARY_PATH以及如何使用了。
在基于GNU glibc的系統上,包括所有的linux系統,啟動一個ELF格式的二進制可執行文件會自動調用加載器加載必要的動態鏈接庫,一個最簡單的可執行文件一般也會包含一些系統的動態庫比如libc.so等。在Linux系統中,這個加載器叫做/lib/ld-linux.so.X
,這個X指的是加載器的版本號。加載器然后查找并加載所需的動態庫。
加載器在什么路徑中搜索和加載動態庫呢——/etc/ld.so.conf
,這個文件會包括/etc/ld.so.conf.d/*.conf
這些文件夾中所有的.conf文件,而具體的動態庫搜索路徑,就包含在每個.conf文件中,比如/etc/ld.so.conf.d/libc.conf
,它是libc的默認的搜索路徑/usr/local/lib
,這也是為什么我們不需要顯示聲明使用系統庫卻能自動完成加載的原因,也是為什么不同的系統編出來的庫無法通用的可見原因之一,因為不同系統的/usr/local/lib
目錄下的動態庫并不一致。
如果每次啟動都去查找所有的目錄,那樣顯然是比較笨的做法,所以使用/etc/ld.so.cache
來緩存路徑,并通過ldconfig來更新這個緩存路徑,有興趣的可以自行查看一下這個緩存文件。實際上,這個緩存路徑也很長了,基本上包含了系統可能存放動態庫的路徑。
上面我們說到可以通過cache和ldconfig來簡化搜索和加載動態庫的流程,但是還有兩個問題沒有考慮到,一是還沒有將編出來的庫放到系統目錄中去,二是依賴庫數量很少,不需要經過這么復雜的查找。
LD_LIBRARY_PATH
就是用來滿足這個需要,它也指定一個搜索路徑,且ld-linux.so會優先在這個路徑下搜索需要的動態庫,如果沒找到,再去ld.so.conf中指定的目錄尋找。
export LD_LIBRARY_PATH=paths-to-libs
需要注意的一點是,多個目錄是通過
:
隔開的
前面分別介紹了java.library.path 和 LD_LIBRARY_PATH,都是為了加載所需的動態庫,有什么區別呢?
前者是在java環境中調用,在jvm啟動前設置生效;后者也是在啟動前,但是是在Unix環境中使用前者是通過修改property來設置路徑;后者是直接增加了ld-linux.so的搜索路徑對于JNI直接調用的庫,最好使用前者,對于有多重依賴關系的庫,最好使用LD_LIBRARY_PATH
上述就是小編為大家分享的java中library.path和LD_LIBRARY_PATH有什么區別了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。