Dies ist eine Übersichtsseite. Weitere Informationen finden Sie unter hotswapagent.org.
Unbegrenzte Java-Laufzeitklassen- und Ressourcen-Neudefinition.
Das Hauptziel dieses Projekts bestand darin, den traditionellen Entwicklungszyklus „Code ändern -> neu starten und warten... -> prüfen“ überflüssig zu machen. Im Laufe der Zeit hat sich dieses Konzept zu einem neuen Paradigma innerhalb des Java-Ökosystems entwickelt und ermöglicht die Softwareentwicklung in Echtzeit innerhalb einer laufenden Anwendung. Dieser Ansatz ist sogar in eingeschränkten Umgebungen wie Docker-Containern machbar.
Wenn Sie ein IntelliJ-Benutzer sind, können Sie die Einrichtung von HA und DCEVM vereinfachen, indem Sie das IntelliJ HotSwapHelper-Plugin verwenden.
Herunterladen und installieren:
Für Java 17/21: Laden Sie die neueste JBR17 oder JBR21 herunter. Da diese Versionen keinen integrierten Hotswap-Agenten enthalten, müssen Sie hotswap-agent.jar
manuell in den Ordner lib/hotswap
kopieren. Den neuesten Hotswap-Agenten finden Sie hier. Stellen Sie sicher, dass die Datei im Ordner lib/hotswap
den Namen hotswap-agent.jar
ohne Versionsnummern im Dateinamen trägt.
Für Java 11: Verwenden Sie TravaJDK, das über einen integrierten HotswapAgent verfügt, und installieren Sie es als alternatives JDK. Alternativ enthält TravaJDK einen eingebetteten HotswapAgent.
Für Java 8: Verwenden Sie jdk8-dcevm zusammen mit dem HotswapAgent.
HotswapAgent-Modi:
Ab dcevm-11.0.9
ist der HotswapAgent standardmäßig deaktiviert. Sie können die Unterstützung für HotswapAgent mithilfe von JVM-Optionen in einem von drei Modi aktivieren:
Der HotswapAgent=core
Modus funktioniert ohne zusätzliche Plugins, mit Ausnahme der Kern-JVM-Plugins, was zu einer schnelleren Leistung aufgrund reduzierter Scan- und Klassenkopieraufgaben führt. Um zusätzliche Plugins zu verwenden, müssen Sie diese als Maven-Abhängigkeiten in Ihrer pom.xml
Datei konfigurieren. Andererseits umfasst der HotswapAgent=fatjar
-Modus standardmäßig alle Plugins, was den Anwendungsstart etwas verlangsamen kann.
-XX:HotswapAgent=fatjar
aktiviert den internen Fatjar HotswapAgent.
-XX:HotswapAgent=core
aktiviert den internen Kern-HotswapAgent.
-XX:HotswapAgent=external
konfiguriert die JVM-Unterstützung für HotswapAgent und ermöglicht dem Benutzer die Bereitstellung eines externen hotswap-agent.jar
mithilfe der Option -javaagent:
.
3.Start:
Java17/21: Starten Sie Ihre Anwendung mit den Optionen -XX:+AllowEnhancedClassRedefinition -XX:HotswapAgent=fatjar
um Advanced Hotswap (dcevm) zu aktivieren und die Fatjar-Version des Hotswap-Agenten zu verwenden. Alternativ können core
oder external
Modi anstelle von fatjar
verwendet werden.
Java11: Starten Sie Ihre Anwendung mit den Optionen -XX:HotswapAgent=fatjar
um die Fatjar-Version des Hotswap-Agenten zu verwenden.
Java8: Starten Sie Ihre Anwendung mit den Optionen -XXaltjvm=dcevm -javaagent:hotswap-agent.jar
um eine grundlegende Einrichtung zu erhalten. Optional können Sie hotswap-agent.properties
zu Ihrer Anwendung hinzufügen, um Plugins und das Verhalten des Agenten zu konfigurieren.
3.Führen Sie Ihre Anwendung aus:
Starten Sie die Anwendung im Debug-Modus und prüfen Sie, ob der Agent und die Plugins korrekt initialisiert sind:
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.Überprüfen Sie die Neudefinition
Speichern Sie eine geänderte Ressource und/oder verwenden Sie die HotSwap-Funktion Ihrer IDE, um Änderungen erneut zu laden
Jedes Anwendungsframework (Spring, Hibernate, Logback, ...) benötigt einen speziellen Neulademechanismus, um nach der Neudefinition der Klasse auf dem neuesten Stand zu bleiben (z. B. Neuladen der Hibernate-Konfiguration nach Einführung einer neuen Entitätsklasse). Der Hotswap-Agent funktioniert als Plugin-System und wird mit allen wichtigen Framework-Plugins vorkonfiguriert ausgeliefert. Es ist einfach, Ihr benutzerdefiniertes Plugin sogar als Teil Ihrer Anwendung zu schreiben.
Dieses Projekt ist aufgrund der vielen unterstützten Frameworks und verschiedenen Versionen sehr komplex. Um es am Leben zu erhalten, ist ein Beitrag der Gemeinschaft erforderlich. Sie können damit beginnen, ein Plugin in Ihrer Anwendung zu erstellen oder ein Beispiel/Integrationstest zu schreiben. Es besteht immer Bedarf an einer Verbesserung der Dokumentation :-). Vielen Dank für jede Hilfe!
Verbesserter Java Hotswap – Methodenkörper ändern, Methode, Feld hinzufügen/umbenennen, ... Der einzige nicht unterstützte Vorgang ist das Ändern der Oberklasse.
Sie können Standard-Java-Hotswap von der IDE im Debug-Modus verwenden, um geänderte Klassen neu zu laden
oder legen Sie die AutoHotswap-Eigenschaft -XXaltjvm=dcevm -javaagent:PATH_TO_AGENThotswap-agent.jar=autoHotswap=true
fest, um geänderte Klassen nach der Kompilierung neu zu laden. Dieses Setup ermöglicht sogar ein Neuladen auf einem Produktionssystem ohne Neustart.
Automatische Konfiguration – alle lokalen Klassen und Ressourcen, die der laufenden Java-Anwendung bekannt sind, werden automatisch erkannt und auf das Neuladen überwacht (alle Dateien im lokalen Dateisystem, nicht in einer JAR-Datei).
Zusätzlicher Klassenpfad – Müssen Sie eine Laufzeitklasse innerhalb der abhängigen JAR ändern? Verwenden Sie die Eigenschaft extraClasspath, um ein beliebiges Verzeichnis als Klassenpfad hinzuzufügen, um nach Klassendateien zu suchen.
Ressource nach einer Änderung neu laden – Ressourcen aus dem Webapp-Verzeichnis werden normalerweise vom Anwendungsserver neu geladen. Aber was ist mit anderen Ressourcen wie src/main/resources? Verwenden Sie die Eigenschaft „watchResources“, um ein beliebiges Verzeichnis hinzuzufügen, das auf eine Ressourcenänderung überwacht werden soll.
Framework-Unterstützung – durch das Plugin-System werden viele Frameworks unterstützt. Neue Plugins können einfach hinzugefügt werden.
Schnell – bis das Plugin initialisiert ist, verbraucht es keine Ressourcen und verlangsamt die Anwendung nicht (weitere Informationen finden Sie unter Laufzeit-Overhead).
Sollten Sie Probleme oder Fragen haben, wenden Sie sich an das HotswapAgent-Forum.
Dieses Projekt ähnelt JRebel. Die Hauptunterschiede sind:
HotswapAgent (DCEVM) unterstützt Java8, Java11 und Java17!
HotswapAgent benötigt keine zusätzliche Konfiguration für die grundlegende Projekteinrichtung.
JRebel ist derzeit ausgereifter und enthält mehr Plugins.
JRebel ist weder Open Source noch kostenlos.
JRebel ändert den Bytecode aller Klassen beim Neuladen. Sie benötigen ein spezielles IDE-Plugin, um das Debuggen zu beheben.
HotswapAgent extraClasspath ähnelt der JRebel-Konfiguration
HotswapAgent fügt die watchResources-Konfiguration hinzu
Siehe HotswapAgentExamples GitHub-Projekt. Der Zweck einer Beispielanwendung ist:
komplexe Integrationstests automatisieren (verschiedene Konfigurationen vor einer Veröffentlichung prüfen, siehe Skript run-tests.sh
)
um die Plugin-Nutzung in der „realen Welt“ während der Plugin-Entwicklung zu überprüfen (d. h. innerhalb eines Containers)
um eine funktionierende Lösung für typische Anwendungskonfigurationen bereitzustellen
Sandbox zur Simulation von Problemen für bestehende oder neue Setups
Fühlen Sie sich frei, eine Anwendung für Ihr Setup zu forken/verzweigen und zu erstellen (funktionell, aber so einfach wie möglich). Allgemeine Setups werden im Master zusammengeführt.
Nichts nötig :) Wirklich! Alle Änderungen sind transparent und Sie müssen lediglich Patch+Agent herunterladen und Ihre Anwendung/Ihren Anwendungsserver einrichten. Da wir das standardmäßige Java-Hotswap-Verhalten verwenden, funktioniert Ihre IDE wie erwartet. Wir arbeiten jedoch an IDE-Plugins, die beim Herunterladen und Konfigurieren helfen.
Einige Plugins sind bereits verfügbar:
Fügen Sie neben der Schaltfläche „Debuggen“ in Intellij zwei Aktionen hinzu: „Mit Hotswap ausführen“ und „Mit Hotswap debuggen“.
Wenn Sie auf die Aktion klicken, werden die VM-Parameter für Sie festgelegt. Sie müssen die VM-Parameter nicht manuell festlegen.
Quellcode und Dokumentation: https://github.com/gejun123456/HotSwapHelper.
Die Grundkonfiguration ist so eingestellt, dass Klassen und Ressourcen aus dem Klassenpfad neu geladen werden, der der laufenden Anwendung bekannt ist (Klassenlader). Wenn Sie eine andere Konfiguration benötigen, fügen Sie die Datei hotswap-agent.properties zum Stammverzeichnis des Klassenpfads hinzu (z. B. src/main/resources/hotswap-agent.properties
).
Eine detaillierte Dokumentation der verfügbaren Eigenschaften und Standardwerte finden Sie in der Agenteneigenschaftendatei
Die vollständige Syntax der Befehlszeilenoptionen lautet:
-javaagent:[yourpath/]hotswap-agent.jar=[option1]=[value1],[option2]=[value2]
Der Hotswap-Agent akzeptiert die folgenden Optionen:
autoHotswap=true – Überwachen Sie alle .class-Dateien auf Änderungen und tauschen Sie die Klasse automatisch in der laufenden Anwendung aus (anstatt Hotswap über Ihre IDE-Debugging-Sitzung auszuführen).
disablePlugin=[pluginName] – ein Plugin deaktivieren. Beachten Sie, dass dadurch das Laden des Plugins vollständig verhindert wird (im Gegensatz zur Option „disablePlugin“ in hotswap-agent.properties, die das Plugin nur für einen Klassenlader deaktiviert. Sie können diese Option für jedes zu deaktivierende Plugin wiederholen.
Fügen Sie die VM-Option -Dhotswapagent.disablePlugin=Spring,SpringBoot hinzu, um Plugins zu deaktivieren. Funktioniert genauso wie die Agent-Option „disablePlugin“ im vorherigen Abschnitt.
Der Hotswap-Agent übernimmt die Aufgabe, Ressourcen und Framework-Konfigurationen (Spring, Hibernate usw.) neu zu laden, hängt jedoch vom Standard-Java-Hotswap-Mechanismus zum Neuladen von Klassen ab. Standard-Java-Hotswap erlaubt nur die Änderung des Methodenkörpers, was es praktisch unbrauchbar macht. DCEVM ist ein JVM-Patch (Hotspot), der nahezu jede strukturelle Klassenänderung bei Hotswap zulässt (mit Ausnahme einer Hierarchieänderung). Obwohl der Hotswap-Agent auch mit Standard-Java funktioniert, empfehlen wir die Verwendung von DCEVM (und alle Tutorials verwenden DCEVM als Ziel-JVM).
Der Hotswap-Agent ist ein Plugin-Container mit Plugin-Manager, Plugin-Registrierung und mehreren Agent-Diensten (z. B. um auf Klassen-/Ressourcenänderungen zu achten). Es hilft bei allgemeinen Aufgaben und Problemen beim Laden von Klassen. Es durchsucht den Klassenpfad nach Klassen, die mit der @Plugin-Annotation annotiert sind, fügt Agentendienste ein und registriert Neulade-Hooks. Die Laufzeit-Bytecode-Änderung wird von der Javaasist-Bibliothek bereitgestellt.
Von Hotswap Agent verwaltete Plugins sind normalerweise auf ein bestimmtes Framework ausgerichtet. Das Spring-Plugin verwendet beispielsweise HA-Dienste, um:
Ändern Sie Root-Spring-Klassen, um Spring-Kontexte und einen registrierten Scanpfad zu erhalten
Achten Sie auf Ressourcenänderungen auf einem Scanpfad
Achten Sie auf einen Hotswap einer Klassendatei innerhalb eines Scanpfadpakets
Bean-Definition nach einer Änderung neu laden
... und viele andere
CXF-JAXRS (3.x) – Definieren Sie die JAXRS-Ressource nach der Neudefinition der Ressourcenklasse neu und fügen Sie die Instanz erneut ein, wenn sie in Spring und CDI (Weld/OWB) integriert ist.
Deltaspike (1.x,2.x) – Nachrichten, ViewConfig, Repository, Proxy-Neuladen. CDI-Bohnen-Reinjektion mit Deltaspike-Zielfernrohr.
ELResolver (2.x-5.x) (JuelEL, Appache Commons EL, Oracle EL 3.0) – ELResolver-Cache bei Klassenänderung löschen. Unterstützt Hotswap für #{...}-Ausdrücke.
FreeMarker – löscht den Klassen-Introspektion-Cache der Apache Freemarker-Beans bei Klassendefinitionsänderungen.
Ruhezustand (3.x-6.x) – Laden Sie die Ruhezustandskonfiguration nach dem Erstellen/Ändern der Entität neu.
iBatis – Neuladen der iBatis-Konfiguration.
IDEA – Unterstützung für die IntelliJ IDEA-Entwicklung in IDEA
Jackson – löscht Jacksons interne Caches, wenn die Klasse neu definiert wird.
Jersey1 – Jersey1-Container nach Definition oder Neudefinition der Stammressource oder Anbieterklasse neu laden.
Jersey2 – Jersey2-Container nach Definition oder Neudefinition der Stammressource oder Anbieterklasse neu laden.
Logback – Neuladen der Logback-Konfiguration.
Log4j2 – Neuladen der Log4j2-Konfiguration.
Mojarra (2.x) – Unterstützung für Änderungen des Anwendungsressourcenpakets (Eigenschaftendatei). Unterstützung für die erneute Injektion/Neuladung von ViewScoped-Beans.
MyBatis (5.3) – Konfiguration nach Änderungen der Mapper-Datei neu laden
MyFaces (2.x-4.x) – Unterstützung für Änderungen an Anwendungsressourcenpaketen (Eigenschaftsdateien). Unterstützung für die erneute Injektion/Neuladung von ViewScoped-Beans.
OmniFaces – Unterstützung für die Neuinjektion/Neuladung von ViewScoped-Beans.
OpenWebBeans – (CDI) (1.x-4.x) – Bean-Klassendefinition nach Klassendefinition/-änderung neu laden. Beans können gemäß der in der Eigenschaftendatei definierten Strategie neu geladen werden.
OsgiEquinox – Hotswap-Unterstützung für Eclipse-Plugin oder Eclipse-Plattformentwicklung.
RestEasy (2.x, 3.x) – Bereinigt und registriert Klassenneudefinitionen.
Spring (3.2.x+, 4.x, 5.x) – Spring-Konfiguration nach Klassendefinition/-änderung neu laden.
Spring Boot (1.5.x+, 2.0.x) – Dynamisches Neuladen von Spring Boot-Konfigurationsdateien in Echtzeit.
Vaadin (23.x, 24.x) – Aktualisieren Sie Routen, Vorlagenmodelle und in der Praxis alles im Handumdrehen.
WebObjects – Löschen Sie Schlüsselwert-Codierungs-, Komponenten-, Aktions- und Validierungs-Caches nach Klassenänderungen.
Weld (CDI) (2.x-5.x) – Bean-Klassendefinition nach Klassendefinition/-änderung neu laden. Beans können gemäß der in der Eigenschaftendatei definierten Strategie neu geladen werden.
Wicket – Wicket-Caches löschen, wenn Eigenschaftsdateien geändert werden
WildFlyELResolver – BeanELResolver nach jeder Klassenneudefinition löschen.
ZK (5x-7x) – ZK Framework (http://www.zkoss.org/). Ändern Sie die Standardwerte der Bibliothekseigenschaften, um Caches zu deaktivieren und den Label-Cache und den Bean-Resolver-Cache beizubehalten.
JBossModules – Fügen Sie einen zusätzlichen Klassenpfad zum Modulklassenlader von JBoss hinzu. (Wildfliege)
Jetty – Fügen Sie dem App-Klassenlader einen zusätzlichen Klassenpfad hinzu. Alle Versionen, die WebAppContext.getExtraClasspath unterstützen, sollten unterstützt werden.
Tomcat (7.x, 8.x, 9.x, 10.x) konfiguriert Apache Tomcat mit extraClasspath und webApp-Eigenschaft. Unterstützt auch GlassFish, Payara und Tomee7.
Undertow – Fügen Sie dem Ressourcenmanager des Undertow zusätzlichen Klassenpfad, watchResources und webappDir hinzu.
Weblogic – Fügen Sie dem App-Klassenlader einen zusätzlichen Klassenpfad hinzu.
AnonymousClassPatch – Tauschen Sie anonyme innere Klassennamen aus, um nicht kompatible Änderungen zu vermeiden.
ClassInit – initialisiert neue statische Mitglieder/Aufzählungswerte nach der Neudefinition der Klasse/Aufzählung und behält statische Werte bei. (Behebung der bekannten DCEVM-Einschränkung)
Hotswapper – Achten Sie auf jede Klassendateiänderung und laden Sie sie im laufenden Betrieb über die Java Platform Debugger Architecture (JPDA) neu (Hotswapper).
Proxy (unterstützt com.sun.proxy, CGlib) – definiert Proxy-Klassen neu, die geänderte Schnittstellen oder Klassen implementieren oder erweitern.
Eine ausführliche Dokumentation jedes Plugins finden Sie in der Hauptdatei README.md des Plugin-Projekts.
Es hängt davon ab, wie viele Frameworks Sie verwenden und welche Caches deaktiviert sind. Beispielmessungen für eine große, reale Unternehmensanwendung basierend auf Spring + Hibernate, ausgeführt auf 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
Sie können Plugins direkt als Teil Ihrer Anwendung schreiben. Legen Sie pluginPackages=your.plugin.package
in Ihrer hotswap-agent.properties
-Konfiguration fest, um @Plugin
annotierte Klassen zu erkennen. Zum Kompilieren benötigen Sie außerdem die JAR-Abhängigkeit des Agenten. Achten Sie jedoch darauf, die JAR NICHT zu Ihrer Anwendung hinzuzufügen. Es darf nur als Javaagent geladen werden. Maven-Abhängigkeit:
org.hotswapagent HotswapAgent ${project.version} provided
Sehen Sie sich „ExamplePlugin“ (Teil von TestApplication) an, um ein kommentiertes einfaches Plugin durchzugehen. Lesen Sie die Agenten-Readme-Datei, um die Agentenkonzepte zu verstehen. Weitere Beispiele finden Sie im Quellcode des vorhandenen Plugins.
Starten Sie das Skript run-tests.sh
im Hauptverzeichnis. Derzeit müssen Sie das Standortverzeichnis JAVA_HOME manuell einrichten. Mindestens Java 11 mit DCEVM sollte vor einem Release geprüft werden. Alle automatischen Tests sind so eingestellt, dass das gesamte Skript fehlschlägt, wenn ein einzelner Test fehlschlägt.
Gehen Sie in das Verzeichnis, das das Repository-Stammverzeichnis darstellt. Falls DCEVM dcevm
heißt
mvn release:prepare mvn release:perform
Hotswap-Agent:
Jiri Bubnik – Projektkoordinator, erste Umsetzung
Alexandros Papadakis – Maven-Versionierung, Weld, JSF, Hibernate3, RestEasy, WildFly-Plugins
Erki Ehtla – Spring-Plugin, Proxy-Plugin
Vladimir Dvorak – ELResolver, OsgiEquinox, Weld, Owb, Deltaspike, Jvm, Jdk, JBossModules, ClassInit, JSF, Mybatis
Sergey Lysenko – Schweiß-Plugin
Samuel Pelletier – WebObjects-Plugin
Jan Tecl - Webdesign
@liuzhengyang – Jackson-Plugin
Lukasz Warzecha – Log4j2-Plugin
@muwaiwai – iBatis-Plugin
Thomas Heigl – Wicket-Plugin
AJ Banck – FreeMarker-Plugin
Sinan Yumak – Mojarra, MyFaces-Plugins
smallfour – Mybatis-Plugin
@cvictory – Spring-Plugin, Spring Boot-Plugin
@homejim – MyBatis-Plugin, MyBatisPlus-Plugin
DCEVM:
Thomas Würthinger – erste Umsetzung.
Ivan Dubrov – ehemaliger Projektkoordinator, Update auf Java7+Java8, Patches, Build-System (Gradle)
Kerstin Breitender – Mitarbeiterin.
Christoph Wimberger – Mitwirkender.
Vladimir Dvorak – Java9-, Java11-, Jbr17-, Jbr21-Migration, Mitwirkender
Jiri Bubnik – Java9, Java11-Migration