Здравствуйте, Цыба, Вы писали:
Ц>Здравствуйте!
[skipped]
Способ есть и если проблема редеплоя стоит остро, то можно сделать сдедующее:
сделать свой класс-лшфдер и грузить нативный класс и его зависимости только в рамках этого лоадера. Далее на аплоаде сервлета нужно освободить все ссылки на нативный класс и его лоадер и вызвать сборку мусора. Поглядите ссылку на по русски все объясняется, но и две другие поглядите тоже. Думаю поможет
Здравствуйте, Xeor, Вы писали:
X>Здравствуйте, Цыба, Вы писали:
[skipped]
это будет работать только в самых простых случаях, когда не используются именованные объекты ядра, когда не открываются файлы с одинаковыми именами и когда зависимости твоей библиотеки следуют этим же правилам. Это плохой подход.
Я его тоже использовал в одном проекте и столкнулся с вышеперечисленным + оказалось, что если решение проще.
Здравствуйте, Цыба, Вы писали:
Ц> Получается, единственным способом удалить библиотеку при переразвёртывании является остановка JVM (в данном случае — Tomcat), что недопустимо. Неужели не существует хоть какого-то способа обойти эту проблему?
А если вообще все просто сделать? Перед System.loadLibrary() копировать библиотеку в dll со случайно сгенерированным именем, и грузить её.
Вот, столкнулись на проекте со следующей ситуацией, которая, по ходу, неизвестно решаема ли нормальным путём. Есть веб-приложение, работающее под Tomcat. Это приложение в силу некоторых требований должно использовать механизм JNI, причём используемые нативные библиотеки являются частью самого веб-приложения и развёртываются вместе с ним. Вроде бы, всё замечательно, но мы не учли один подводный камень, а именно тот факт, что после вызова System.load() используемая .dll (.so пока под Linux не проверяли, но кажется, там так же) не освобождается при переразвёртывании этого веб-приложения. В итоге директория с приложением после этого неудаляема, поскольку нативная библиотека уже загружена в память. Метода System.unload(), к сожалению, не существует. Ни Google, ни Stack Overflow не помогли... Получается, единственным способом удалить библиотеку при переразвёртывании является остановка JVM (в данном случае — Tomcat), что недопустимо. Неужели не существует хоть какого-то способа обойти эту проблему?
после вызова System.load() используемая .dll (.so пока под Linux не проверяли, но кажется, там так же) не освобождается при переразвёртывании этого веб-приложения. В итоге директория с приложением после этого неудаляема, поскольку нативная библиотека уже загружена в память.
Под линухом этой проблемы не будет, если я правильно понял. Там можно удалять файлы и каталоги, используемые другими процессами. Высвобождение inode выполняется после того, как на него не осталось ссылок (из родительского каталога и от активных процессов). Поэтому, например, можно обновлять компоненты системы на лету (даже KDE, не останавливая его).
Re: Веб-приложения под Tomcat с использованием JNI
Здравствуйте, Цыба, Вы писали:
Ц>Получается, единственным способом удалить библиотеку при переразвёртывании является остановка JVM (в данном случае — Tomcat), что недопустимо. Неужели не существует хоть какого-то способа обойти эту проблему?
По крайней мере JNI_OnUnload ведь существует:
void JNI_OnUnload(JavaVM *vm, void *reserved);
The VM calls JNI_OnUnload when the class loader containing the native library is garbage collected. This function can be used to perform cleanup operations. Because this function is called in an unknown context (such as from a finalizer), the programmer should be conservative on using Java VM services, and refrain from arbitrary Java call-backs.
Не знаю правда, можно ли тут гарантированно выгрузить требуемую библиотеку, но поиграться можно
Re[2]: Веб-приложения под Tomcat с использованием JNI
Здравствуйте, Xeor, Вы писали:
X>По крайней мере JNI_OnUnload ведь существует:
X>
X>void JNI_OnUnload(JavaVM *vm, void *reserved);
X> The VM calls JNI_OnUnload when the class loader containing the native library is garbage collected. This function can be used to perform cleanup operations. Because this function is called in an unknown context (such as from a finalizer), the programmer should be conservative on using Java VM services, and refrain from arbitrary Java call-backs.
X>Не знаю правда, можно ли тут гарантированно выгрузить требуемую библиотеку, но поиграться можно
Мне кажется, это не совсем то, что нужно. Поскольку это обработчик события, он, очевидно, вызвется только тогда, когда останавливается сам Tomcat. Сутью проблемы, по большому счёту, является невозможность пока (или просто неумение) выгружать нативную библиотеку нужным образом. Возможно, для этого нужно убрать все ссылки на экземпляры единственного класса (возможно, принудительным вызовом сборщика мусора), который использует эту библиотеку, но сам вызов System.load() вызывается в статическом блоке инициализации (простите, не очень владею терминологией Java, и я здесь имею в виду static { System.load(...); } ), что, похоже, даже усугубляет ситуацию. Как быть — не знаю.
Re[2]: Веб-приложения под Tomcat с использованием JNI
Здравствуйте, dimgel, Вы писали:
D>Под линухом этой проблемы не будет, если я правильно понял. Там можно удалять файлы и каталоги, используемые другими процессами. Высвобождение inode выполняется после того, как на него не осталось ссылок (из родительского каталога и от активных процессов). Поэтому, например, можно обновлять компоненты системы на лету (даже KDE, не останавливая его).
Хм, интересно... Но поддержка Windows также нужна, и на ней провернуть такой трюк, на сколько мне известно, невозможно в принципе.
Re: Веб-приложения под Tomcat с использованием JNI
Здравствуйте, Цыба, Вы писали:
Ц>Вот, столкнулись на проекте со следующей ситуацией, которая, по ходу, неизвестно решаема ли нормальным путём. Есть веб-приложение, работающее под Tomcat. Это приложение в силу некоторых требований должно использовать механизм JNI, причём используемые нативные библиотеки являются частью самого веб-приложения и развёртываются вместе с ним. Вроде бы, всё замечательно, но мы не учли один подводный камень, а именно тот факт, что после вызова System.load() используемая .dll (.so пока под Linux не проверяли, но кажется, там так же) не освобождается при переразвёртывании этого веб-приложения.
Да, это невозможно. DLL — глобальный ресурс для всей JVM, и в общем случае его нельзя выгрузить.
Единственное, что могу порекомендовать — скопируйте .dll/.so в другой файл, и попробуйте загрузить снова.
Sapienti sat!
Re: Веб-приложения под Tomcat с использованием JNI
Ц> частью самого веб-приложения и развёртываются вместе с ним.
А вынести загрузку найтивной библиотеки в сам контейнер не возможно?
Например в контейнере загружаешь найтивную обертку, и в ней (найтивно) реализуешь функционал загрузки\выгрузки библиотеки. А путь передаешь, где у тебя лежит библиотека в вебПриложении
PS: Наверняка ты уже рассматривал такой вариант, но на всякий случай...
Re: Веб-приложения под Tomcat с использованием JNI
Это выглядит как последствия использования инструмента не по назначению. Томкат как веб сервер должен парсить запрос и отдавать ресурс, т.е. обслуживать HTTP. И все. Обработка запроса, поиск ресурса, его создание и прочее — это лучше возложить на другие приложения, сервисы, внешние по отношению к веб серверу.