Comment puis-je écrire une application Java qui peut se mettre à jour au moment de l'exécution?


Je voudrais implémenter une application java (application serveur) qui peut télécharger une nouvelle version (.fichier jar) à partir d'une URL donnée, puis se mettre à jour au moment de l'exécution.

Quelle est la meilleure façon de le faire et est-il possible?

Je suppose que l'application peut télécharger un nouveau .fichier jar et le démarrer. Mais comment dois-je faire le transfert, par exemple savoir quand la nouvelle application est démarrée, puis quitter. Ou est-il une meilleure façon de le faire?

Author: Jonas, 2010-10-23

9 answers

La structure de base d'une solution est la suivante:

  • Il existe une boucle principale chargée de charger à plusieurs reprises la dernière version de l'application (si nécessaire) et de la lancer.

  • L'application fait sa chose, mais vérifie périodiquement l'URL de téléchargement. S'il détecte une nouvelle version, il retourne au lanceur.

Vous pouvez implémenter cela de plusieurs façons. Par exemple:

  • Le lanceur pourrait être un wrapper script ou application binaire qui démarre une nouvelle JVM pour exécuter l'application à partir d'un fichier JAR qui est remplacé.

  • Le lanceur pourrait être une application Java qui crée un classloader pour le nouveau JAR, charge une classe entrypoint et appelle une méthode dessus. Si vous le faites de cette façon, vous devez surveiller les fuites de stockage de classloader, mais ce n'est pas difficile. (Vous devez juste vous assurer qu'aucun objet avec des classes chargées à partir du POT n'est accessible après vous relancer.)

Les avantages de l'approche wrapper externe sont:

  • vous n'avez besoin que d'un POT,
  • vous pouvez remplacer l'application Java entière,
  • tous les threads secondaires créés par l'application, etc. disparaîtront sans logique d'arrêt spéciale, et
  • vous pouvez également gérer la récupération à partir de plantages d'applications, etc.

La deuxième approche nécessite deux pots, mais présente les avantages suivants:

  • la solution est Java pur et portable,
  • , le passage sera plus rapide, et
  • vous pouvez plus facilement conserver l'état pendant le redémarrage (problèmes de fuite modulo).

La "meilleure" façon dépend de vos besoins spécifiques.

, Il convient également de noter que:

  • La mise à jour automatique comporte des risques de sécurité. En général, si le serveur qui fournit les mises à jour est compromis ou si les mécanismes de fourniture des mises à jour sont susceptibles d'être attaqués, la mise à jour automatique peut entraîner une le compromis de la client(s).

  • Pousser une mise à jour à un client qui cause des dommages au client pourrait avoir des risques juridiques et des risques pour la réputation de votre entreprise.


Si vous pouvez trouver un moyen d'éviter de réinventer la roue, ce serait bien. Voir les autres réponses pour des suggestions.

 49
Author: Stephen C, 2017-01-16 03:05:22

Je développe actuellement un démon JAVA Linux et j'ai également eu besoin d'implémenter un mécanisme de mise à jour automatique. Je voulais limiter mon application à un fichier jar et j'ai trouvé une solution simple:

Emballez l'application updater dans la mise à jour elle-même.

Application : Lorsque l'application détecte une version plus récente, elle effectue les opérations suivantes:

  1. Télécharger la mise à jour (Fichier zip)
  2. Extraire l'application et ApplicationUpdater (tous dans le zipfile)
  3. Exécuter le programme de mise à jour

ApplicationUpdater : Lorsque le programme de mise à jour s'exécute, il effectue ce qui suit:

  1. Arrêtez l'application (dans mon cas, un démon via init.d)
  2. Copiez le fichier jar téléchargé pour remplacer l'application actuelle
  3. Lancer l'application
  4. Nettoyage.

J'espère que ça aide quelqu'un.

 30
Author: Berdus, 2012-11-12 10:51:56

J'ai écrit une application Java qui peut charger des plugins à l'exécution et commencer à les utiliser immédiatement, inspirée par un mécanisme similaire dans jEdit. jEdit est open source, vous avez donc la possibilité de voir comment cela fonctionne.

La solution utilise un ClassLoader personnalisé pour charger des fichiers à partir du fichier jar. Une fois qu'ils sont chargés, vous pouvez invoquer une méthode à partir du nouveau jar qui agira comme sa méthode main. Ensuite, la partie délicate est de vous assurer de vous débarrasser de toutes les références à l'ancien code afin qu'il peut être nettoyée. Je ne suis pas tout à fait un expert sur cette partie, je l'ai fait fonctionner mais ce n'était pas facile.

 10
Author: Brad Mace, 2016-04-11 08:39:45

C'est un problème connu et je recommande de ne pas réinventer une roue - n'écrivez pas votre propre hack, utilisez simplement ce que d'autres personnes ont déjà fait.

Deux situations que vous devez considérer:

  1. L'application doit être auto-mise à jour et continuer à fonctionner même pendant la mise à jour (application serveur, applications intégrées). Aller avec OSGi: Bundles ou Équinoxe p2.

  2. App est une application de bureau et a un installateur. Il existe de nombreux installateurs avec option de mise à jour. Vérifier liste des installateurs .

 7
Author: Peter Knego, 2010-10-26 07:53:49
  1. Première façon: utilisez tomcat et ses installations de déploiement.
  2. Deuxième façon: diviser l'application en deux parties (fonctionnelle et mise à jour) et laisser la partie mise à jour remplacer la partie fonction.
  3. Troisième voie: Dans votre application serveur, téléchargez simplement la nouvelle version, puis l'ancienne version libère le port lié, puis l'ancienne version exécute la nouvelle version( démarre le processus), puis l'ancienne version envoie une demande sur le port de l'application à la nouvelle version pour supprimer l'ancienne version, l'ancienne version se termine et la nouvelle version supprime version. Pareil: le texte d'alt
 5
Author: ycnix, 2010-10-26 07:29:26

J'ai récemment créé update4j qui est entièrement compatible avec le système de modules de Java 9.

Il démarrera de manière transparente la nouvelle version sans redémarrage.

 3
Author: Mordechai, 2018-03-15 17:20:24

Ce n'est pas nécessairement la meilleure façon , mais cela pourrait fonctionner pour vous.

Vous pouvez écrire une application bootstrap (ala le lanceur World of Warcraft, si vous avez joué à WoW). Ce bootstrap est responsable de la vérification des mises à jour.

  • Si une mise à jour est disponible, il la proposera à l'utilisateur, gérera le téléchargement, l'installation, etc.
  • Si l'application est à jour, il permet à l'utilisateur de lancer l'application
  • En option, vous pouvez autoriser l'utilisateur pour lancer l'application, même si elle n'est pas à jour

De cette façon, vous n'avez pas à vous soucier de forcer une sortie de votre application.

Si votre application est basée sur le Web et s'il est important qu'elle dispose d'un client à jour, vous pouvez également effectuer des vérifications de version pendant l'exécution de l'application. Vous pouvez les faire à intervalles réguliers, tout en effectuant une communication normale avec le serveur (certains ou tous les appels), ou les deux.

Pour un produit sur lequel j'ai récemment travaillé, nous avons fait la version vérifie au lancement (sans application boot strapper, mais avant l'apparition de la fenêtre principale) et pendant les appels au serveur. Lorsque le client était obsolète, nous nous appuyions sur l'utilisateur pour quitter manuellement, mais interdisons toute action contre le serveur.

Veuillez noter que je ne sais pas si Java peut invoquer le code de l'interface utilisateur avant d'afficher votre fenêtre principale. Nous avons été à l'aide de C#/WPF.

 2
Author: Merlyn Morgan-Graham, 2010-10-23 04:29:35

Si vous construisez votre application à l'aide de Équinoxe plugins, vous pouvez utiliser le P2 Système de Provisioning pour obtenir une solution à ce problème. Cela nécessitera le serveur redémarrer après une mise à jour.

 2
Author: Tom Crockett, 2010-10-26 18:40:17

Je vois un problème de sécurité lors du téléchargement d'un nouveau pot (etc.), par exemple, un homme dans l'attaque du milieu. Vous devez toujours signer votre mise à jour téléchargeable.

Sur JAX2015, Adam Bien a parlé de l'utilisation de JGit pour mettre à jour les binaires. Malheureusement, je ne pouvais pas trouver de tutoriels.

Source en allemand.

Adam Bien a créé le programme de mise à jour voir ici

Je l'ai fourché ici avec un frontend JavaFX. Je travaille également sur une signature automatique.

 0
Author: Kaito, 2016-04-13 12:59:14