使用java.library.path和LD_LIBRARY_PATH之间的区别

时间:2015-01-14 14:28:49

标签: java linux java-native-interface shared-libraries

设置JVM参数

之间是否存在差异
-Djava.library.path=/path 

在JVM启动并设置Linux环境变量

export LD_LIBRARY_PATH=/path 
在JVM启动之前

这两种方法有哪些优点/缺点?

2 个答案:

答案 0 :(得分:13)

第一种形式

-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
根据{{​​1}}

的文件,

将以原生方式处理

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.) ,Android没有使用LD_LIBRARY_PATH来确定库位置,您可以从here看到Android的实现。

答案 1 :(得分:4)

Java可以明确加载-Djava.library.path=...列出的库 正如alijandro所描述的那样。

例如,如果在绑定模式下使用mq系列,则可以使用-Djava.library.path=/opt/mq/java/lib指定必需库的路径,并且mqseries将加载库。

如果库没有从java中明确加载,即必须使用依赖库,则必须使用LD_LIBRARY_PATH在jvm中使该库可用。