Tomcat: как Tomcat самостоятельно выгружает классы?

Я ищу способ заменить банку со старой функциональностью на новую, не останавливая все приложение. Я немного погуглил ( Разгрузка классов в Java?, Динамически загружаемые и выгружаемые модули приложения в Java - как?) И нашел 3 возможных решения:

  1. OSGI, который выглядит слишком сложным для моих целей: разгрузка классов - единственное, что мне нужно из этой мощной спецификации.
  2. Собственная реализация, которая подразумевает создание собственного Classloader, загрузку jar-файлов с его помощью и, когда придет время, чтобы закрыть jar - открыть экземпляр Classloader для GC и надеяться, что GC удалит его вместе со всеми загруженными jar-файлами, что может произойти не сразу.
  3. Скопируйте материал, который делают серверы приложений:). Это цель моего вопроса.

Есть ли объяснение того, как Tomcat выгружает классы (войны)? Можно ли повторно использовать это в моем приложении?

PS Как раз в то время, когда я писал этот пост, мне в голову пришли 2 странные идеи:

  1. может быть, мы сможем запустить другой экземпляр приложения с новым набором jar-файлов и переключить потоки входных и выходных данных со старого на новый. Если есть место для сохранения состояния - это может быть быстрее, чем полный перезапуск.
  2. может быть весна может помочь? Он может динамически регистрировать бины, но это выглядит как некрасивое решение, и он все равно не может их выгружать; может быть, Spring Boot может помочь?

3 ответа

Класс может быть выгружен только тогда, когда он и его загрузчик классов недоступны и, следовательно, пригодны для сборки мусора. Поскольку загрузчик классов может достигать каждого загруженного им класса, и каждый класс, загруженный загрузчиком классов, может достигать своего загрузчика классов, и каждый объект, который является экземпляром класса, может достигать его класса, это означает, что загрузчик классов, все загруженные им классы и все объекты, которые являются экземплярами этих классов, должны быть недоступны и иметь право на сборку мусора. Только тогда класс может быть "выгружен", когда этот полный граф объектов будет собран мусором.

Я могу лишь частично ответить на ваши вопросы, но лучше, чем ничего... Вы правы, модульность - довольно утомительная тема (по крайней мере, до появления Java 9).

Идея объявления 2 (Spring): Я уже потратил некоторые мысли на Spring Boot здесь и пришел к выводу, что я буду придерживаться либо OSGI (оно того стоит), либо чисто микросервисной архитектуры.

  • Я полагаю, что вы не выполняете полное перераспределение приложения, но не хотите перезапускать все приложение каждый раз, когда вы его разрабатываете

  • Если вы хотите изменить функциональность методов без изменения класса или сигнатур методов, вы можете использовать Spring Loaded.

  • Добавьте зависимость к вашему проекту https://mvnrepository.com/artifact/org.springframework/springloaded/1.2.6.RELEASE

  • Установить параметр JVM -javaagent: путь \springloaded-version.jar -noverify

    • Эта опция может быть установлена ​​несколькими способами в зависимости от того, как вы запускаете tomcat

    • У меня есть веб-сайт Broadleaf eccomerce, и я добавил эту опцию в MAVEN_OPTS в пакетном скрипте, который запускает встроенный tomcat, или вы можете настроить его в разделе Запуск конфигурации для опций Tomcat VM

  • прочитайте http://docs.spring.io/spring-boot/docs/current/reference/html/howto-hotswapping.html

Другие вопросы по тегам