【发布时间】:2015-03-12 18:34:35
【问题描述】:
设置JVM参数有区别吗
-Djava.library.path=/path
在 JVM 启动和设置 Linux 环境变量时
export LD_LIBRARY_PATH=/path
在JVM启动之前?
这两种方法的优缺点是什么?
【问题讨论】:
标签: java linux java-native-interface shared-libraries
设置JVM参数有区别吗
-Djava.library.path=/path
在 JVM 启动和设置 Linux 环境变量时
export LD_LIBRARY_PATH=/path
在JVM启动之前?
这两种方法的优缺点是什么?
【问题讨论】:
标签: java linux java-native-interface shared-libraries
Java 可以显式加载以-Djava.library.path=... 列出的库
如 alijandro 所述。
例如,如果 mq series 用于绑定模式,则可以使用 -Djava.library.path=/opt/mq/java/lib 指定所需库的路径,然后 mqseries 加载库。
如果一个库不是从 java 中明确加载的,即必须使用依赖库,则必须使用 LD_LIBRARY_PATH 使该库在 jvm 中可用。
【讨论】:
第一种形式
-Djava.library.path=/path
将在 java 字节码级别处理,System.loadLibrary 将调用Runtime.loadLibary,然后将调用java/lang/ClassLoader.loadLibrary。在函数调用ClassLoader.loadLibrary中,会检查系统属性java.library.path获取库的全路径,并将该全路径传递给native code调用系统apidlopen/dlsym,最终使库加载。您可以从OpenJDK 存储库浏览源代码。以下代码 sn -p 是我从链接中复制的段。
这种形式的好处是,如果你的库路径有问题,你会在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的文档以native方式处理
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来确定库位置,可以从here看到Android的实现。
【讨论】:
$LD_LIBRARY_PATH中找到它们。