Skip to content

autoHotswap 配置不可达:AgentArgs 无该字段,HotSwapperPlugin 文件监听无法通过 agent 参数开启 #320

Description

@ayuayue

autoHotswap 配置不可达:AgentArgs 无该字段,HotSwapperPlugin 文件监听永远无法通过 agent 参数开启

现象

HotSwapperPlugin 提供了基于 @OnClassFileEvent 的 class 文件监听自动重载能力,但通过 IDEA 插件(以 -javaagent 方式带 hotswap=true 启动)使用时,该能力永远无法启用,只能靠往应用 classpath 放 debug-tools-agent.properties 开启。

源码分析

1. agent 启动参数链路中不存在 autoHotswap

DebugToolsJavaProgramPatcher.applyForConfiguration() 中 hotswap executor 分支只设置了:

agentArgs.setHotswap(Boolean.TRUE.toString());
agentArgs.setServer(Boolean.FALSE.toString());
// ... printSql / traceSql / autoAttach / autoSaveSql / sqlRetentionDays / logLevel
// 没有任何 autoHotswap 相关设置

AgentArgs 类本身也没有 autoHotswap 字段。且 AgentArgs.parse() 用反射 getDeclaredField(keyValue[0]) 解析 key=value,未知 key 走 catch (Exception ignored) 静默丢弃——用户手写 -javaagent:...=autoHotswap=true 也不会生效,无任何提示。

2. HotswapAgent.isAutoHotswap() 恒为 false

// HotswapAgent.java:50
private static boolean autoHotswap = false;

// parseArgs() 只处理了 disabledPlugins 和 propertiesFilePath,
// 从不写 autoHotswap

3. HotSwapperPlugin.init() 的两个 skip 条件必然命中第一个

if (!HotswapAgent.isAutoHotswap() && !pluginConfiguration.containsPropertyFile()) {
    LOGGER.debug("... hot swapper skipped.");   // isAutoHotswap() 恒 false → 只要没有 properties 文件就走这里
    return;
}
if (!HotswapAgent.isAutoHotswap() && !pluginConfiguration.getPropertyBoolean("autoHotswap")) {
    return;
}

结论:@OnClassFileEvent 监听永远不会注册,watcher 自动重载成为只能通过 classpath 内 debug-tools-agent.properties(PluginConfiguration.PLUGIN_CONFIGURATION)开启的死配置面——这会污染应用构建产物,实际很少有人这么用。

影响评估

  • 不影响正常功能:本项目的设计是 IDEA 侧主动推送重载(compile_and_reload_modified_files 走 debugger HotSwap、HotDeploymentAction → LocalCompilerHotDeployPacket → redefineClasses),都不依赖 agent 侧文件监听。改完代码不会"自动"重载,需显式触发。
  • 是能力缺口而非 bug:对 AI Agent 场景(MCP 工具链)有实际价值——若 agent 参数能开 autoHotswap,AI 改完代码后无需等 IDEA 侧触发,class 文件落盘即自动 redefine,减少一次显式 compile_and_reload_modified_files 调用。

建议修复(最小改动,3 处)

  1. AgentArgs 增加 autoHotswap 字段(format()/parse() 均为反射驱动,加字段即自动生效);loadConfigurationFile() 中增加从外部 properties 兜底读取
  2. HotswapAgent.parseArgs() 增加:
    if (DebugToolsStringUtils.isNotBlank(args.getAutoHotswap())) {
        autoHotswap = Boolean.parseBoolean(args.getAutoHotswap());
    }
  3. (可选)DebugToolsJavaProgramPatcher + 设置页增加开关,默认关闭

设计取舍(需要作者确认)

不确定默认不透传 autoHotswap 是有意为之还是历史遗漏:

  • 若有意(如避免与 debugger HotSwap / HotDeploymentAction 两条重载通道叠加触发、缺少跨通道协调):建议至少在 AgentArgs.parse() 对未知 key 打 warning 日志,避免用户参数被静默吞掉
  • 若是遗漏:按上面 3 处修复即可;不建议默认开启,watcher 自动 redefine 与 IDEA 侧显式重载同时触发时目前只有 PluginManager.hotswapLock 兜底

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions