Подтвердить что ты не робот

Is -Djava.library.path =... эквивалентно System.setProperty( "java.library.path",...)

Загружаю внешнюю библиотеку, помещенную в ./lib. Эти два решения задают эквивалент java.library.path?

  • Задайте путь в консоли при выполнении jar:

    java -Djava.library.path=./lib -jar myApplication.jar
    
  • Задайте путь в коде перед загрузкой библиотеки:

    System.setProperty("java.library.path", "./lib");
    

Если они эквивалентны, почему во втором решении Java не может найти библиотеку, в то время как первая в порядке?

Если нет, существует ли способ установить путь в коде?

4b9b3361

Ответ 1

Вообще говоря, оба подхода имеют одинаковый сетевой эффект в том, что системное свойство java.library.path установлено в значение ./lib.

Однако некоторые системные свойства оцениваются только в определенные моменты времени, такие как запуск JVM. Если java.library.path входит в число этих свойств (и ваш эксперимент, похоже, указывает на это), то использование второго подхода не будет иметь заметного эффекта, кроме как вернуть новое значение при будущих вызовах getProperty().

Как правило, использование свойства командной строки -D работает во всех свойствах системы, а System.setProperty() работает только с свойствами, которые не только проверяются во время запуска.

Ответ 2

Несмотря на то, что он недостаточно хорошо документирован, системное свойство java.library.path является свойством "только для чтения" в отношении метода System.loadLibrary(). Это сообщенная ошибка, но она была закрыта Sun, а не исправлена. Проблема в том, что JVM ClassLoader читает это свойство один раз при запуске, а затем кэширует его, не позволяя нам впоследствии его программно изменять. Строка System.setProperty("java.library.path", anyVal); не будет иметь эффекта, кроме вызовов метода System.getProperty().

К счастью, кто-то опубликовал обходной путь на форумах Sun. К сожалению, эта ссылка больше не работает, но я нашел код в другом источнике. Вот код, который вы можете использовать для работы, не имея возможности установить системное свойство java.library.path:

public static void addDir(String s) throws IOException {
    try {
        // This enables the java.library.path to be modified at runtime
        // From a Sun engineer at http://forums.sun.com/thread.jspa?threadID=707176
        //
        Field field = ClassLoader.class.getDeclaredField("usr_paths");
        field.setAccessible(true);
        String[] paths = (String[])field.get(null);
        for (int i = 0; i < paths.length; i++) {
            if (s.equals(paths[i])) {
                return;
            }
        }
        String[] tmp = new String[paths.length+1];
        System.arraycopy(paths,0,tmp,0,paths.length);
        tmp[paths.length] = s;
        field.set(null,tmp);
        System.setProperty("java.library.path", System.getProperty("java.library.path") + File.pathSeparator + s);
    } catch (IllegalAccessException e) {
        throw new IOException("Failed to get permissions to set library path");
    } catch (NoSuchFieldException e) {
        throw new IOException("Failed to get field handle to set library path");
    }
}

ПРЕДУПРЕЖДЕНИЕ: Это может не работать на всех платформах и/или JVM.

Ответ 3

вы можете добавить три строки

 System.setProperty("java.library.path", "/path/to/libs" );
 Field fieldSysPath = ClassLoader.class.getDeclaredField( "sys_paths" );
 fieldSysPath.setAccessible( true );
 fieldSysPath.set( null, null );

а также импортировать java.lang.reflect.Field Это нормально для решения проблемы