I work on debuggers, such as one for Python. My friends who use Eclipse to debug Java tell me that there is a very useful feature that Eclipse (and similar Java IDE's?) called "hot code replace" - if you edit a source file and save it while debugging a method, it will replace the (executing) code and restart the top most method.
I would like to be able to understand at a technical level a little bit about how this works, what the Java Runtime system provides to make this possible, and what restrictions or limitations there are for being able to do this.
For example, @howlger in the comments below informs that it "...only works when the class signature does not change; you cannot remove or add fields to existing classes, for instance."
Are there any other other restrictions?
This is what I could find from wiki.eclipse.org and www.ibm.com, which boil down to not being able to change inner classes, method declarations and fields as well as methods called from native code on-the-fly as well as JSP debugging does not support it and it will not work on the bottom of the stack frame (i.e. the main
method). But their description is much more informed than what I could provide, so here's my findings:
HCR has been specifically added as a standard technique to Java to facilitate experimental development and to foster iterative trial-and-error coding. HCR only works when the class signature does not change; you cannot remove or add fields to existing classes, for instance. However, HCR can be used to change the body of a method. HCR is reliably implemented only on 1.4.1 VMs and later, or using any version of the IBM J9 VM. J9 is available in IBM products such as Websphere Studio Device Developer.
If HCR does not work for you even in a simple Java application and you have confirmed that you are running the application on a supported VM (taking note that the JVM that runs Eclipse may not be the same as the JVM that is running your Java application), you may not have automatic building turned on. Make sure that 'Project > Build Automatically' is checked.
https://wiki.eclipse.org/FAQ_What_is_hot_code_replace%3F
Hot Code Replace requires two things to work:
The VM has to support re-defining a class during debug The debugger must be able to pop the frame that is affected to reload the class that gets re-defined. This is equivalent to the "Drop
to Frame" action from the Debug View.
One of the limitations with "Drop to Frame" is that the user cannot drop to frames to a native method or any stackframes below the native method. This is a limitation imposed by the VM. If you are trying hot code replace on the first stackframe after a native call, it will fail because the debugger cannot pop the frame to the native method and reload the top stackframe.
https://www.ibm.com/support/pages/understanding-one-limitation-hot-code-replace
Drop to frame and Hot code replace: Do not use the drop to frame and hot code replace features while debugging other languages called from Java™.
Changes to source that affect the shape of the class are not supported. This means that changes to method bodies will be hot replaced, while these are examples of changes that will not be hot replaced:
changes to class structure, such as the removal/addition of methods modification of class variables changes to inner classes
If you change the shape of the class by adding or removing a field or method, or as described above, you might receive an error with the message "Scheme change not implemented", as pictured below:
This error indicates that you have performed an unsupported hot code replacement, and the change was not processed by the virtual machine. You might also see an "(out of synch)" message on the stack frames or threads in the debug view. These messages should disappear if you undo the unsupported change. Changes to the code in the bottom stack frame (the main(...) method) cannot be hot replaced. Changes to the code that is directly referenced by native methods cannot be hot replaced. For example, imagine that the debugger is currently suspended in methodA, called from methodB, and you make a change in the body of methodA. The hot code replacement will not succeed if methodB is a native method. You will not be able to replace methods invoked through reflection while you are suspended in these methods. Some examples of methods invoked through reflection, are constructors called through Class.newInstance() and Method.invoke().
If you change the body of a method invoked by native code while the debugger is suspended there, you might see an error dialog titled "Obsolete Methods on the Stack" like the one below:
Continuing the previous example, since methodA has been changed, the original methodA before the change is now obsolete. However, the virtual machine is unable to execute the new methodA because it is called from a native method, and so will continue to use the old, now obsolete contents of methodA. JSP page debugging does not support hot method replace of Java code.
https://www.ibm.com/docs/en/radfws/9.6.1?topic=debugger-java-mixed-language-debug-limitations