Связывание статической библиотеки с JNI

Java-версии, предшествующие Java 8, требуют, чтобы собственный код находился в общей библиотеке, но я прочитал, что с Java 8 можно использовать статические связанные библиотеки с JNI. Я искал примеры, но не смог найти.

Как я могу статически связать библиотеку JNI с моим java-приложением?

Ответы

Ответ 1

Спецификация Java SE 8 была изменена для поддержки статического связывания, а статическое связывание реализовано в JDK. Это кратко упоминается в спецификации для System.loadLibrary. Разделы спецификации JNI, на которые он ссылается, здесь и здесь.

Родные сигнатуры методов и типы данных одинаковы для статически и динамически связанных методов. Возможно, вам придется взломать make файлы JDK, чтобы связать вашу библиотеку статически.

Одно существенное различие заключается в том, как инициализируются статические библиотеки. Динамические библиотеки инициализируются вызовом функции JNI_OnLoad и деинициализируются вызовом JNI_OnUnload. Каждая динамическая библиотека может иметь собственную версию этих функций. Если существует несколько статически связанных библиотек, ясно, что они не могут иметь функции с такими же именами. Для статической библиотеки с именем libname функции загрузки/выгрузки JNI_OnLoad_libname и JNI_OnUnload_libname.

Функция JNI_OnLoad_libname должна вернуть значение JNI_VERSION_1_8 или выше. Если это не так, JVM будет игнорировать статическую библиотеку.

В принципе, если вы вызываете System.loadLibrary("foo"), система ищет функцию JNI_OnLoad_foo в исполняемом исполняемом образце, и если она найдена, предполагается, что библиотека статически связана, а ее собственные методы выполняются в пределах бегущий образ. Если JNI_OnLoad_foo не найден, тогда происходит обычная загрузка и загрузка динамических библиотек, а встроенные методы связаны из найденной динамической библиотеки.

Ответ 2

В соответствии с JEP 178, с которым вы связались в своем комментарии, вам не нужно ничего делать по-другому. System.loadLibrary теперь будет загружать как динамические, так и статические библиотеки.

Не требуется никаких изменений в существующем Java-коде, чтобы использовать статическую родную библиотеку в отличие от динамической родной библиотеки. Метод invoke формы System.loadLibrary( "foo" ), в частности, должен иметь возможность загружать библиотеку "foo" независимо от того, предоставлена ​​ли эта библиотека в статической или динамической форме.

Вероятно, вам просто нужно убедиться, что ваш java.library.path установлен правильно.