使用 java.library.path 和 LD_LIBRARY_PATH 的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27945268/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between using java.library.path and LD_LIBRARY_PATH
提问by christian
Is there a difference between setting the JVM argument
设置JVM参数有区别吗
-Djava.library.path=/path
at JVM start and setting the Linux environment variable
在 JVM 启动时设置 Linux 环境变量
export LD_LIBRARY_PATH=/path
before the JVM is started?
在 JVM 启动之前?
What are the advantages/disadvantages of the two approaches?
这两种方法的优点/缺点是什么?
采纳答案by alijandro
The first form
第一种形式
-Djava.library.path=/path
will be handled in java bytecode level, System.loadLibrary
will call Runtime.loadLibary
, then will call java/lang/ClassLoader.loadLibrary
. In the function call ClassLoader.loadLibrary
, the system property java.library.path
will be checked to get the full path of the library and pass this full path to native code to call system api dlopen/dlsym
, eventually make the library loaded. You can browse the source from OpenJDKrepository. The following code snippet is the segment I copy from the link.
将在 Java 字节码级别处理,System.loadLibrary
将调用Runtime.loadLibary
,然后将调用java/lang/ClassLoader.loadLibrary
. 在函数调用中ClassLoader.loadLibrary
,java.library.path
会检查系统属性以获取库的完整路径,并将此完整路径传递给本机代码调用系统api dlopen/dlsym
,最终使库加载。您可以从OpenJDK存储库浏览源代码。以下代码片段是我从链接中复制的片段。
The advantage of this form is that you will get error or warning or exception in Java code, if there are some problems with your library path.
这种形式的好处是,如果你的库路径有问题,你会在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);
}
// ....
The second form
第二种形式
export LD_LIBRARY_PATH=/path
will be handled in native, according to the document of dlopen/dlsym
将在本地处理,根据文档 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.)
In this manner, if there are some problems with your library path and the system can't load your library, the system won't give too much clue what happen and will fail silently (I guess). It depends whether or not to implement LD_LIBRARY_PATH
, Android didn't use LD_LIBRARY_PATH
to determine the library location, you can see Android's implementation from here.
以这种方式,如果您的库路径存在一些问题并且系统无法加载您的库,系统将不会提供太多线索并且会静默失败(我猜)。要看要不要实现LD_LIBRARY_PATH
,Android没有LD_LIBRARY_PATH
用来判断库位置,可以从这里看Android的实现。
回答by christian
Java can explicitely load libaries listed with -Djava.library.path=...
as described by alijandro.
Java 可以-Djava.library.path=...
如 alijandro 所述显式加载列出的库 。
For example, if mq series is used in bindings mode, the path for the neccessary libraries can be specified with -Djava.library.path=/opt/mq/java/lib
and mqseries loads the libraries.
例如,如果在绑定模式下使用 mq 系列,则可以指定所需库的路径 -Djava.library.path=/opt/mq/java/lib
并 mqseries 加载库。
If a library is not explcitely loaded from java, i.e. a dependent library has to be used, then LD_LIBRARY_PATH
has to be used to have that library available in the jvm.
如果库不是从 java 显式加载的,即必须使用依赖库,则LD_LIBRARY_PATH
必须使用该库才能在 jvm 中使用该库。