Ich möchte eine Java-Anwendung (Serveranwendung) implementieren, die eine neue Version (.jar-Datei) von einer bestimmten URL herunterladen und sich dann zur Laufzeit selbst aktualisieren kann.
Was ist der beste Weg dies zu tun und ist es möglich?
Ich denke, 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?
Antworten:
Die Grundstruktur 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 eine neue Version erkannt wird, kehrt sie zum Launcher zurück.
Es gibt verschiedene Möglichkeiten, dies zu implementieren. Beispielsweise:
Der Launcher kann ein Wrapper-Skript oder eine Binäranwendung sein, die eine neue JVM startet, um die Anwendung aus einer JAR-Datei auszuführen, die ersetzt wird.
Der Launcher kann eine Java-Anwendung sein, die einen Klassenladeprogramm für die neue JAR erstellt, eine Einstiegspunktklasse lädt und eine Methode dafür aufruft. Wenn Sie dies auf diese Weise tun, müssen Sie auf Speicherlecks im Classloader achten, aber das ist nicht schwierig. (Sie müssen nur sicherstellen, dass nach dem Neustart keine Objekte mit aus der JAR geladenen Klassen erreichbar sind.)
Die Vorteile des externen Wrapper-Ansatzes sind:
Der zweite Ansatz erfordert zwei JARs, hat jedoch die folgenden Vorteile:
Der "beste" Weg hängt von Ihren spezifischen Anforderungen ab.
Es sollte auch beachtet werden, dass:
Bei der automatischen Aktualisierung bestehen Sicherheitsrisiken. Wenn der Server, der die Updates bereitstellt, gefährdet ist oder wenn die Mechanismen zum Bereitstellen der Updates anfällig für Angriffe sind, kann die automatische Aktualisierung im Allgemeinen zu einer Gefährdung der Clients führen.
Das Weiterleiten eines Updates an einen Kunden, das dem Kunden Schaden zufügt, kann rechtliche Risiken und Risiken für den Ruf Ihres Unternehmens mit sich bringen.
Wenn Sie einen Weg finden, das Rad nicht neu zu erfinden, wäre das gut. In den anderen Antworten finden Sie Vorschläge.
quelle
Ich entwickle derzeit einen JAVA Linux Daemon und musste auch einen Mechanismus zur automatischen Aktualisierung implementieren. Ich wollte meine Anwendung auf eine JAR-Datei beschränken und fand eine einfache Lösung:
Packen Sie die Updater-Anwendung in das Update selbst.
Anwendung : Wenn die Anwendung eine neuere Version erkennt, führt sie Folgendes aus:
ApplicationUpdater : Wenn der Updater ausgeführt wird, führt er Folgendes aus:
Hoffe es hilft jemandem.
quelle
Dies ist ein bekanntes Problem, und ich empfehle, ein Rad nicht neu zu erfinden. Schreiben Sie keinen eigenen Hack, sondern verwenden Sie nur das, was andere bereits getan haben.
Zwei Situationen, die Sie berücksichtigen müssen:
Die App muss selbst aktualisierbar sein und auch während des Updates ausgeführt werden (Server-App, eingebettete Apps). Gehen Sie mit OSGi: Bundles oder Equinox p2 .
App ist eine Desktop-App und hat ein Installationsprogramm. Es gibt viele Installationsprogramme mit Update-Option. Überprüfen Sie die Installationsliste .
quelle
Ich habe kürzlich update4j erstellt, das vollständig mit dem Modulsystem von Java 9 kompatibel ist.
Die neue Version wird nahtlos ohne Neustart gestartet.
quelle
Ich habe eine Java-Anwendung geschrieben, die Plugins zur Laufzeit laden und sofort verwenden kann, inspiriert von einem ähnlichen Mechanismus in jEdit. jEdit ist Open Source, sodass Sie die Möglichkeit haben, zu sehen, wie es funktioniert.
Die Lösung verwendet einen benutzerdefinierten ClassLoader, um Dateien aus dem JAR zu laden. Sobald sie geladen sind, können Sie eine Methode aus dem neuen Jar aufrufen, die als
main
Methode fungiert. Dann besteht der schwierige Teil darin, sicherzustellen, dass Sie alle Verweise auf den alten Code entfernen, damit dieser durch Müll gesammelt werden kann. Ich bin kein Experte in diesem Bereich, ich habe es geschafft, aber es war nicht einfach.quelle
NetworkClassLoader
auf dem JavaDoc für ClassLoaderquelle
Dies ist nicht unbedingt der beste Weg, aber es könnte für Sie funktionieren.
Sie können eine Bootstrap-Anwendung schreiben (ua der World of Warcraft-Launcher, wenn Sie WoW gespielt haben). Dieser Bootstrap ist für die Suche nach Updates verantwortlich.
Auf diese Weise müssen Sie sich keine Sorgen machen, dass Ihre Anwendung beendet werden muss.
Wenn Ihre Anwendung webbasiert ist und es wichtig ist, dass sie über einen aktuellen Client verfügt, können Sie auch Versionsprüfungen durchführen, während die Anwendung ausgeführt wird. Sie können sie in Intervallen ausführen, während Sie eine normale Kommunikation mit dem Server durchführen (einige oder alle Anrufe) oder beides.
Für ein Produkt, an dem ich kürzlich gearbeitet habe, haben wir beim Start (ohne Bootstrapper-App, aber bevor das Hauptfenster angezeigt wurde) und bei Aufrufen des Servers Versionsprüfungen durchgeführt. Wenn der Client veraltet war, haben wir uns darauf verlassen, dass der Benutzer manuell beendet, aber keine Aktionen gegen den Server ausgeführt.
Bitte beachten Sie, dass ich nicht weiß, ob Java UI-Code aufrufen kann, bevor Sie Ihr Hauptfenster aufrufen. Wir haben C # / WPF verwendet.
quelle
Wenn Sie Ihre Anwendung mit Equinox- Plugins erstellen, können Sie das P2-Bereitstellungssystem verwenden , um eine vorgefertigte Lösung für dieses Problem zu erhalten. Dazu muss sich der Server nach einem Update neu starten.
quelle
Ich sehe ein Sicherheitsproblem beim Herunterladen eines neuen Glases (usw.), z. B. eines Mannes im mittleren Angriff. Sie müssen Ihr herunterladbares Update immer unterschreiben.
Auf JAX2015 erzählte Adam Bien von der Verwendung von JGit zum Aktualisieren der Binärdateien. Leider konnte ich keine Tutorials finden.
Quelle in deutscher Sprache.
Adam Bien hat den Updater erstellt, siehe hier
Ich habe es hier mit einem JavaFX-Frontend gegabelt . Ich arbeite auch an einer automatischen Signatur.
quelle