Использование Java native library на серверах приложений

Java native library (JNL) представляет собой JAR-архив, содержащий в себе JNI-код и объекты, которые операционная система может загрузить в качестве разделяемых библиотек. Это позволяет вызывать из Java-приложения функции, реализованные платформо-зависимыми методами. Способы создания JNL — это тема отдельной большой статьи, поэтому считаем, что у вас уже есть JNL и вы хотите ею воспользоваться в своем приложении. Об особенностях использования JNL в приложениях, работающих под управлением сервера приложений, и будет эта статья.

Использование JNL приводит к следующим негативным последствиям:

Однако в некоторых случаях без JNL обойтись невозможно. В качестве примеров можно назвать:

Использование JNL в standalone-приложениях практически ничем не отличается от использования обычных Java-библиотек. Т.е. необходимым условием является расположение JNL в месте, известном загрузчику классов (обычно достаточно разместить библиотеку где-нибудь в classpath). Однако иногда бывает необходимо разместить JNL в каталоге, непосредственно доступном и системному загрузчику ОС.

А вот если приложение предназначено для работы на каком-либо сервере приложений, то просто так засунуть JNL WAR/EAR файл и задеплоить его вместе с самим приложением на сервер не получится. Причина очевидна: возможная дыра в безопасности. Приложение с JNL получает доступ к операционной системе с привилегиями сервера приложений (это как минимум). Сервер приложений имеет свою собственную систему безопасности, и обходить ее пользовательскому приложению будет как-то не по пацански.

Таким образом, если вы засунете JNL непосредственно в EAR или WAR, то приложение, конечно же, задеплоится. Но вот при попытке вызова JNI-кода вы получите исключение (скорее всего это будет java.lang.UnsatisfiedLinkError с диагностикой Native Library already loaded in another classloader).

Так что же, использование JNL на сервере приложений абсолютно невозможно? На самом деле, это не так. Просто необходимо объяснить самому серверу приложений, что JNL используется на законных основаниях (и, наверное, ее использование для самого сервера приложений будет более-менее безопасно). Ну и далее начинаются тонкости, зависящие от конкретного сервера приложений.

В любом случае, при компиляции Java-кода необходимо указать пути к используемой JNL (чтобы иметь возможность ссылаться на содержащиеся в ней Java-классы), но вот упаковывать ее внутрь EAR/WAR или JAR файла, предназначенного для деплоймента, не надо. Дальнейшие действия зависят от целевого сервера приложений.

Glassfish 3.x, 4.x

Необходимо скопировать JNL в domain-dir/lib или domain-dir/lib/ext (при этом JNL будет доступна для всех приложений). В конфигурации Glassfish и в пользовательском приложении никаких дополнительных изменений делать не требуется.

WildFly, Jboss

Здесь все немного сложнее. Последовательность действий следующая:
@Vedga
08.09.2015 12:03 UTC
Первоисточник