Я хотел бы реализовать приложение Java (серверное приложение), которое может загружать новую версию (файл .jar) с заданного URL-адреса, а затем обновлять себя во время выполнения.
Как лучше всего это сделать и возможно ли это?
Я предполагаю, что приложение может загрузить новый файл .jar и запустить его. Но как мне выполнить передачу, например, узнать, когда новое приложение запущено, а затем выйти. Или есть способ лучше?
Ответы:
Базовая структура решения следующая:
Существует основной цикл, отвечающий за многократную загрузку последней версии приложения (при необходимости) и ее запуск.
Приложение делает свое дело, но периодически проверяет URL загрузки. Если он обнаруживает новую версию, он возвращается в программу запуска.
Есть несколько способов реализовать это. Например:
Средство запуска может быть сценарием-оболочкой или двоичным приложением, которое запускает новую JVM для запуска приложения из заменяемого файла JAR.
Средство запуска может быть приложением Java, которое создает загрузчик классов для нового JAR, загружает класс точки входа и вызывает для него какой-то метод. Если вы сделаете это таким образом, вам придется следить за утечками хранилища загрузчика классов, но это несложно. (Вам просто нужно убедиться, что никакие объекты с классами, загруженными из JAR, не доступны после перезапуска.)
Преимущества подхода внешней оболочки:
Второй подход требует двух JAR, но имеет следующие преимущества:
«Лучший» способ зависит от ваших конкретных требований.
Также следует отметить, что:
При автоматическом обновлении есть риски безопасности. В общем, если сервер, предоставляющий обновления, скомпрометирован или если механизмы предоставления обновлений уязвимы для атак, то автоматическое обновление может привести к компрометации клиента (ов).
Отправка клиенту обновления, которое причиняет ущерб клиенту, может иметь юридические риски и риски для репутации вашего бизнеса.
Если вы найдете способ не изобретать велосипед заново, это будет хорошо. См. Другие ответы для предложений.
источник
В настоящее время я разрабатываю JAVA Linux Daemon, и мне также нужно было реализовать механизм автоматического обновления. Я хотел ограничить свое приложение одним файлом jar и нашел простое решение:
Упакуйте программу обновления в само обновление.
Приложение : когда приложение обнаруживает более новую версию, оно выполняет следующие действия:
ApplicationUpdater : при запуске программа обновления выполняет следующие действия:
Надеюсь, это кому-то поможет.
источник
Это известная проблема, и я не рекомендую изобретать колесо - не пишите свой собственный хак, просто используйте то, что уже сделали другие люди.
Вам необходимо рассмотреть две ситуации:
Приложение должно быть самообновляемым и продолжать работать даже во время обновления (серверное приложение, встроенные приложения). Используйте OSGi: Bundles или Equinox p2 .
Приложение является настольным приложением и имеет установщик. Есть много установщиков с возможностью обновления. Проверить список установщиков .
источник
Недавно я создал update4j, который полностью совместим с модульной системой Java 9.
Новая версия будет запущена без перезагрузки.
источник
Я написал приложение Java, которое может загружать плагины во время выполнения и сразу же начинать их использовать, вдохновленное аналогичным механизмом в jEdit. jEdit имеет открытый исходный код, так что вы можете посмотреть, как он работает.
Решение использует собственный ClassLoader для загрузки файлов из jar. Как только они загружены, вы можете вызвать какой-нибудь метод из нового jar-файла, который будет действовать как его
main
метод. Затем сложнее всего убедиться, что вы избавились от всех ссылок на старый код, чтобы его можно было собрать мусором. Я не совсем специалист в этой части, я заставил это работать, но это было непросто.источник
NetworkClassLoader
JavaDoc есть пример для ClassLoaderисточник
Это не обязательно лучший способ, но он может сработать для вас.
Вы можете написать приложение для начальной загрузки (как лаунчер World of Warcraft, если вы играли в WoW). Этот бутстрап отвечает за проверку обновлений.
Таким образом, вам не нужно беспокоиться о принудительном выходе из вашего приложения.
Если ваше приложение является веб-приложением и важно, чтобы у него был актуальный клиент, вы также можете выполнять проверку версии во время работы приложения. Вы можете выполнять их через определенные промежутки времени, выполняя обычную связь с сервером (некоторые или все вызовы) или и то, и другое.
Для продукта, над которым я недавно работал, мы выполняли проверку версии при запуске (без приложения загрузочного ремня, но до появления главного окна) и во время обращений к серверу. Когда клиент устарел, мы полагались на то, что пользователь завершит работу вручную, но запрещали любые действия против сервера.
Обратите внимание, что я не знаю, может ли Java вызывать код пользовательского интерфейса до того, как вы откроете главное окно. Мы использовали C # / WPF.
источник
Если вы создаете свое приложение с использованием плагинов Equinox , вы можете использовать P2 Provisioning System, чтобы получить готовое решение этой проблемы. Это потребует перезапуска сервера после обновления.
источник
Я вижу проблему безопасности при загрузке нового jar-файла (и т. Д.), Например, атака человека посередине. Вы всегда должны подписывать загружаемое обновление.
На JAX2015 Адам Бьен рассказал об использовании JGit для обновления двоичных файлов. К сожалению, я не смог найти никаких руководств.
Источник на немецком языке.
Адам Бьен создал программу обновления см. Здесь
Я раздвоил это раздвоил здесь с помощью внешнего интерфейса javaFX. Я также работаю над автоматической подписью.
источник