Объединение родной DLL с банкой
Возможный дубликат:
Как связать собственную библиотеку и библиотеку JNI внутри JAR?
Мне нужно включить собственный lib (jnotify, но я думаю, что это не имеет значения) для моей банки. Я хочу сделать это с помощью NetBeans.
Я добавил Bundle-NativeCode: /lib/jnotify.dll; osname=win32
в мой файл manifest.mf
и добавил папку jnotify.dll
в projektHome\src\lib\
. Но, к сожалению, NetBeans превосходит файл manifest.mf
.
Как я могу исправить? Могу ли я сделать это, используя только NetBeans? Правильно ли это строка 'Bundle-NativeCode: /lib/jnotify.dll; osname=win32
? Я также слышал, что я должен положить хэши dll в manifest.mf
и подписать мою банку. Это правда?
Ответы
Ответ 1
Я не думаю, что исполняемый файл Java поддерживает Bundle-NativeCode
. Я уверен, что это атрибут OSGi. Список поддерживаемых атрибутов определен в JAR File Specification.
Внешние рамки, которые его предоставляют, не содержат встроенной поддержки для связывания собственных библиотек внутри JAR файлов. Если я правильно помню, можно извлечь файл во временное место и загрузить его вручную.
Ответ 2
Иногда я обнаружил, что проблема заключается не в Java-способе загрузки родных библиотек, а в сторонней библиотеке, которая нуждается в этом собственном коде.
Проблема в том, что сторонние библиотеки будут делать в какой-то момент (обычно очень рано в инициализации)
System.loadLibrary("native.dll");
И если native.dll не находится в соответствующем месте, он выдает ошибку.
Если у вас есть доступ к источнику java библиотеки сторонних разработчиков, это может быть легко исправить этот код, и вы можете легко извлечь свою DLL из JAR и запустить System.load перед использованием сторонней библиотеки.
Обновление
Я просмотрел источники JNotify. Это именно то, что я сказал:
public class JNotify_win32
{
static
{
System.loadLibrary("jnotify"); /* *** */
int res = nativeInit();
if (res != 0)
{
throw new RuntimeException("Error initialiing native library. (#" + res + ")");
}
}
Возьмите строку *** out или surround с помощью try-catch, загрузите System.load(), и все будет готово.
Ответ 3
Я столкнулся с этой проблемой при попытке подключить событие выключения Windows, когда программа работает на этой ОС. Решение, которое я в конечном итоге использовал, было по существу McDowell - добавление DLL в файл jar и извлечение его во временное место при запуске программы. Если он подходит вашей программе, вы можете оставить DLL в более постоянном месте, а затем ссылаться на нее при последующих запусках программы. Мое приложение использовалось в среде, где пользователи могли бы умышленно удалять файлы, которые им не нужны, поэтому мне пришлось извлекать DLL при каждом запуске. Однако это не привело к значительным последствиям производительности.