Wie kann ich eine Java-Anwendung schreiben, die sich zur Laufzeit selbst aktualisieren kann?

Ich möchte eine Java-Anwendung (Server-Anwendung) implementieren, die eine neue Version (JAR-Datei) von einer bestimmten URL herunterladen und dann selbst zur Laufzeit aktualisieren kann.

Was ist der beste Weg dies zu tun und ist es möglich?

Ich schätze, dass die Anwendung eine neue .jar-Datei herunterladen und starten kann. Aber wie soll ich die Übergabe machen, zB wissen wann die neue Anwendung gestartet wird und dann beenden. Oder gibt es einen besseren Weg, dies zu tun?

Die grundlegende Struktur einer Lösung ist wie folgt:

  • Es gibt eine Hauptschleife, die dafür verantwortlich ist, die neueste Version der App (falls erforderlich) wiederholt zu laden und zu starten.

  • Die Anwendung macht ihre Sache, überprüft aber regelmäßig die Download-URL. Wenn es eine neue Version erkennt, wird es zum Launcher zurückversetzt.

Es gibt verschiedene Möglichkeiten, dies zu implementieren. Beispielsweise:

  • Der Launcher könnte ein Wrapper-Skript oder eine Binäranwendung sein, die eine neue JVM startet, um die Anwendung von einer JAR-Datei auszuführen, die ersetzt wird.

  • Der Launcher könnte eine Java-Anwendung sein, die einen classnlader für die neue JAR erstellt, eine Eintragspunktklasse lädt und eine Methode dafür aufruft. Wenn Sie es so machen, müssen Sie nach Speicherlecks im Classloader Ausschau halten, aber das ist nicht schwer. (Sie müssen nur sicherstellen, dass keine Objekte mit geladenen classn aus dem JAR nach dem Neustart erreichbar sind.)

Die Vorteile des externen Wrapper-Ansatzes sind:

  • Du brauchst nur ein JAR,
  • Sie können die gesamte Java-App ersetzen,
  • alle sekundären Threads, die von der App usw. erstellt wurden, gehen ohne spezielle Abschaltlogik verloren
  • Sie können auch mit der Wiederherstellung von Anwendungsabstürzen etc. umgehen.

Der zweite Ansatz erfordert zwei JARs, bietet jedoch folgende Vorteile:

  • Die Lösung ist Java und portabel,
  • die Umstellung wird schneller und
  • Sie können den Status während des Neustarts leichter beibehalten (Modulo-Leakage-Probleme).

Der “beste” Weg hängt von Ihren spezifischen Anforderungen ab.

Es sollte auch beachtet werden, dass:

  • Es gibt Sicherheitsrisiken bei der automatischen Aktualisierung. Wenn der Server, der die Aktualisierungen bereitstellt, kompromittiert ist oder wenn die Mechanismen zum Bereitstellen der Aktualisierungen anfällig für Angriffe sind, kann eine automatische Aktualisierung zu einer Kompromittierung der Clients führen.

  • Wenn Sie ein Update an einen Kunden senden, das dem Kunden schadet, können rechtliche Risiken und Risiken für den Ruf Ihres Unternehmens entstehen.


Wenn Sie einen Weg finden, das Rad nicht neu zu erfinden, wäre das gut. Siehe die anderen Antworten für Vorschläge.

Ich entwickle gerade einen JAVA Linux Daemon und musste einen automatischen Update-Mechanismus implementieren. Ich wollte meine Anwendung auf eine JAR-Datei beschränken und kam zu einer einfachen Lösung:

Packen Sie die Updater-Anwendung in das Update selbst.

Anwendung : Wenn die Anwendung eine neuere Version erkennt, geschieht Folgendes:

  1. Update herunterladen (Zipfile)
  2. Extract Application und ApplicationUpdater (alles in der Zip-Datei)
  3. Aktualisierer ausführen

ApplicationUpdater : Wenn der Updater ausgeführt wird, geschieht Folgendes:

  1. Stoppen Sie die Anwendung (in meinem Fall ein Daemon über init.d)
  2. Kopieren Sie die heruntergeladene JAR-Datei, um die aktuelle Anwendung zu überschreiben
  3. Starten Sie die Anwendung
  4. Aufräumen.

Hoffe es hilft jemandem.

Ich habe eine Java-Anwendung geschrieben, die Plugins zur Laufzeit laden kann und sie sofort verwendet, inspiriert von einem ähnlichen Mechanismus in jEdit. jEdit ist Open Source, also haben Sie die Möglichkeit zu sehen, wie es funktioniert.

Die Lösung verwendet einen benutzerdefinierten ClassLoader zum Laden von Dateien aus dem Jar. Sobald sie geladen sind, können Sie eine Methode aus dem neuen jar aufrufen, die als Hauptmethode dient. Dann ist der schwierige Teil, sicherzustellen, dass Sie alle Verweise auf den alten Code loswerden, so dass es Müll gesammelt werden kann. Ich bin nicht wirklich ein Experte in diesem Teil, ich habe es geschafft, aber es war nicht einfach.

Dies ist ein bekanntes Problem und ich empfehle, ein Rad nicht neu zu erfinden – schreibe nicht deinen eigenen Hack, sondern nutze nur, was andere Leute bereits getan haben.

Zwei Situationen, die Sie beachten müssen:

  1. Die App muss selbstaktualisierbar sein und auch während des Updates weiterlaufen (Server-App, eingebettete Apps). Gehen Sie mit OSGi: Bundles oder Equinox p2 .

  2. App ist eine Desktop-App und hat ein Installationsprogramm. Es gibt viele Installer mit Update-Option. Überprüfen Sie die Installationsliste .

  1. Erste Möglichkeit: Verwenden Sie Tomcat und seine Bereitstellungsfunktionen.
  2. Zweiter Weg: um die Anwendung auf zwei Teile zu teilen (funktional und update) und den Teileaustausch-functionsteil aktualisieren zu lassen.
  3. Dritter Weg: In Ihrer Server-Anwendung nur neue Version herunterladen, dann alte Version Releases gebundenen Port, dann alte Version führt neue Version (startet process), dann alte Version sendet eine Anfrage auf Anwendungsport auf die neue Version, um alte Version, alte Version zu löschen terminiert und neue Version löscht alte Version. So was: Alt-Text

Ich habe kürzlich update4j erstellt, das vollständig mit dem Modulsystem von Java 9 kompatibel ist.

Es wird nahtlos die neue Version ohne Neustart starten.

Dies ist nicht unbedingt der beste Weg, aber es könnte für Sie arbeiten.

Sie können eine Bootstrap-Anwendung schreiben (ala der World of Warcraft Launcher, wenn Sie WoW gespielt haben). Dieser Bootstrap ist dafür verantwortlich, nach Updates zu suchen.

  • Wenn ein Update verfügbar ist, wird es dem Benutzer angeboten, den Download, die Installation usw. übernehmen.
  • Wenn die Anwendung auf dem neuesten Stand ist, kann der Benutzer die Anwendung starten
  • Optional können Sie dem Benutzer erlauben, die Anwendung zu starten, auch wenn sie nicht aktuell ist

Auf diese Weise müssen Sie sich keine Sorgen darüber machen, dass Sie Ihre Anwendung beenden müssen.

Wenn Ihre Anwendung webbasiert ist und es wichtig ist, dass sie über einen aktuellen Client verfügt, können Sie auch Versionsüberprüfungen durchführen, während die Anwendung ausgeführt wird. Sie können dies in Intervallen tun, während Sie normale Kommunikation mit dem Server (einige oder alle Anrufe) oder beides durchführen.

Für ein Produkt, an dem ich kürzlich gearbeitet habe, haben wir Versionsüberprüfungen beim Start (ohne eine Bootstrapper-App, aber bevor das Hauptfenster erschien) und während der Aufrufe des Servers durchgeführt. Wenn der Client veraltet war, mussten wir den Benutzer manuell beenden, verbieten jedoch jegliche Maßnahmen gegen den Server.

Bitte beachten Sie, dass ich nicht weiß, ob Java den Benutzeroberflächencode aufrufen kann, bevor Sie Ihr Hauptfenster aufrufen. Wir benutzten C # / WPF.

Wenn Sie Ihre Anwendung mit Equinox- Plug-Ins erstellen, können Sie das P2-Bereitstellungssystem verwenden , um eine fertige Lösung für dieses Problem zu erhalten. Dies erfordert, dass der Server nach einem Update neu gestartet wird.

Ich sehe ein Sicherheitsproblem beim Herunterladen eines neuen Krams (usw.), z. B. ein Mann im mittleren Angriff. Sie müssen Ihr herunterladbares Update immer unterschreiben.

Auf JAX2015 erzählte Adam Bien von der Verwendung von JGit zur Aktualisierung der Binärdateien. Leider konnte ich keine Tutorials finden.

Quelle auf Deutsch.

Adam Bien hat den Updater hier erstellt

Ich habe es hier mit einem javaFX-Frontend gegabelt. Ich arbeite auch an einer automatischen Unterzeichnung.