Объединение родной 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 при каждом запуске. Однако это не привело к значительным последствиям производительности.