Перепакованный Spring Boot jar в качестве службы Windows без открытых портов с использованием JSL (JNI)
Я пытаюсь настроить Java с Spring Boot в качестве службы Windows. Открытые порты не допускаются, а также требуется приостановка и продолжение работы, что исключает использование Apache commons daemon/procrun и WinSW (что рекомендуется самой Spring).
Я нашел JSL (см. http://www.roeschter.de/), который работает через вызовы JNI в работающем экземпляре JVM с новым потоком. В случае традиционного файла.jar это работает как шарм со всеми необходимыми функциями. JSL требует, чтобы вызываемые методы находились в пути к классам в тот момент, когда открывается.jar и пока не выполняется ни один код. Однако Spring Boot поставляется с функцией переупаковки, которая перемещает все в подпапки и вложенные файлы.jars. Хотя это довольно удобная функция (вложенные файлы jar), которую Java обычно не поддерживает, она, по-видимому, лишает возможности прямого доступа к классам до того, как загрузчик Spring Boot программно создает экземпляр пути к классам (из вложенных архивов). Некоторые методы действительно доступны, например, System.exit (int) и, очевидно, org.springframework.boot.loader. *
Одна вещь, которая на самом деле работает, заключается в формулировке паузы, продолжения, выключения и т. Д. В качестве параметров, передаваемых основному методу. Однако перед вызовом моего основного метода Spring Boot воссоздает classpath каждый раз, когда выполняется такой вызов, что, как я ожидаю, в какой-то момент приведет к проблемам. Также JSL поддерживает "обратный вызов init Finished". Это в основном работает, порождая поток в JVM с заданным классом / методом перед запуском основного метода при запуске. Ожидается, что вы реализуете этот указанный метод, чтобы блокировать, пока ваша программа init не будет завершена. Довольно аккуратная и простая функция, которая прекрасно работает в обычных jar-файлах, но в Spring она запускает одновременно два экземпляра загрузки класса Spring Boot, что приводит к сбою.
Я также попытался обратиться к классам в BOOT-INF/classes/* напрямую, однако это не удалось из-за неправильных дескрипторов пакетов в классах. (У них явно нет BOOT-INF/classes/ prepended)
Использование заштрихованной банки не совсем то, что мы намереваемся сделать, поэтому я хотел бы избежать этого, а также добавленная в Spring Boot функциональность вложенных банок очень приветствуется в команде. Мы строим с Gradle, используя плагин Gradle Spring Boot.
Итак, наконец, мой вопрос (ы): как я могу настроить перепакованный.jar Spring Boot таким образом, чтобы я мог получить доступ к любому куску кода (я где-то написал) прямо из jar, не создавая путь к классу перед?
Есть ли "хороший" способ сделать это?
Может ли некоторые файлы классов внедриться непосредственно в.jar после компиляции? (это действительно забавно, и мои знания о том, как Java обрабатывает classpath, достигли своего предела)
Эта проблема очень похожа на: [ Как добавить хуки JNI к одному банку, сгенерированному Spring Boot ], но предлагаемое решение там не то, что я намереваюсь сделать (тогда я мог бы просто вызвать System.exit).
Спасибо за ваши идеи.
Ресурсы:
Документация по переупаковке Spring Boot: https://docs.spring.io/spring-boot/docs/current/reference/html/executable-jar.html