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)
Found out that it is Intellij's by-design behaviour after finding one feedback from Jetbrains to an issue request:
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)
}
}
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With