Ceci est une page de présentation, veuillez visiter hotswapagent.org pour plus d'informations.
Redéfinition des classes d'exécution et des ressources illimitées Java.
L'objectif principal de ce projet était d'éliminer le besoin du cycle de développement traditionnel « modifier le code -> redémarrer et attendre... -> vérifier ». Au fil du temps, ce concept a évolué vers un nouveau paradigme au sein de l'écosystème Java, permettant le développement de logiciels en temps réel au sein d'une application en cours d'exécution. Cette approche est même réalisable dans des environnements restreints, tels que les conteneurs Docker.
Si vous êtes un utilisateur IntelliJ, vous pouvez simplifier la configuration de HA et DCEVM en utilisant le plugin IntelliJ HotSwapHelper.
Téléchargez et installez :
Pour Java 17/21 : téléchargez la dernière version de JBR17 ou JBR21. Étant donné que ces versions n'incluent pas d'agent Hotswap intégré, vous devrez copier manuellement hotswap-agent.jar
dans le dossier lib/hotswap
. Vous pouvez trouver le dernier agent Hotswap ici. Assurez-vous que le fichier dans le dossier lib/hotswap
est nommé hotswap-agent.jar
sans aucun numéro de version dans le nom de fichier.
Pour Java 11 : utilisez TravaJDK, qui intègre un HotswapAgent, et installez-le comme JDK alternatif. Alternativement, TravaJDK inclut un HotswapAgent intégré.
Pour Java 8 : utilisez jdk8-dcevm avec HotswapAgent.
Modes HotswapAgent :
À partir de dcevm-11.0.9
, le HotswapAgent est désactivé par défaut. Vous pouvez activer la prise en charge de HotswapAgent à l'aide des options JVM dans l'un des trois modes suivants :
Le mode HotswapAgent=core
fonctionne sans plugins supplémentaires, à l'exception des plugins JVM principaux, ce qui entraîne des performances plus rapides grâce à la réduction des tâches d'analyse et de copie de classes. Pour utiliser des plugins supplémentaires, vous devez les configurer en tant que dépendances Maven dans votre fichier pom.xml
. En revanche, le mode HotswapAgent=fatjar
inclut tous les plugins par défaut, ce qui peut légèrement ralentir le démarrage des applications.
-XX:HotswapAgent=fatjar
active le fatjar HotswapAgent interne.
-XX:HotswapAgent=core
active le HotswapAgent interne du noyau.
-XX:HotswapAgent=external
configure la prise en charge JVM pour HotswapAgent et permet à l'utilisateur de fournir un hotswap-agent.jar
externe à l'aide de l'option -javaagent:
.
3.Lancement :
Java17/21 : lancez votre application avec les options -XX:+AllowEnhancedClassRedefinition -XX:HotswapAgent=fatjar
pour activer le hotswap avancé (dcevm) et utiliser la version fatjar de Hotswap Agent. Comme alternative, des modes core
ou external
peuvent être utilisés à la place de fatjar
.
Java11 : lancez votre application avec les options -XX:HotswapAgent=fatjar
pour utiliser la version fatjar de Hotswap Agent.
Java8 : lancez votre application avec les options -XXaltjvm=dcevm -javaagent:hotswap-agent.jar
pour obtenir une configuration de base. Vous pouvez éventuellement ajouter hotswap-agent.properties
à votre application pour configurer les plugins et le comportement de l'agent.
3.Exécutez votre application :
Démarrez l'application en mode débogage, vérifiez que l'agent et les plugins sont correctement initialisés :
HOTSWAP AGENT: 9:49:29.548 INFO (org.hotswap.agent.HotswapAgent) - Loading Hotswap agent - unlimited runtime class redefinition. HOTSWAP AGENT: 9:49:29.725 INFO (org.hotswap.agent.config.PluginRegistry) - Discovered plugins: [org.hotswap.agent.plugin.hotswapper.HotswapperPlugin, org.hotswap.agent.plugin.jvm.AnonymousClassPatchPlugin, org.hotswap.agent.plugin.hibernate.HibernatePlugin, org.hotswap.agent.plugin.spring.SpringPlugin, org.hotswap.agent.plugin.jetty.JettyPlugin, org.hotswap.agent.plugin.tomcat.TomcatPlugin, org.hotswap.agent.plugin.zk.ZkPlugin, org.hotswap.agent.plugin.logback.LogbackPlugin] ... HOTSWAP AGENT: 9:49:38.700 INFO (org.hotswap.agent.plugin.spring.SpringPlugin) - Spring plugin initialized - Spring core version '3.2.3.RELEASE'
4.Vérifiez la redéfinition
Enregistrez une ressource modifiée et/ou utilisez la fonctionnalité HotSwap de votre IDE pour recharger les modifications
Chaque framework d'application (Spring, Hibernate, Logback, ...) nécessite un mécanisme de rechargement spécial pour rester à jour après la redéfinition de la classe (par exemple, rechargement de la configuration Hibernate après l'introduction d'une nouvelle classe d'entité). L'agent Hotswap fonctionne comme un système de plugins et est livré préconfiguré avec tous les principaux plugins du framework. Il est facile d’écrire votre plugin personnalisé même dans le cadre de votre application.
Ce projet est très complexe en raison du grand nombre de frameworks pris en charge et des différentes versions. La contribution communautaire est obligatoire pour le maintenir en vie. Vous pouvez commencer par créer un plugin dans votre application ou en écrivant un exemple/test d'intégration. Il y a toujours un besoin d'amélioration de la documentation :-). Merci pour toute aide !
Java Hotswap amélioré - modifier le corps de la méthode, ajouter/renommer une méthode, un champ, ... La seule opération non prise en charge consiste à modifier la superclasse.
Vous pouvez utiliser Java Hotswap standard de l'IDE en mode débogage pour recharger la classe modifiée
ou définissez la propriété autoHotswap -XXaltjvm=dcevm -javaagent:PATH_TO_AGENThotswap-agent.jar=autoHotswap=true
pour recharger les classes modifiées après la compilation. Cette configuration permet même de recharger sur un système de production sans redémarrage.
Configuration automatique - toutes les classes et ressources locales, connues de l'application Java en cours d'exécution, sont automatiquement découvertes et surveillées pour le rechargement (tous les fichiers du système de fichiers local, pas dans un fichier JAR).
Chemin de classe supplémentaire – Besoin de modifier une classe d'exécution dans un JAR dépendant ? Utilisez la propriété extraClasspath pour ajouter n’importe quel répertoire en tant que chemin de classe afin de surveiller les fichiers de classe.
Recharger la ressource après une modification - les ressources du répertoire webapp sont généralement rechargées par le serveur d'applications. Mais qu'en est-il des autres ressources comme src/main/resources ? Utilisez la propriété watchResources pour ajouter n’importe quel répertoire afin de surveiller un changement de ressource.
Prise en charge du framework - via le système de plugins, de nombreux frameworks sont pris en charge. De nouveaux plugins peuvent être facilement ajoutés.
Rapide : jusqu'à ce que le plugin soit initialisé, il ne consomme aucune ressource et ne ralentit pas l'application (voir la surcharge d'exécution pour plus d'informations)
Si vous avez des problèmes ou des questions, posez-les sur le forum HotswapAgent.
Ce projet est similaire à JRebel. Les principales différences sont :
HotswapAgent (DCEVM) prend en charge Java8, Java11 et Java17 !
HotswapAgent ne nécessite aucune configuration supplémentaire pour la configuration de base du projet.
JRebel est actuellement plus mature et contient plus de plugins.
JRebel n'est ni open source ni gratuit.
JRebel modifie le bytecode de toutes les classes lors du rechargement. Vous avez besoin d'un plugin IDE spécial pour corriger le débogage.
HotswapAgent extraClasspath est similaire à la configuration de JRebel
HotswapAgent ajoute la configuration watchResources
Voir le projet GitHub HotswapAgentExamples. Le but d’un exemple d’application est :
tests d'intégration complexes et automatisés (vérifier les différentes configurations avant une sortie, voir le script run-tests.sh
)
pour vérifier l'utilisation du plugin "dans le monde réel" pendant le développement du plugin (c'est-à-dire à l'intérieur d'un conteneur)
pour fournir une solution de travail pour les configurations d'applications typiques
sandbox pour simuler les problèmes des configurations existantes ou nouvelles
N'hésitez pas à créer une bifurcation/branchement et à créer une application pour votre configuration (fonctionnelle, mais aussi simple que possible). Les configurations générales seront fusionnées dans le maître.
Aucun besoin :) Vraiment ! Toutes les modifications sont transparentes et tout ce que vous avez à faire est de télécharger le patch+agent et de configurer votre application/serveur d'applications. Parce que nous utilisons le comportement Java hotswap standard, votre IDE fonctionnera comme prévu. Cependant, nous travaillons sur des plugins IDE pour faciliter le téléchargement et la configuration.
Certains plugins sont déjà disponibles :
Ajoutez deux actions à côté du bouton "Debug" dans intellij, Exécuter avec hotswap, Déboguer avec hotswap.
Lorsque vous cliquez sur l'action, les paramètres vm seront définis pour vous, pas besoin de définir les paramètres vm manuellement.
Code source et documentation : https://github.com/gejun123456/HotSwapHelper.
La configuration de base est définie pour recharger les classes et les ressources à partir du chemin de classe connu de l'application en cours d'exécution (classloader). Si vous avez besoin d'une configuration différente, ajoutez le fichier hotswap-agent.properties à la racine du chemin de classe (par exemple src/main/resources/hotswap-agent.properties
).
Une documentation détaillée des propriétés disponibles et des valeurs par défaut est disponible dans le fichier de propriétés de l'agent.
La syntaxe complète des options de ligne de commande est :
-javaagent:[yourpath/]hotswap-agent.jar=[option1]=[value1],[option2]=[value2]
L'agent Hotswap accepte les options suivantes :
autoHotswap=true - surveillez les modifications apportées à tous les fichiers .class et échangez automatiquement la classe dans l'application en cours d'exécution (au lieu d'exécuter Hotswap à partir de votre session de débogage IDE)
DisablePlugin=[pluginName] - désactive un plugin. Notez que cela interdira complètement le chargement du plugin (contrairement à l'option DisablePlugin dans hotswap-agent.properties, qui désactivera uniquement le plugin pour un chargeur de classe. Vous pouvez répéter cette option pour chaque plugin à désactiver.
Ajoutez l'option vm -Dhotswapagent.disablePlugin=Spring,SpringBoot pour désactiver les plugins, fonctionne de la même manière que l'option d'agent DisablePlugin dans la section précédente.
L'agent Hotswap effectue le travail de rechargement des ressources et de configuration du framework (Spring, Hibernate, ...), mais cela dépend du mécanisme standard Java hotswap pour recharger les classes. Le hotswap Java standard permet uniquement le changement de corps de méthode, ce qui le rend pratiquement inutilisable. DCEVM est un correctif JVM (Hotspot) qui permet presque tout changement de classe structurelle sur hotswap (à l'exception d'un changement de hiérarchie). Bien que l'agent hotswap fonctionne même avec Java standard, nous vous recommandons d'utiliser DCEVM (et tous les didacticiels utilisent DCEVM comme JVM cible).
L'agent Hotswap est un conteneur de plugins avec un gestionnaire de plugins, un registre de plugins et plusieurs services d'agent (par exemple pour surveiller les changements de classe/ressource). Cela aide avec les tâches courantes et les problèmes de chargement de classes. Il analyse le chemin de classe pour rechercher la classe annotée avec l'annotation @Plugin, injecte des services d'agent et enregistre les hooks de rechargement. La modification du bytecode d'exécution est fournie par la bibliothèque javaasist.
Les plugins administrés par Hotswap Agent sont généralement axés sur un framework spécifique. Par exemple, le plugin Spring utilise les services HA pour :
Modifier les classes racine Spring pour obtenir les contextes Spring et le chemin d'analyse enregistré
Surveillez tout changement de ressource sur un chemin d'analyse
Surveillez le remplacement à chaud d'un fichier de classe dans un package de chemin d'analyse.
Recharger la définition du bean après une modification
... et bien d'autres
CXF-JAXRS (3.x) - redéfinit la ressource JAXRS après la redéfinition de la classe de ressources, réinjecte l'instance si elle est intégrée à Spring et CDI (Weld/OWB).
Deltaspike (1.x,2.x) - messages, ViewConfig, référentiel, rechargement du proxy. Réinjection de beans CDI dans le cadre de Deltaspike.
ELResolver (2.x-5.x) (JuelEL, Appache Commons EL, Oracle EL 3.0) - effacer le cache ELResolver lors d'un changement de classe. Prise en charge du hotswap pour les expressions #{...}.
FreeMarker - efface le cache d'introspection de classe des beans Apache Freemarker lors du changement de définition de classe.
Hibernate (3.x-6.x) - Rechargez la configuration Hibernate après la création/la modification de l'entité.
iBatis - Rechargement de la configuration iBatis.
IDEA - prise en charge du développement d'IntelliJ IDEA dans IDEA
Jackson - efface les caches internes de Jackson lors de la redéfinition de la classe.
Jersey1 - recharge le conteneur Jersey1 après la définition ou la redéfinition de la ressource racine ou de la classe de fournisseur.
Jersey2 - recharge le conteneur Jersey2 après la définition ou la redéfinition de la ressource racine ou de la classe de fournisseur.
Logback - Rechargement de la configuration de logback.
Log4j2 - Rechargement de la configuration Log4j2.
Mojarra (2.x) - prise en charge des modifications du bundle de ressources d'application (fichier de propriétés). Prise en charge de la réinjection/rechargement des beans ViewScoped.
MyBatis (5.3) - recharger la configuration après les modifications du fichier du mappeur
MyFaces (2.x-4.x) - prise en charge des modifications du bundle de ressources d'application (fichiers de propriétés). Prise en charge de la réinjection/rechargement des beans ViewScoped.
OmniFaces - prise en charge de la réinjection/rechargement des beans ViewScoped.
OpenWebBeans - (CDI) (1.x-4.x) - recharge la définition de la classe du bean après la définition/la modification de la classe. Les beans peuvent être rechargés selon la stratégie définie dans le fichier de propriétés.
OsgiEquinox - Prise en charge Hotswap pour le développement du plugin Eclipse ou de la plateforme Eclipse.
RestEasy (2.x, 3.x) - Nettoie et enregistre les redéfinitions de classe.
Spring (3.2.x+, 4.x, 5.x) - Rechargez la configuration Spring après la définition/la modification de la classe.
Spring Boot (1.5.x+, 2.0.x) - Rechargement dynamique des fichiers de configuration Spring Boot en temps réel.
Vaadin (23.x, 24.x) - Mettez à jour les itinéraires, les modèles de modèles et, en pratique, tout ce qui se passe à la volée.
WebObjects - Effacez les caches de codage de valeurs clés, de composants, d'actions et de validation après un changement de classe.
Weld (CDI) (2.x-5.x) - recharge la définition de la classe du bean après la définition/la modification de la classe. Les beans peuvent être rechargés selon la stratégie définie dans le fichier de propriétés.
Wicket - efface les caches de guichet si les fichiers de propriétés sont modifiés
WildFlyELResolver - Effacez BeanELResolver après toute redéfinition de classe.
ZK (5x-7x) - Cadre ZK (http://www.zkoss.org/). Modifiez les valeurs par défaut des propriétés de la bibliothèque pour désactiver les caches, conserver le cache d'étiquettes et le cache du résolveur de bean.
JBossModules - ajoute un chemin de classe supplémentaire au chargeur de classe de module de JBoss. (Mouche sauvage)
Jetty - ajoutez un chemin de classe supplémentaire au chargeur de classe de l'application. Toutes les versions prenant en charge WebAppContext.getExtraClasspath doivent être prises en charge.
Tomcat (7.x, 8.x, 9.x, 10.x) configure Apache Tomcat avec la propriété extraClasspath et webApp. Prend également en charge GlassFish, Payara et Tomee7.
Undertow - ajoutez un chemin de classe supplémentaire, watchResources et webappDir au gestionnaire de ressources de Undertow.
Weblogic - ajoutez un chemin de classe supplémentaire au chargeur de classe de l'application.
AnonymousClassPatch - Échangez les noms de classes internes anonymes pour éviter les modifications non compatibles.
ClassInit - initialise les nouvelles valeurs statiques de membres/énumérations après la redéfinition de classe/énumération et conserve les valeurs statiques survivantes. (Correction d'une limitation DCEVM connue)
Hotswapper - Surveillez tout changement de fichier de classe et rechargez-le (hotswap) à la volée via Java Platform Debugger Architecture (JPDA)
Proxy (pris en charge par com.sun.proxy, CGlib) - redéfinit les classes proxy qui implémentent ou étendent les interfaces ou classes modifiées.
Trouvez une documentation détaillée de chaque plugin dans le fichier README.md principal du projet de plugin.
Cela dépend du nombre de frameworks que vous utilisez et des caches désactivés. Exemples de mesures pour une grande application d'entreprise réelle basée sur Spring + Hibernate, exécutée sur Jetty.
Setup | Startup time -----------------------------|------------- Run (plain Java) | 23s Debug (plain Java) | 24s Debug (plain DCEVM) | 28s Agent - disabled all plugins | 31s Agent - all plugins | 35s
Vous pouvez écrire un plugin directement dans le cadre de votre application. Définissez pluginPackages=your.plugin.package
dans votre configuration hotswap-agent.properties
pour découvrir les classes annotées @Plugin
. Vous aurez également besoin de la dépendance JAR de l'agent pour compiler, mais veillez à NE PAS ajouter le JAR à votre application ; il doit être chargé uniquement en tant qu'agent java. Dépendance Maven :
org.hotswapagent HotswapAgent ${project.version} provided
Voir SamplePlugin (qui fait partie de TestApplication) pour parcourir un plugin simple commenté. Lisez le fichier Lisez-moi de l'agent pour comprendre les concepts de l'agent. Vérifiez le code source des plugins existants pour plus d’exemples.
Lancez le script run-tests.sh
dans le répertoire principal. Actuellement, vous devez configurer manuellement le répertoire d'emplacement JAVA_HOME. Au moins Java 11 avec DCEVM doit être vérifié avant une version. Tous les tests automatiques sont configurés pour échouer dans l'ensemble du script en cas d'échec d'un seul test.
Accédez au répertoire représentant la racine du référentiel. Dans le cas où DCEVM s'appelle dcevm
mvn release:prepare mvn release:perform
Agent d'échange à chaud :
Jiri Bubnik - coordinateur du projet, mise en œuvre initiale
Alexandros Papadakis - Plugins Maven Versioning, Weld, JSF, Hibernate3, RestEasy, WildFly
Erki Ehtla - Plugin Spring, plugin Proxy
Vladimir Dvorak - ELResolver, OsgiEquinox, Weld, Owb, Deltaspike, Jvm, Jdk, JBossModules, ClassInit, JSF, Mybatis
Sergey Lysenko - Plugin de soudure
Samuel Pelletier - Plugin WebObjects
Jan Tecl - conception de sites Web
@liuzhengyang - plugin Jackson
Lukasz Warzecha - Plugin Log4j2
@muwaiwai - plugin iBatis
Thomas Heigl - Plugin Wicket
AJ Banck - Plugin FreeMarker
Sinan Yumak - Mojarra, plugins MyFaces
smallfour - Plugin Mybatis
@cvictory - Plugin Spring, plugin Spring Boot
@homejim - Plugin MyBatis, plugin MyBatisPlus
DCEVM :
Thomas Würthinger - mise en œuvre initiale.
Ivan Dubrov - ancien coordinateur de projet, mise à jour vers Java7+Java8, correctifs, système de build (Gradle)
Kerstin Breitender - contributrice.
Christoph Wimberger - contributeur.
Vladimir Dvorak - migration java9, java11, jbr17, jbr21, contributeur
Jiri Bubnik-migration java9,java11