Je souhaite implémenter une application Java (application serveur) pouvant télécharger une nouvelle version (fichier .jar) à partir d'une URL donnée, puis se mettre à jour au moment de l'exécution.
Quel est le meilleur moyen 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 faire le transfert, par exemple savoir quand la nouvelle application est lancée puis quitter. Ou y a-t-il une meilleure façon de faire cela?
La structure de base d'une solution est la suivante:
Il existe une boucle principale chargée de charger de manière répétée 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.
Vous pouvez mettre cela en œuvre de différentes manières. Par exemple:
Le programme de lancement peut être un script wrapper ou une application binaire qui démarre une nouvelle machine virtuelle Java pour exécuter l'application à partir d'un fichier JAR remplacé.
Le programme de lancement 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 procédez ainsi, vous devez surveiller les fuites de stockage du chargeur de classe, mais ce n'est pas difficile. (Vous devez simplement vous assurer qu'aucun objet contenant des classes chargées à partir du fichier JAR n'est accessible après le redémarrage.)
Les avantages de l’approche externe sont les suivants:
La deuxième approche nécessite deux fichiers JAR, mais présente les avantages suivants:
Le "meilleur" moyen dépend de vos besoins spécifiques.
Il convient également de noter que:
Il y a des risques de sécurité avec la mise à jour automatique. En général, si le serveur qui fournit les mises à jour est compromis ou si les mécanismes permettant de fournir les mises à jour sont susceptibles d'attaques, la mise à jour automatique peut alors compromettre le ou les clients.
Transmettre à un client une mise à jour causant un préjudice à celui-ci peut comporter des risques juridiques, ainsi que des atteintes à 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.
Je développe actuellement un démon Java Linux et je devais également mettre en place un mécanisme de mise à jour automatique. Je voulais limiter mon application à un fichier jar et j'ai proposé une solution simple:
Pack 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:
ApplicationUpdater : Lorsque le programme de mise à jour s'exécute, il effectue les opérations suivantes:
J'espère que ça aide quelqu'un.
J'ai écrit une application Java qui peut charger des plugins au moment de 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 appeler une méthode du nouveau fichier jar qui agira comme sa méthode main
. Ensuite, la partie délicate consiste à vous débarrasser de toutes les références à l’ancien code afin qu’il puisse être nettoyé. Je ne suis pas tout à fait un expert sur ce point, j'ai fait en sorte que cela fonctionne, mais ce n'était pas facile.
C'est un problème connu et je recommande de ne pas 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:
L'application doit pouvoir être mise à jour automatiquement et continuer à fonctionner même pendant la mise à jour (application serveur, applications intégrées). Allez avec OSGi: Bundles ou Equinox p2 .
App est une application de bureau et dispose d'un programme d'installation. Il existe de nombreux installateurs avec option de mise à jour. Vérifiez la liste des installateurs .
J'ai récemment créé update4j , qui est entièrement compatible avec le système de modules de Java 9.
La nouvelle version démarrera de manière transparente sans redémarrage.
Ce n'est pas forcément le chemin meilleur, mais cela pourrait fonctionner pour vous.
Vous pouvez écrire une application bootstrap (comme le lanceur World of Warcraft, si vous avez déjà joué à WoW). Ce bootstrap est responsable de la vérification des mises à jour.
De cette façon, vous n'avez pas à vous soucier de forcer la 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 établissant une communication normale avec le serveur (tout ou partie des appels), ou les deux.
Pour un produit sur lequel j'ai récemment travaillé, nous avons effectué des vérifications de version au lancement (sans application de démarrage, mais avant l'apparition de la fenêtre principale), ainsi que lors d'appels au serveur. Lorsque le client était obsolète, nous nous sommes appuyés sur l'utilisateur pour quitter manuellement, mais interdisons toute action contre le serveur.
Veuillez noter que je ne sais pas si Java peut appeler le code de l'interface utilisateur avant d'afficher votre fenêtre principale. Nous utilisions C #/WPF.
Je vois un problème de sécurité lors du téléchargement d’un nouveau bocal (etc.), par exemple un homme au milieu d’une attaque. Vous devez toujours signer votre mise à jour téléchargeable.
Sur JAX2015, Adam Bien a expliqué comment utiliser JGit pour mettre à jour les fichiers binaires . Malheureusement, je n’ai trouvé aucun tutoriel.
Adam Bien a créé le programme de mise à jour voir ici
Je l'ai bifurqué ici avec une interface javaFX. Je travaille également sur une signature automatique.