设置 JVM native 库的两种方式

Difference between using java.library.path and LD_LIBRARY_PATH

设置 JVM native 库有两种方式。

第一种 -Djava.library.path=/path

这种方式是通过java的代码实现的本地库加载,调用栈为:System.loadLibrary > Runtime.loadLibary > java/lang/ClassLoader.loadLibrary > dlopen/dlsym,注意 dlopen/dlsym 是操作系统提供的 api,由于加载行为是由 java 代码触发的,那么如果加载失败,java 代码可以填充一些异常信息。下面是 OpenJDK 的实现代码

// 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

这种方式可以理解为发生在jvm完全启动之前,根据 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 further details):

  • (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.
  • 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.)

这种方式,如果加载本地库失败,不会获得很多有用的错误信息,甚至忽略了加载错误。


- - - - - - - - End Thank For Your Reading - - - - - - - -
0%