web-dev-qa-db-ja.com

Java.library.pathとLD_LIBRARY_PATHの使用の違い

JVM引数の設定に違いはありますか

-Djava.library.path=/path 

jVMの開始時およびLinux環境変数の設定

export LD_LIBRARY_PATH=/path 

jVMが起動する前に?

2つのアプローチの長所と短所は何ですか?

17
christian

最初の形式

-Djava.library.path=/path

Javaバイトコードレベルで処理され、System.loadLibraryRuntime.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);
    }
// ....

2番目の形式

export LD_LIBRARY_PATH=/path

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

このように、ライブラリパスに問題があり、システムがライブラリを読み込めない場合、システムは何が起こっているのかについてあまり手がかりを与えず、サイレントに失敗します(私は推測します)。 LD_LIBRARY_PATHを実装するかどうかによって異なります、Androidはライブラリの場所を決定するためにLD_LIBRARY_PATHを使用しませんでした。Androidの実装は ここに

16
alijandro

Javaは、alijandroの説明に従って、-Djava.library.path=...でリストされたライブラリを明示的にロードできます。

たとえば、mqシリーズがバインディングモードで使用されている場合、必要なライブラリのパスは-Djava.library.path=/opt/mq/Java/libで指定でき、mqseriesはライブラリをロードします。

ライブラリがJavaから明示的にロードされていない場合、つまり依存ライブラリを使用する必要がある場合は、LD_LIBRARY_PATHを使用してそのライブラリをjvmで使用できるようにする必要があります。

4
christian