Debug info not updated when code dynamically re-loaded
Apache NetBeans version
Apache NetBeans 15
What happened
Rather than compiling code and then running it, my system compiles, dynamically loads, and then runs code all at runtime. The benefit of this is that code can be changed at runtime on a live system without having to compile or re-boot a production server. This is something I have been using for years in production environments. It works well. The actual source code for this is at https://github.com/blakemcbride/Kiss
Previously, I used IntelliJ. Debugging this code in a live environment and changing it dynamically worked as expected. However, NetBeans doesn't seem to update its debug info when I dynamically change code. The first time I execute the code, NetBeans debugs fine. However, after I change the code, NetBeans seems to have its line numbers off. So, the new code is executing, but NetBeans is using debug info from the original load.
Again, this is production code that has been working perfectly for years. With IntelliJ, I have been able to debug updated code without a problem. And there has never been a problem in production. When I update a file, the new code gets executed just fine.
I created two videos that demonstrate the problem. The first video shows code that is dynamically loaded. It debugs just fine. The second video shows the same debug session but after the code has been changed and re-loaded. You can see that NetBeans is using the wrong line number information. Here are links to the two videos.
https://private.stack360.io/files/debug-1.mkv https://private.stack360.io/files/debug-2.mkv
(Please let me know if you need a different movie file type.)
How to reproduce
No response
Did this work correctly in an earlier version?
No / Don't know
Operating System
Fedora Linux
JDK
17
Apache NetBeans packaging
Apache NetBeans binary zip
Anything else
Although my example and use is with Groovy code. I am very inclined to believe that this same issue would occur with Java code as well because, in essence, it is just a dynamic re-load of a class into the JVM.
Are you willing to submit a pull request?
No
Code of Conduct
Yes
I can assure you that the dynamic class reloading for debugging is working in Java projects. Just tested, it works with Groovy as well (though I could imagine, that there are limitations) I have to mention that I've tested this with Gradle projects which probably is the best project type for Groovy support in NetBeans.
You can assure me? Have you seen my videos? Clearly, it's not working.
I remind you that I have debugged this code with IntelliJ for many years without a problem. So, the difference between these two scenarios is NetBeans.
Also, this is not some wacky test project. This is a large system that has been in production for more than ten years.
If you like, I can create a smallish open-source program to demonstrate the problem.
Also, you can't test this with a typical Gradle project because Gradle compiles the code before it gets executed. I'm not doing that, as I've explained.
If you like, I can create a smallish open-source program to demonstrate the problem.
That would be extremely HELPFUL! My professional experience has taught me a small reproducible test case goes a very long ways to helping with fixing/diagnosing a problem.
Then maybe others, like me, can get more involved.
The test program is at https://private.stack360.io/files/Test.zip
In it, there is a file named README.txt that has the instructions.
Thank you!
I just updated Test.zip with a few corrections to the README.txt file.
I updated it again to include the NetBeans project files.
I see what you mean! I think so far the debug info loading happened in one direction IDE -> APP, or in the first use IDE <- APP, but after the first IDA <- APP sync the IDE never syncs the debug info back from the APP.
Exactly. Thank you!
That system also dynamically loads Java. I tested it. The problem exists in Java too. So, this is not a Groovy problem.
I develop a dynamic reloading system myself, although I've never used the debugger with it - partly because the dynamic source code doesn't exist in files on disk either.
A question would be how you're doing reload? I haven't looked at your system. But in terms of Java at least do you use HotSwap or dynamic classloaders? Because there could be a 1-to-1 vs 1-to-many mapping between source and class to consider too.
When I load a new version, I remove all references to the old class. So there is only one loaded at a time.
If memory serves, Groovy has the ability to dynamically compile and load files built-in. For Java, I use https://github.com/dvare/dynamic-loader
I am interested in funding a project to correct this problem. If interested, please contact me. Blake McBride [email protected]
I'm aware of dynamic-loader - it's similar, although simpler, to how PraxisCORE works. Feel free to contact me (company info on my GitHub profile). It might be something I can take a look at.
Neil was unable to help me, so this is still an open project.
Incidentally, I noticed that not only does IntelliJ handle this situation correctly, but so does eclipse. So, the only major IDE that doesn't is NetBeans.