【问题标题】:Hotswap/DCEVM doesn't work in Intellij IDEA (Community Version)Hotswap/DCEVM 在 Intellij IDEA(社区版)中不起作用
【发布时间】:2015-09-10 17:09:15
【问题描述】:

我在使用 Intellij IDEA 社区版中的热插拔功能时遇到了麻烦。我的是 v 14.1.4。

每次我启动调试并更改 java 代码后,我已经单击了重新构建项目并在确认重新加载类时按“是”。 Intellij 报告已重新加载更改的类,但应用程序结果与以前相同。我只是在尝试使用System.out.println、字符串连接等内容的最简单的Java应用程序(即不在Tomcat、applet等场景中)。我在调试模式下更改的只是方法主体代码,而不是方法签名/姓名。看不懂。

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

出了什么问题?

(备注:

事实上,我正在尝试使用 DCEVM 使结构更改成为可能(例如更改类名、方法名、添加方法等),认为它可以解决 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...."

连接到目标VM,地址:'127.0.0.1:51018',传输:'socket'

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

【问题讨论】:

    标签: java intellij-idea intellij-14 hotswap dcevm


    【解决方案1】:

    在找到 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 相比的行为不同),如果您将“Hello”更改为“Bye”在(1)处,新代码将永远不会被执行——只有在第二次调用 main() 时才能再次执行新代码,这是不可能的,因为应用程序已经终止了

    2. 如果更改的是 (2)(例如,用“Sean”替换“James”)而不是 (1),在执行光标被放置在 ( 1)(因此还没有进入getName()),你重新加载类,你会得到正在运行的新代码(打印“Sean”)

    DCEVM 也可以完美运行,使用相同的方式测试热插拔

    您还可以在堆栈跟踪窗口中使用“丢帧”来使当前语句回滚到方法的开头(main() 除外) - 实际上它在 Eclipse 中是相同的行为。

    【讨论】:

    • Eclipse(据我所知)丢弃了必要的帧以摆脱过时的代码。
    猜你喜欢
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    • 1970-01-01
    • 2015-10-13
    • 2015-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多