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 procéder 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 démarrée puis quitter. Ou y a-t-il une meilleure façon de faire cela?
Réponses:
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 son travail, mais vérifie périodiquement l'URL de téléchargement. S'il détecte une nouvelle version, il revient au lanceur.
Vous pouvez mettre cela en œuvre de plusieurs manières. Par exemple:
Le lanceur peut être un script wrapper ou une application binaire qui démarre une nouvelle JVM pour exécuter l'application à partir d'un fichier JAR qui est remplacé.
Le lanceur peut être une application Java qui crée un chargeur de classe pour le nouveau JAR, charge une classe de point d'entrée et appelle une méthode dessus. Si vous procédez de cette façon, 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 avec des classes chargées à partir du JAR n'est accessible après le redémarrage.)
Les avantages de l'approche du wrapper externe sont:
La seconde approche nécessite deux JAR, mais présente les avantages suivants:
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 conduire à une compromission du ou des clients.
Envoyer une mise à jour à un client qui cause des dommages au client peut comporter 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.
la source
Je développe actuellement un démon Linux JAVA et j'ai également eu besoin de mettre en œuvre 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 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.
la source
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 les autres ont déjà fait.
Deux situations à considérer:
L'application doit être auto-actualisable et continuer à fonctionner même pendant la mise à jour (application serveur, applications intégrées). Optez pour OSGi: Bundles ou Equinox p2 .
L'application 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 .
la source
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.
la source
J'ai écrit une application Java qui peut charger des plugins lors de l'exécution et commencer à les utiliser immédiatement, inspirée d'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 jar qui agira comme sa
main
méthode. Ensuite, la partie la plus délicate est de vous assurer de vous débarrasser de toutes les références à l'ancien code afin 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.la source
NetworkClassLoader
sur le JavaDoc pour ClassLoaderla source
Ce n'est pas nécessairement la meilleure façon, mais cela pourrait fonctionner pour vous.
Vous pouvez écrire une application de bootstrap (ala le lanceur World of Warcraft, si vous avez 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 faire à intervalles, 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 effectué des vérifications de version au lancement (sans application de boot strapper, mais avant l'apparition de la fenêtre principale), et lors des appels au serveur. Lorsque le client était obsolète, nous comptions sur l'utilisateur pour quitter manuellement, mais nous 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 utilisions C # / WPF.
la source
Si vous créez votre application à l'aide des plug-ins Equinox , vous pouvez utiliser le système de provisionnement P2 pour obtenir une solution toute faite à ce problème. Cela obligera le serveur à redémarrer lui-même après une mise à jour.
la source
Je vois un problème de sécurité lors du téléchargement d'un nouveau fichier jar (etc.), par exemple, un homme au milieu attaque. 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 n'ai trouvé aucun tutoriel.
Source en allemand.
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.
la source