这是概述页面,请访问 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 迁移