Могу ли я узнать, какая переменная java.library.path отображается на текущей платформе?

До сих пор я узнал следующее о свойстве java.library.path:

  • Он использовался при загрузке собственных библиотек, в отличие от классов Java
  • Его значение по умолчанию зависит от операционной системы:
    • В Windows он отображает PATH
    • В Linux он сопоставляется с LD_LIBRARY_PATH
    • В OS X он сопоставляется с DYLD_LIBRARY_PATH

(Пожалуйста, поправьте меня, если я неправильно понял любой из вышеперечисленных)

Мотивация:

Я хочу изменить значение java.library.path, видимое приложением Java из фреймворка, который я настроил для вызова приложения Java. Я хочу сделать это, не устанавливая свойство java.library.path напрямую, а вместо этого изменяя переменную системного пути, к которой она привязана. Я бы хотел, чтобы был чистый способ сделать это, у которого нет уродливого кода, специфичного для ОС, или, если это возможно, оставьте края.

Мой вопрос:

Есть ли способ спросить локальную реализацию Java, к какой переменной среды java.library.path сопоставляется?

Затем, в сценарии оболочки, я мог бы написать что-то по строкам:

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

Ответ 1

Это не совсем необоснованный вопрос, но нет хорошего ответа, поэтому для потомков я попытаюсь объяснить, почему вы застряли, и почему это не сработает.

  1. java.library.path не может быть установлен из переменной среды вообще. Вы можете указать, к чему вы хотите, с -Djava.library.path=. Скорее всего, это то, что вы действительно хотите сделать в любом случае. Вот почему существует опция.

  2. Оказывается (по крайней мере на окнах), что переменная среды, которую вы ищете, не просто используется без проблем. Попробуйте этот код.

    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);
                }
            }
        }
    }
    

    Вы заметите, что при запуске первые две вещи, которые он печатает, различны. Если Java использует PATH Windows, она сначала начинает вычислять значение. Я бросил расследование, что происходит. Дело в том, что не было переменной среды, которая точно соответствовала java.library.path. Я не пытался использовать Linux или OSX, ваш пробег может варьироваться

  3. Это действительно не очень приятно связываться с такими переменными среды, как это. Они используются для всей оболочки, поэтому вы обязываете своих пользователей иметь свою общую библиотеку в своей среде, но только иногда. Единственной реальной причиной изменения java.library.path является добавление собственных библиотек. Если вы используете родные библиотеки, то у вас уже есть код, специфичный для ОС (его нужно скомпилировать для платформы, верно?), Так что вы действительно уже отказались от борьбы за "отсутствие конкретных случаев для конкретной платформы". Лучше всего поместить вашу родную библиотеку в место, где системный путь (независимо от того, что может быть) уже найдет его, или добавить к нему свой путь к библиотеке с помощью какого-либо установщика. Если вы не хотите делать что-либо из этого, я бы предложил использовать вариацию кода @malat, распечатав настоящий java.library.path, а затем добавив путь к этому результату в ваш скрипт, а затем воспользуемся -D чтобы установить его для реального запуска программы.

Ответ 2

В моем linux box, вот что я сделал бы:

$ 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