Как я могу написать приложение Java, которое может обновляться во время выполнения?


Я хотел бы реализовать приложение java (серверное приложение), которое может загрузить новую версию (.jar file) с заданного url-адреса, а затем обновите себя во время выполнения.

каков наилучший способ сделать это и возможно ли это?

Я думаю, что приложение может скачать новый .jar-файл и запустить его. Но как я должен сделать передачу, например, знать, когда новое приложение запускается, а затем выйти. Или есть лучший способ сделать это?

9 73

9 ответов:

базовая структура решения выглядит следующим образом:

  • существует основной цикл, ответственный за повторную загрузку последней версии приложения (если требуется) и его запуск.

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

есть несколько способов реализации этого. Для пример:

  • пусковая установка может быть сценарием-оболочкой или двоичным приложением, которое запускает новую JVM для запуска приложения из файла JAR, который заменяется.

  • пусковая установка может быть Java-приложением, которое создает загрузчик классов для нового JAR, загружает класс entrypoint и вызывает некоторый метод на нем. Если вы делаете это таким образом, вам нужно следить за утечками памяти classloader, но это не сложно. (Вам просто нужно убедиться, что нет объекты с классами, загруженными из JAR, доступны после перезапуска.)

преимущества внешнего подхода оболочки:

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

второй подход требует двух банок, но имеет следующие преимущества:

  • решение чисто Java и портативный,
  • переключение будет быстрее, и
  • вы можете более легко сохранить состояние через перезапуск (проблемы утечки по модулю).

" самый лучший " путь зависит от ваших специфических требований.

следует также отметить, что:

  • есть риски безопасности с автоматическим обновлением. В общем, если сервер, который предоставляет обновления, скомпрометирован, или если механизмы предоставления обновлений подвержены атаке, то автоматическое обновление может привести к компрометации клиента(ов).

  • нажатие обновления для клиента, которое наносит ущерб клиенту, может иметь юридические риски и риски для репутации вашего бизнеса.


Если вы можете найти способ избежать изобретения колеса, это было бы хорошо. Посмотреть другие ответы предложения.

в настоящее время я разрабатываю Демон JAVA Linux, а также имел необходимость реализовать механизм автоматического обновления. Я хотел ограничить свое приложение одним файлом jar и придумал простое решение:

обновления приложение обновления в себя обновления.

приложение: когда приложение обнаруживает более новую версию, оно делает следующее:

  1. загрузить обновление (Zipfile)
  2. Экстракт Применение и ApplicationUpdater (все в zipfile)
  3. запустить программу обновления

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

  1. остановить приложение (в моем случае демон через init.г)
  2. скопируйте загруженный файл jar для перезаписи текущего приложения
  3. запустить приложение
  4. очистка.

надеюсь, что это поможет кому-то.

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

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

Это известная проблема, и я рекомендую не изобретать колесо - не пишите свой собственный Хак, просто используйте то, что уже сделали другие люди.

две ситуации, которые вы должны рассмотреть:

  1. приложение должно быть самообновляемым и продолжать работать даже во время обновления (серверное приложение, встроенные приложения). Пойдите с OSGi:Пучков или равноденствие p2.

  2. приложение является настольным приложением и имеет установщик. Есть много установщики с опцией обновления. Проверьте установщиками список.

  1. Первый способ: используйте tomcat и это развертывание объектов.
  2. Второй способ: разделить приложение на две части (функциональную и обновленную) и позволить обновленной части заменить функциональную часть.
  3. Третий способ: в вашем серверном приложении просто загрузите новую версию, затем старая версия выпускает связанный порт, затем старая версия запускает новую версию (запускает процесс), затем старая версия отправляет запрос на порт приложения в новую версию для удаления старой версии, старая версия завершается и новая версия удаляет старую версию. Вроде этого: alt text

Я недавно создал update4j который полностью совместим с системой модулей Java 9.

Он будет легко начать новую версию без перезагрузки.

Это не обязательно лучшие, но это может работать для вас.

вы можете написать приложение bootstrap (ala the World of Warcraft launcher, Если Вы играли в WoW). Этот загрузчик отвечает за проверку обновлений.

  • если обновление доступно, оно предложит его пользователю, обработает загрузку, установку и т. д.
  • если приложение обновлено, оно позволит пользователю запустить применение
  • при необходимости вы можете разрешить пользователю запускать приложение, даже если оно не обновлено

таким образом, вам не придется беспокоиться о принуждении выйти из вашего приложения.

Если ваше приложение основано на интернете, и если важно, чтобы у них был обновленный клиент, вы также можете выполнять проверку версий во время работы приложения. Вы можете делать их через определенные промежутки времени, выполняя нормальную связь с сервером (некоторые или все звонки), или оба.

для продукта, над которым я недавно работал, мы выполняли проверку версий при запуске (без приложения Boot strapper, но до появления главного окна) и во время вызовов на сервер. Когда клиент устарел, мы полагались на пользователя, чтобы выйти вручную, но запретить любые действия против сервера.

обратите внимание, что я не знаю, Может ли Java вызвать код пользовательского интерфейса, прежде чем вы откроете свое главное окно. Мы использовали C# / WPF.

Если вы создаете приложение с помощью равноденствия плагины, вы можете использовать P2 Provisioning System получить готовое решение этой проблемы. Это потребует перезапуска сервера после обновления.

Я вижу проблему безопасности при загрузке новой банки (и др.), например, человек в середине атаки. Вы всегда должны подписать загружаемое обновление.

на JAX2015 Адам Бьен рассказал об использовании JGit для обновления двоичных файлов. К сожалению, я не смог найти никаких учебников.

источник на немецком языке.

Адам Бьен создал программу обновления посмотреть здесь

Я раздвоил его здесь С некоторым интерфейсом javaFX. Я тоже работаю на автоматической подписи.