Hotswap/DCEVM 在 Intellij IDEA(社区版)中不起作用

Hotswap/DCEVM doesn't work in Intellij IDEA (Community Version)

我在使用Intellij IDEA Community Version 的hotswap 功能时遇到了麻烦。我的是 v 14.1.4.

每次我启动调试并更改 java 代码后,我已经单击重建项目并按 "Yes" 确认重新加载 classes。 Intellij 报告更改 classes 已重新加载,但应用程序结果与以前相同。我只是在尝试最简单的 Java 应用程序(即不在 Tomcat、applet 等场景中),使用 System.out.println、字符串连接等简单的东西。我在调试模式下所做的更改只是方法体代码,而不是方法signature/name。听不懂。

在Eclipse中我直接修改代码,然后按保存,就可以了。

出了什么问题?

(备注:

事实上,我正在尝试使用 DCEVM,它使结构更改成为可能(例如更改 class 名称、方法名称、添加方法等),认为它可以解决在中发现的热交换问题Intellij。不用说,它没有用。

在eclipse中,我成功使用了DCEVM,并且可以在调试过程中更改方法名称。

我进一步尝试了hotswap-agent,还是不行;我看到一篇文章说 IDE 必须通过端口 5000 JDPA 连接到 JVM,但无论我如何尝试,Intellij 控制台显示它仍在通过随机端口(下面的 51018)连接:

"C:\Program Files\Java\jdk1.8.0_60\bin\java" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:51018...."

连接到目标虚拟机,地址:'127.0.0.1:51018',传输:'socket'

是否可以强制它通过一个特定的端口连接? 在 Run/Debug 配置中添加 DEBUG_OPT 环境变量不起作用)

在找到 Jetbrains 对 issue request 的反馈后发现这是 Intellij 的设计行为:

换句话说,这个问题与我如何测试热插拔有关:

public class Main {
//    /*
    public static String getName() {
        return "James"; // <=== (2)
    }

    //*/
    public static void main(String[] args) {
        System.out.println("Hello " + getName()); // <=== (1)
    }
}
  1. 由于 Intellij 的行为是“在 VM 退出过时的堆栈框架之前仍然使用旧代码”(与 Eclipse 不同的行为),如果在 (1) 处将“Hello”更改为“Bye”,则永远不会执行新代码 - 只有在第二次调用 main() 时才能再次执行新代码,这是不可能的,因为应用程序已经终止

  2. 如果更改的是 (2)(例如,将“James”替换为“Sean”)而不是 (1),在执行光标运行期间被放置在 (1) 的断点停止(因此还没有进入 getName()),你重新加载 class,你将得到新代码 运行(打印“肖恩”)

DCEVM 也完美运行,使用相同的方式测试热交换

您还可以在堆栈跟踪中使用“丢帧”window 使当前语句回滚到方法的开头(main() 除外)——事实上,这与 Eclipse 中的行为相同。