The slow Death of the onjcmd Debugger Feature

Almost to the day, a year ago, I published my blog post called Level-up your Java Debugging Skills with on-demand Debugging. In this blog post, I wrote about multiple rarely known and rarely used features of the Java debugging agent, including the onjcmd feature. To quote my own blog post:

JCmd triggered debugging

There are often cases where the code that you want to debug is executed later in your program’s run or after a specific issue appears. So don’t waste time running the debugging session from the start of your program, but use the onjcmd=y option to tell the JDWP agent to wait with the debugging session till it is triggered via jcmd.

A similar feature long existed in the SAPJVM. In 2019 Christoph Langer from SAP decided to add it to the OpenJDK, where it was implemented in JDK 12 and has been there ever since.

The alternative to using this feature is to start the debugging session at the beginning and only connect to the JDWP agent when you want to start debugging. But this was, for a time, significantly slower than using the onjcmd feature (source):

After the feature had been merged, it was decided that it needed a CSR because it was user-facing. But the feature wasn’t it without its opponents, and the CSR was only accepted because the feature had already been merged:

After consultation with others including Alan Bateman and Mark Reinhold, I’ve concluded there is lack of technical consensus on this appropriateness of the feature in its current state to the platform.

As noted in the CSR FAQ (https://wiki.openjdk.java.net/display/csr/CSR+FAQs):

“In exceptional circumstances, the need for a CSR review may be recognized only after a push has already occurred. In such cases, a retroactive CSR review can be conducted. The results of such a retroactive review may require updates to the change, up to and including complete removal of the change.”

Administratively, I’m retroactively voting to approve this CSR as it has already been pushed in JDK 12; however, given the lack of consensus, I’ve filed the follow-up bug JDK-8226608 to:

  • hide the onjcmd option from the help output
  • explore hiding “VM.start_java_debugging” from the “jcmd help”

This bug needs to be addressed before JDK 13 ramdown 2.

JOE Darcy in His Comment to THE CSR

So, it was decided to remove it with JDK-8226608, as Joe Darcy mentions in his comment with the CSR JDK-8227078:

Summary

Hide the onjcmd option of the jdwp agent and the corresponding VM.start_java_debugging command, without removing the functionality outright.

Problem

According to JDK-8223456 the onjcmd option and the corresponding diagnostic command should be hidden as far as possible.

Solution

The onjcmd option is not mentioned in the help output of the JDWP agent anymore. The corresponding diagnostic command VM.start_java_debugging is now registered as hidden, so it would not be included in the list of supported commands by jcmd or via the mbeans.

Apart from that the functionality is still working.

This is probably one of the major reasons nobody wrote about it: nobody outside the SAP, the few people involved in its inception, and the JDWP agent knew about it. If you search the internet for the onjcmd feature, you will likely only encounter blog posts from this very blog (and its various cross-posts).

So this feature was a hidden gem for a while, but as discussed in my blog post Is JDWP’s onjcmd feature worth using?, this feature is not worth using anymore:

Between JDK 11.0.3 and JDK 21, there have been improvements to the OpenJDK, some of which drastically improved the performance of the JVM in debugging mode. Most notable is the fix for JDK-8227269 by Roman Kennke. […]

This clearly shows the significant impact of the change. 11.0.3 came out on Apr 18, 2019, and 11.0.9 on Jul 15, 2020, so the onjcmd improved on-demand debugging for almost a year.

So, the feature has been hidden and has offered no benefits since mid-2020. It’s just sitting in the OpenJDK, likely unused and unknown by most developers. The last thing to do is remove the feature. For this, I created the CSR with the help of Christoph:

Summary

Remove the onjcmd option from the jdwp agent, because it is considered obsolete and unused.

Problem

[…]

However, it is not needed anymore, as the performance issue has been fixed, and the networking/open port topic can easily be handled by infrastructure. Furthermore, the option is rarely used due to being hidden via JDK-8227078. So, we should remove the feature along with its coding to reduce complexity.

Solution

Remove the onjcmd option from the JDWP agent and eliminate the corresponding VM.start_java_debugging command in the JVM. This will clean up the agent code and remove obsolete functionality that is no longer needed or used.

For such CSRs, one also needs to state the compatibility risks. As explained before, there are possibly none outside of SAP. Together with my related PR, this will remove the feature from the OpenJDK, and JDK 24 will most probably be the first JDK since JDK 12 without the onjcmd debugger feature. RIP.

Conclusion

In this week’s blog post, we saw the life cycle of the onjcmd feature, from its inception to its removal. As software developers, we shouldn’t be too afraid to remove features we or our teams implemented. Every unused removed feature is a good feature. Large projects, like the OpenJDK, tend to collect lots of features that were great years ago but fell out of use and clog the source code. In my opinion, this also includes other JDWP agent features like onthrow. To be slightly more controversial, why not start deprecating the UI stack and moving it into a separate project like JFX?

But what do you think? Do you have a use for onjcmd and will miss it? Whatever your opinion is, I hope you liked my blog post. See you in my next blog post.

This article is part of my work in the SapMachine team at SAP, making profiling and debugging easier for everyone. Thank you to Christopher Langer and Cris Plummer for the help with the CSR, and the PR.

P.S: Stuart Marks, aka Dr. Deprecator, likes the removal of unused features. I managed to meet him at Devoxx Belgium this week:

Author

  • Johannes Bechberger

    Johannes Bechberger is a JVM developer working on profilers and their underlying technology in the SapMachine team at SAP. This includes improvements to async-profiler and its ecosystem, a website to view the different JFR event types, and improvements to the FirefoxProfiler, making it usable in the Java world. He started at SAP in 2022 after two years of research studies at the KIT in the field of Java security analyses. His work today is comprised of many open-source contributions and his blog, where he writes regularly on in-depth profiling and debugging topics, and of working on his JEP Candidate 435 to add a new profiling API to the OpenJDK.

    View all posts

New posts like these come out at least every two weeks, to get notified about new posts, follow me on Twitter, Mastodon, or LinkedIn, or join the newsletter:

Leave a Reply

Your email address will not be published. Required fields are marked *