JII-зависимые библиотеки

Я запускаю библиотеку через JNI (я ее не писал), и внутренне она вызывает другую DLL. Я получаю сообщение об ошибке "Не могу найти зависимые библиотеки", если я не поместил путь к другой DLL в переменную PATH системы (я нахожусь в Windows XP). Я хотел бы иметь возможность справиться с этим в командной строке java, и я уже пытался добавить его к -Djava.library.path и к пути к классам, ни то, что работало (я ожидал -Djava.library.path работать но не classpath, но не работал). Есть ли способ сделать это?

спасибо,

Джефф

Ответ 1

  • Если у вас есть DLL-имя "MyNativeDLL.dll", вы должны использовать "MyNativeDLL" в своем вызове LoadLibrary.
  • Используйте Dependency Walker, чтобы проверить, есть ли файлы, необходимые MyNativeDLL.dll
  • Если они есть, включите их в ту же папку, что и MyNativeDLL.dll, - один из них вы попробуете загрузить дополнительные файлы в папку System32.

Ответ 2

Мне удалось заставить это работать, не помещая DLL файлы в PATH, используя System.load() для всех DLL в обратном порядке зависимости. Чтобы быть ясным, я вызывал System.load() во всех зависимых DLL, а не только JNI DLL. Вам не нужно вызывать System.load() в DLL, которые поставляются с Windows (они находятся в PATH).

Я делал это в веб-приложении, где в jar содержались библиотеки DLL, которые распаковывались. Ваша ситуация кажется более простой, поэтому я считаю, что она должна работать. Я обычно выполнял решение здесь: Как сделать JAR файл, содержащий файлы DLL?

Ответ 3

Это очень помогло мне. Также управлялась загрузка DLL JNI, созданная с использованием cygwin:

сначала:

/* conditioned if OS is windows because also need it to work in Linux env. */ 
System.loadLibrary("cygwin1"); 

то

System.loadLibrary("mylib"); 

В окнах для этого требуется либо установить java.library.path для соответствия местоположению обеих библиотек.

При запуске из Eclipse этот параметр может быть заменен на "Native Libraries Location" в пути сборки Java (в настройках библиотек JRE).

Однако, все еще это немного сложно.

Ответ 4

Я успешно ввел папку в переменную PATH с помощью JNA. Это можно использовать в качестве обходного пути, если вы хотите развернуть свои зависимые DLL вместе с вашим приложением, не загрязняя глобальную среду или не вмешиваясь в явный порядок загрузки DLL.

Однако мне непонятно, как влияет на это жизненный цикл classloader. Я только пробовал этот метод в модульной системе NetBeans, но если вы просмотрите класс класса ClassLoader для loadLibrary, вы увидите, что он кэширует некоторые переменные пути. Может понадобиться или нет необходимости создавать новый загрузчик классов для загрузки библиотеки.

Недостатком является использование JNA или JNI. Кроме того, это выглядит довольно грубо. См. здесь для примера того, как установить переменную среды с помощью JNA.

Ответ 5

Для меня создание статической сборки сработало так:

g++ -static

Он добавляет зависимые библиотеки в самой сборке.