web-dev-qa-db-ja.com

現在のプラットフォームでJava.library.pathがどの変数にマップされているかを調べることはできますか?

これまでに、Java.library.pathプロパティについて次のことを学びました。

  • Javaクラスではなく、ネイティブライブラリのロード時に使用されます
  • デフォルト値はオペレーティングシステムに依存します:
    • Windowsでは、PATHにマップします
    • Linuxでは、LD_LIBRARY_PATHにマップします
    • OS Xでは、DYLD_LIBRARY_PATHにマップします

(上記のいずれかを誤解した場合は修正してください)

私の動機:

Javaアプリケーションを呼び出すように設定したフレームワークからJavaアプリケーションによって認識されるJava.library.pathの値を変更したい。これを行うには、Java.library.pathプロパティを直接設定するのではなく、マップ先のシステムパス変数を変更します。 specificいOS固有のコードを持たない、または可能であればEdgeケースを除外する、これを行うためのクリーンな方法が欲しいです。

私の質問:

ローカルJava実装に、Java.library.pathがどの環境変数にマップされるかを尋ねる方法はありますか?

次に、シェルスクリプトで、次の行に沿って何かを書くことができます。

path_var = get_library_path_variable  # the magic function I want to call
${path_var} = /my/custom/path:${${path_var}}
26
Charlie

これは完全に不合理な質問ではありませんが、良い答えはありませんので、後世のためにwhyあなたが動けなくなる理由と、それがうまくいかない理由を説明しようとします。

  1. Java.library.pathは、環境変数から設定されることはまったく保証されていません。 -Djava.library.path=を使用して、希望するものを指定できます。おそらく、これは本当にとにかくやりたいことです。それがオプションが存在する理由です。

  2. (少なくともWindows上では)探している環境変数は、単純に使用されているだけではないことがわかります。このコードを試してください。

    package com.stackoverflow;
    
    import Java.util.Map;
    
    public class LibPathFinder {
        public static void main(String[] args) {
            String javaLibPath = System.getProperty("Java.library.path");
            Map<String, String> envVars = System.getenv();
            System.out.println(envVars.get("Path"));
            System.out.println(javaLibPath);
            for (String var : envVars.keySet()) {
                System.err.println("examining " + var);
                if (envVars.get(var).equals(javaLibPath)) {
                    System.out.println(var);
                }
            }
        }
    }
    

    実行すると、印刷される最初の2つのことが異なることに注意してください。 Javaがwindows PATH変数を使用している場合、最初に値をいじっています。何が起こっているのかを調査するのをあきらめました。ポイントは、環境変数がありませんでしたJava.library.pathと完全に一致しました。LinuxまたはOSXでは試しませんでした。あなたの走行距離は異なる場合があります

  3. このような誰かの環境変数をいじるのは、あまり良いことではありません。これらはシェル全体に使用されるため、ユーザーに環境に共有ライブラリを持たせることをコミットしていますが、時々のみです。 Java.library.pathを変更する唯一の本当の理由は、ネイティブライブラリを追加することです。ネイティブライブラリを使用している場合は、OS固有のコードが既にあり(プラットフォーム用にコンパイルする必要がありますか?)、「プラットフォーム固有のEdgeケースがない」ための戦いはすでにあきらめています。最良の方法は、ネイティブライブラリを、システムパス(それが何であれ)が既に見つける場所に置くか、何らかの方法でインストーラーを使用してライブラリのパスを追加することです永続的に 。これらのいずれかを行いたくない場合は、@ malatのコードのバリエーションを使用し、実際のJava.library.pathを出力し、その結果にパスをスクリプトに追加してから使用することをお勧めします-Dオプションを使用して、実際のプログラム実行用に設定します。

16
Ian McLaird

私のLinuxボックスでは、次のようにします。

$ cat GetSystemProperty.Java
import Java.util.Properties;
import Java.util.Enumeration;

public class GetSystemProperty {
  public static void main(String args[]) {
    if( args.length == 0 ) {
      Properties p = System.getProperties();
      Enumeration keys = p.keys();
      while (keys.hasMoreElements()) {
        String key = (String)keys.nextElement();
        String value = (String)p.get(key);
        System.out.println(key + " : " + value);
      }
    }
    else {
      for (String key: args) {
        System.out.println(System.getProperty( key ));
      }
    }
  }
}
$ javac GetSystemProperty.Java
$ Java GetSystemProperty Java.library.path
/usr/lib/jvm/Java-6-openjdk/jre/lib/AMD64/server:/usr/lib/jvm/Java-6-openjdk/jre/lib/AMD64:/usr/lib/jvm/Java-6-openjdk/jre/../lib/AMD64:/usr/Java/packages/lib/AMD64:/usr/lib/jni:/lib:/usr/lib
10
malat