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

До сих пор я узнал следующее о свойстве 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}}

Ответы [ 2 ]

16 голосов
/ 13 декабря 2013

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

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

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

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

10 голосов
/ 10 декабря 2013

На моей 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
...