這是一個概述頁面,請訪問 hotswapagent.org 以了解更多資訊。
Java無限運行時類別和資源重定義。
該專案的主要目標是消除傳統的「更改程式碼 -> 重新啟動並等待... -> 檢查」開發週期。隨著時間的推移,這個概念已經發展成為 Java 生態系統中的一個新範例,允許在運行的應用程式中進行即時軟體開發。這種方法甚至在受限環境中也是可行的,例如 Docker 容器。
如果您是 IntelliJ 用戶,可以使用 IntelliJ HotSwapHelper 外掛程式簡化 HA 和 DCEVM 的設定。
下載並安裝:
對於 Java 17/21:下載最新的 JBR17 或 JBR21。由於這些版本不包含內建的 Hotswap Agent,因此您需要手動將hotswap-agent.jar
複製到lib/hotswap
資料夾。您可以在此處找到最新的熱插拔代理。確保lib/hotswap
資料夾中的檔案名為hotswap-agent.jar
檔案名稱中不包含任何版本號。
對於 Java 11:使用 TravaJDK,它整合了 HotswapAgent,並將其安裝為替代 JDK。或者,TravaJDK 包含嵌入式 HotswapAgent。
對於 Java 8:將 jdk8-dcevm 與 HotswapAgent 一起使用。
HotswapAgent 模式:
從dcevm-11.0.9
開始,預設會停用 HotswapAgent。您可以在以下三種模式之一中使用 JVM 選項啟用對 HotswapAgent 的支援:
HotswapAgent=core
模式無需額外插件(核心 JVM 插件除外)即可運行,由於掃描和類別複製任務減少,因此效能更快。要使用其他插件,您需要在pom.xml
檔案中將它們配置為 Maven 依賴項。另一方面, HotswapAgent=fatjar
模式預設包含所有插件,這可能會稍微減慢應用程式的啟動速度。
-XX:HotswapAgent=fatjar
啟動內部 fatjar HotswapAgent。
-XX:HotswapAgent=core
啟動內部核心HotswapAgent。
-XX:HotswapAgent=external
配置 JVM 對 HotswapAgent 的支持,並允許使用者使用-javaagent:
選項提供外部hotswap-agent.jar
。
3.啟動:
Java17/21:使用選項-XX:+AllowEnhancedClassRedefinition -XX:HotswapAgent=fatjar
啟動應用程式以開啟進階熱交換 (dcevm) 並使用 Hotswap Agent fatjar 版本。作為替代core
或external
模式,可以使用fatjar
來代替。
Java11:使用選項-XX:HotswapAgent=fatjar
啟動應用程式以使用 Hotswap Agent fatjar 版本。
Java8:使用選項-XXaltjvm=dcevm -javaagent:hotswap-agent.jar
啟動應用程式以取得基本設定。您可以選擇將hotswap-agent.properties
新增至應用程式以配置插件和代理程式的行為。
3.運行您的應用程式:
以調試模式啟動應用程序,檢查代理和插件是否正確初始化:
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.檢查重新定義
儲存變更的資源和/或使用 IDE 的 HotSwap 功能重新載入更改
每個應用程式框架(Spring、Hibernate、Logback...)都需要一個特殊的重新載入機制來在類別重新定義後保持最新(例如,在引入新實體類別後重新載入Hibernate 配置)。 Hotswap 代理程式以外掛系統運作,並預先配置了所有主要框架外掛程式。即使作為應用程式的一部分,也可以輕鬆編寫自訂插件。
由於支援的框架很多且版本多樣,這個專案非常複雜。為了保持其活力,社區貢獻是強制性的。您可以從在應用程式內建立外掛程式或編寫範例/整合測試開始。總是需要改進文件:-)。感謝您的幫忙!
增強的 Java Hotswap - 更改方法體、新增/重新命名方法、欄位…唯一不支援的操作是更改超類別。
您可以在偵錯模式下使用 IDE 中的標準 Java Hotswap 來重新載入變更的類
或設定 autoHotswap 屬性-XXaltjvm=dcevm -javaagent:PATH_TO_AGENThotswap-agent.jar=autoHotswap=true
以在編譯後重新載入已變更的類別。此設定甚至允許在生產系統上重新加載而無需重新啟動。
自動配置 - 運行的 Java 應用程式已知的所有本機類別和資源都會自動發現並監視重新載入(本機檔案系統上的所有文件,而不是任何 JAR 文件內的文件)。
額外的類別路徑 - 需要更改依賴 JAR 內的運行時類別嗎?使用 extraClasspath 屬性將任何目錄新增為類別路徑以監視類別檔案。
更改後重新載入資源 - webapp 目錄中的資源通常由應用程式伺服器重新載入。但是像 src/main/resources 這樣的其他資源呢?使用 watchResources 屬性新增任何目錄以監視資源變更。
框架支援 - 透過插件系統,支援許多框架。可以輕鬆新增插件。
快速 - 在插件初始化之前,它不會消耗任何資源或減慢應用程式的速度(有關更多信息,請參閱運行時開銷)
如果您有任何問題或疑問,請在 HotswapAgent 論壇提問。
該項目與 JRebel 類似。主要區別是:
HotswapAgent (DCEVM) 支援 Java8、Java11 和 Java17!
HotswapAgent 不需要任何額外的設定來進行基本項目設定。
JRebel目前更加成熟,包含更多外掛程式。
JRebel 既不是開源的,也不是免費的。
JRebel 在重新載入時修改所有類別的字節碼。您需要一個特殊的 IDE 插件來修復調試。
HotswapAgent extraClasspath與JRebel配置類似
HotswapAgent 新增 watchResources 配置
請參閱 HotswapAgentExamples GitHub 專案。範例應用程式的目的是:
複雜的自動化整合測試(在發布之前檢查各種配置,請參閱run-tests.sh
腳本)
在插件開發期間檢查「現實世界」插件的使用情況(即在容器內)
為典型應用程式設定提供可行的解決方案
沙箱來模擬現有或新設定的問題
請隨意分叉/分支並為您的設定建立應用程式(功能齊全,但盡可能簡單)。常規設定將合併到主設定。
不需要:)真的!所有更改都是透明的,您所需要做的就是下載補丁+代理並設定您的應用程式/應用程式伺服器。因為我們使用標準的 java 熱插拔行為,所以您的 IDE 將如預期般運作。不過,我們致力於開發 IDE 外掛程式來幫助下載和設定。
一些插件已經可用:
在 intellij 中的「調試」按鈕旁邊添加兩個操作:使用熱交換運行、使用熱交換進行調試。
點擊該操作時,將為您設定虛擬機器參數,無需手動設定虛擬機器參數。
原始碼和文件:https://github.com/gejun123456/HotSwapHelper。
基本配置設定為從正在運行的應用程式(類別載入器)已知的類別路徑重新載入類別和資源。如果您需要不同的配置,請將 hotswap-agent.properties 檔案新增至類別路徑根目錄(例如src/main/resources/hotswap-agent.properties
)。
可用屬性和預設值的詳細文件可以在代理屬性檔案中找到
命令列選項的完整語法是:
-javaagent:[yourpath/]hotswap-agent.jar=[option1]=[value1],[option2]=[value2]
熱插拔代理接受以下選項:
autoHotswap=true - 監視所有 .class 檔案的變更並自動在正在執行的應用程式中熱交換該類別(而不是從 IDE 偵錯會話執行熱交換)
disablePlugin=[pluginName] - 停用插件。請注意,這將完全禁止載入插件(與 hotswap-agent.properties 中的 disablePlugin 選項相反,該選項只會停用類別載入器的插件。您可以對每個要停用的插件重複此選項。
新增vm選項-Dhotswapagent.disablePlugin=Spring,SpringBoot以停用插件,與上一節的代理選項disablePlugin相同。
Hotswap代理負責重新載入資源和框架配置(Spring、Hibernate等)的工作,但它依賴標準的Java熱交換機制來重新載入類別。標準 Java 熱插拔僅允許更改方法體,這使得它實際上無法使用。 DCEVM 是一個 JVM(熱點)補丁,它允許熱交換上的幾乎所有結構類別變更(層次結構變更除外)。儘管熱交換代理甚至可以使用標準 java,但我們建議使用 DCEVM(並且所有教程都使用 DCEVM 作為目標 JVM)。
Hotswap 代理程式是一個外掛程式容器,具有外掛程式管理器、外掛程式註冊表和多個代理服務(例如,用於監視類別/資源變更)。它有助於解決常見任務和類別載入問題。它掃描類路徑以查找帶有 @Plugin 註釋的類,注入代理服務並註冊重新載入掛鉤。運行時字節碼修改由 javaasist 庫提供。
Hotswap Agent 管理的插件通常專注於特定框架。例如,Spring 插件使用 HA 服務來:
修改根 Spring 類別以取得 Spring 上下文和註冊的掃描路徑
監視掃描路徑上的任何資源變化
監視掃描路徑包中類別文件的熱交換
更改後重新載入 bean 定義
……以及許多其他人
CXF-JAXRS (3.x) - 在資源類別重新定義後重新定義 JAXRS 資源,如果與 Spring 和 CDI (Weld/OWB) 集成,則重新註入實例。
Deltaspike (1.x,2.x) - 訊息、ViewConfig、儲存庫、代理重新載入。 Deltaspike 範圍 CDI 豆再注入。
ELResolver (2.x-5.x)(JuelEL、Appache Commons EL、Oracle EL 3.0)- 在類別變更時清除 ELResolver 快取。支援 #{...} 表達式的熱插拔。
FreeMarker - 在類別定義變更時清除 Apache Freemarker beans 類別內省快取。
Hibernate (3.x-6.x) - 在實體建立/變更後重新載入 Hibernate 設定。
iBatis - iBatis 配置重新載入。
IDEA - 支援IDEA中的IntelliJ IDEA開發
Jackson - 重新定義類別時清除 Jackson 內部快取。
Jersey1 - 在根資源或提供程式類別定義或重新定義後重新載入 Jersey1 容器。
Jersey2 - 在根資源或提供程式類別定義或重新定義後重新載入 Jersey2 容器。
Logback - Logback 配置重新載入。
Log4j2 - Log4j2 配置重新載入。
Mojarra (2.x) - 支援應用程式資源包變更(屬性檔)。支援 ViewScoped beans 重新註入/重新加載。
MyBatis (5.3) - 映射器檔案變更後重新載入配置
MyFaces (2.x-4.x) - 支援應用程式資源包變更(屬性檔)。支援 ViewScoped beans 重新註入/重新加載。
OmniFaces - 支援 ViewScoped beans 重新註入/重新加載。
OpenWebBeans - (CDI) (1.x-4.x) - 在類別定義/變更後重新載入 bean 類別定義。 Bean 可以根據屬性檔案中定義的策略重新載入。
OsgiEquinox - 對 Eclipse 外掛程式或 Eclipse 平台開發的熱交換支援。
RestEasy(2.x、3.x)- 清理並註冊類別重新定義。
Spring(3.2.x+、4.x、5.x)- 在類別定義/更改後重新載入 Spring 配置。
Spring Boot(1.5.x+、2.0.x)- 即時動態重新載入 Spring Boot 設定檔。
Vaadin (23.x, 24.x) - 更新路線、範本模型以及實踐中的任何動態內容。
WebObjects - 類別變更後清除鍵值編碼、元件、操作和驗證快取。
Weld (CDI) (2.x-5.x) - 在類別定義/變更後重新載入 bean 類別定義。 Bean 可以根據屬性檔案中定義的策略重新載入。
Wicket - 如果屬性檔案發生更改,則清除 wicket 快取
WildFlyELResolver - 在任何類別重新定義後清除 BeanELResolver.
ZK (5x-7x) - ZK 框架 (http://www.zkoss.org/)。更改庫屬性預設值以停用快取,維護標籤快取和 bean 解析器快取。
JBossModules - 新增額外的類別路徑到 JBoss 的模組類別載入器。 (野蠅)
Jetty - 將額外的類別路徑新增至應用程式類別載入器。應支援所有支援 WebAppContext.getExtraClasspath 的版本。
Tomcat(7.x、8.x、9.x、10.x)使用 extraClasspath 和 webApp 屬性來設定 Apache Tomcat。也支援 GlassFish、Payara 和 Tomee7。
Undertow - 將額外的類別路徑、watchResources 和 webappDir 加入到 undertow 的資源管理器中。
Weblogic - 將額外的類別路徑新增至應用程式類別載入器。
AnonymousClassPatch - 交換匿名內部類別名稱以避免不相容的變更。
ClassInit - 在類別/枚舉重新定義後初始化新的靜態成員/枚舉值並保持存活的靜態值。 (修復已知的 DCEVM 限制)
Hotswapper - 監視任何類別檔案變更並透過 Java 平台偵錯器架構 (JPDA) 即時重新載入(熱交換)它
代理程式(支援 com.sun.proxy、CGlib)- 重新定義實作或擴充已變更的介面或類別的代理類別。
在外掛程式專案主 README.md 檔案中尋找每個外掛程式的詳細文件。
這取決於您使用的框架數量以及禁用了哪些快取。基於 Spring + Hibernate、在 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
您可以直接編寫插件作為應用程式的一部分。在hotswap-agent.properties
配置中設定pluginPackages=your.plugin.package
以發現@Plugin
註解的類別。您還需要代理 JAR 依賴項來編譯,但請注意不要將 JAR 新增到您的應用程式中;它必須僅作為 javaagent 載入。 Maven 依賴:
org.hotswapagent HotswapAgent ${project.version} provided
請參閱ExamplePlugin(TestApplication 的一部分)來瀏覽帶有註解的簡單插件。閱讀代理自述文件以了解代理概念。檢查現有插件原始程式碼以取得更多範例。
在主目錄中啟動run-tests.sh
腳本。目前,您必須手動設定 JAVA_HOME 位置目錄。在發布之前至少應該檢查帶有 DCEVM 的 Java 11。所有自動測試都設定為在任何單一測試失敗的情況下使整個腳本失敗。
前往代表儲存庫根的目錄。如果 DCEVM 被命名為dcevm
mvn release:prepare mvn release:perform
熱插拔代理:
Jiri Bubnik - 專案協調員,初步實施
Alexandros Papadakis - Maven 版本控制、Weld、JSF、Hibernate3、RestEasy、WildFly 插件
Erki Ehtla - Spring 插件、代理插件
Vladimir Dvorak - ELResolver、OsgiEquinox、Weld、Owb、Deltaspike、Jvm、Jdk、JBossModules、ClassInit、JSF、Mybatis
Sergey Lysenko - 焊接插件
Samuel Pelletier - WebObjects 插件
Jan Tecl - 網頁設計
@liuzhengyang - 傑克遜插件
Lukasz Warzecha - Log4j2 插件
@muwaiwai - iBatis 插件
Thomas Heigl - Wicket 插件
AJ Bank - FreeMarker 插件
Sinan Yumak - Mojarra、MyFaces 插件
Smallfour - Mybatis 插件
@cvictory - Spring 外掛程式、Spring Boot 插件
@homejim - MyBatis 外掛程式、MyBatisPlus 插件
直流電子虛擬機器:
Thomas Würthinger - 初步實施。
Ivan Dubrov - 前專案協調員,更新至 Java7+Java8、修補程式、建置系統 (Gradle)
Kerstin Breitender - 貢獻者。
克里斯托夫溫伯格 - 貢獻者。
Vladimir Dvorak - java9、java11、jbr17、jbr21 遷移、貢獻者
Jiri Bubnik - java9、java11 遷移