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

1

9

I have troubles in making use of the hotswap function in Intellij IDEA Community Version. Mine is v 14.1.4.

Each time after I fired off debugging and change the java code, I have already click rebuild project and press "Yes" on confirming reload classes. Intellij reports that changed classes are reloaded, but the application outcome is the same as before. I'm just trying the simplest Java application (i.e. not in scenarios like Tomcat, applet etc) with stuffs simply like System.out.println, string concats etc. What I've changed during debug mode is just method body codes, but not the method signature/name. I can't get it.

In Eclipse I just directly change the code and press save, then it just works.

What went wrong?

(Remarks:

In fact I'm attempting to use DCEVM which makes structure change possible (e.g. change class name, method name, add methods etc), thought that it would solve the problem of the hotswap problem found in Intellij. Needless to say, it didn't work.

In eclipse, I succeed in using DCEVM and can change the method names during debugging.

I further try hotswap-agent and it still didn't work; I've come across an article saying that the IDE must JDPA-connect to the JVM thru port 5000, but no matter how I tried, Intellij console shows that it is still connecting thru a random port (51018 below):

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

Connected to the target VM, address: '127.0.0.1:51018', transport: 'socket'

Is it possible to force it to connect thru one specific port? Adding the DEBUG_OPT environment variable in the Run/Debug Config doesn't work)

Brigidabrigit answered 10/9, 2015 at 17:9 Comment(0)
B
7

Found out that it is Intellij's by-design behaviour after finding one feedback from Jetbrains to an issue request:

Feedback of an issue request from Jetbrains

In other words, the problem is related to how I test out the hotswapping:

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

    //*/
    public static void main(String[] args) {
        System.out.println("Hello " + getName()); // <=== (1)
    }
}
  1. As Intellij's behaviour is that "the old code is still used until the VM exits the obsolete stack frame" (a different behaviour comparing to Eclipse), if you change "Hello" to "Bye" at (1), the new code will never be executed - the new code can be executed again only when main() is called the second time, which is impossible as the application is terminated already

  2. If it is (2) that is changed (say, replacing "James" w/ "Sean") instead of (1), during the time when the execution cursor is being stopped by a breakpoint placed at (1) (therefore haven't entered to getName() yet), and you reload the class, you will get the new code being run (printing "Sean")

DCEVM worked perfectly too, using the same way to test the hotswapping

You can also use "drop frame" in the stack trace window to make the current statement roll back to the method's beginning (except main()) - in fact it's the same behaviour in Eclipse.

Brigidabrigit answered 13/9, 2015 at 12:18 Comment(1)
Eclipse (as far as I remember) drops the necessary frames to get out of the obsolete code.Calcifuge

© 2022 - 2024 — McMap. All rights reserved.