Comment puis-je écrire une application Java capable de 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-ce possible?

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

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

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

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

Il y a plusieurs façons de mettre en œuvre cela. Par exemple:

  • Le lanceur peut être un script wrapper ou une application binary qui démarre une nouvelle JVM pour exécuter l’application à partir d’un fichier JAR remplacé.

  • Le lanceur peut être une application Java qui crée un chargeur de classes pour le nouveau JAR, charge une classe de point d’entrée et appelle une méthode dessus. Si vous le faites de cette façon, vous devez surveiller les fuites de stockage du chargeur de classe, mais ce n’est pas difficile. (Vous devez juste vous assurer qu’aucun object avec des classes chargées depuis le JAR ne soit accessible après le redémarrage.)

Les avantages de l’approche enveloppante externe sont les suivants:

  • vous n’avez besoin que d’un seul JAR,
  • 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 faire face à la récupération suite à des plantages d’applications, etc.

La seconde approche nécessite deux JAR, mais présente les avantages suivants:

  • la solution est pure Java et portable,
  • le changement sera plus rapide et
  • vous pouvez plus facilement conserver l’état sur le redémarrage (problèmes de fuite modulo).

Le «meilleur» moyen 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 compromettre le ou les clients.

  • Pousser une mise à jour vers un client qui cause des dommages au client peut entraîner des risques juridiques et des risques pour la réputation de votre entreprise.


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

Je suis en train de développer un démon Linux JAVA et j’ai également eu besoin de mettre en place un mécanisme de mise à jour automatique. Je voulais limiter mon application à un fichier jar et proposer une solution simple:

Emballez l’application de mise à jour 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 fichier zip)
  3. Run updater

ApplicationUpdater : Lorsque le programme de mise à jour s’exécute, il effectue les opérations suivantes:

  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. Démarrer l’application
  4. Nettoyer.

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

J’ai écrit une application Java capable de charger des plugins à l’exécution et de commencer à les utiliser immédiatement, inspirée par un mécanisme similaire à 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’elles sont chargées, vous pouvez appeler une méthode du nouveau fichier jar qui agira comme méthode main . Ensuite, la partie la plus délicate est de vous assurer que vous vous débarrassez de toutes les références à l’ancien code pour qu’il puisse être récupéré. Je ne suis pas tout à fait un expert dans ce domaine, je l’ai fait fonctionner mais ce n’était pas facile.

C’est un problème connu et je vous déconseille de réinventer une roue – n’écrivez pas votre propre piratage, utilisez simplement ce que d’autres personnes ont déjà fait.

Deux situations à prendre en compte:

  1. L’application doit pouvoir être mise à jour automatiquement et fonctionner même pendant la mise à jour (application serveur, applications intégrées). Aller avec OSGi: Bundles ou Equinox p2 .

  2. App est une application de bureau et dispose d’un installateur. Il existe de nombreux installateurs avec option de mise à jour. Vérifiez la liste des installateurs .

  1. Premier moyen: utiliser tomcat et ses installations de déploiement.
  2. Deuxième manière: diviser l’application en deux parties (fonctionnelle et mise à jour) et laisser la partie mise à jour remplacer la partie fonction.
  3. Troisième façon: dans votre application de 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 d’application pour supprimer l’ancienne version se termine et nouvelle version supprime l’ancienne version. Comme ça: texte alt

J’ai récemment créé update4j, 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.

Ce n’est pas nécessairement le meilleur moyen, mais cela pourrait fonctionner pour vous.

Vous pouvez écrire une application bootstrap (comme le lanceur World of Warcraft, si vous avez joué à WoW). Ce bootstrap est chargé de vérifier les mises à jour.

  • Si une mise à jour est disponible, elle l’offrira à l’utilisateur, gérera le téléchargement, l’installation, etc.
  • Si l’application est à jour, cela permettra à l’utilisateur de lancer l’application
  • En option, vous pouvez autoriser l’utilisateur à 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 effectuer à 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 travaillé récemment, nous avons effectué des vérifications de version au lancement (sans application de démarrage de boot mais avant que la fenêtre principale n’apparaisse), et lors d’appels au serveur. Lorsque le client était obsolète, nous comptions sur l’utilisateur pour quitter manuellement, mais interdire toute action contre le serveur.

Veuillez noter que je ne sais pas si Java peut invoquer le code de l’interface utilisateur avant de faire apparaître votre fenêtre principale. Nous utilisions C # / WPF.

Si vous créez votre application à l’aide des plug-ins Equinox , vous pouvez utiliser le P2 Provisioning System pour obtenir une solution prête à l’emploi pour résoudre ce problème. Cela nécessitera que le serveur redémarre après une mise à jour.

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

Sur JAX2015, Adam Bien a parlé de l’utilisation de JGit pour la mise à jour des fichiers binarys. Malheureusement, je n’ai pas trouvé de tutoriels.

Source en allemand.

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

Je l’ai fourché ici avec un frontal javaFX. Je travaille également sur une signature automatique.