Skip to content

Conversation

@macarte
Copy link
Contributor

@macarte macarte commented Oct 28, 2025

Add jdk.management.AOTCacheMXBean. The interface provides a single action that when called will cause any hosted JVM currently recording AOT information will stop recording. Existing functionality is preserved: when stopped the JVM will create the required artifacts based on the execution mode. Conveniently as the application running on the JVM has not stopped (as was previously the only way to stop recording), the application will resume execution after the artifacts have been generated.

The interface will return TRUE if a recording was successfully stopped, in all other cases (not recording etc.) will return FALSE

It follows that invoking the action on a JVM that is recording, twice in succession, should (baring internal errors) produce the following two responses:

TRUE
FALSE

Passes tier1 on linux (x64) and windows (x64)


Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change requires CSR request JDK-8369737 to be approved

Issues

  • JDK-8369736: Add management interface for AOT cache creation (Enhancement - P3)
  • JDK-8369737: Add management interface for AOT cache creation (CSR)

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/28010/head:pull/28010
$ git checkout pull/28010

Update a local copy of the PR:
$ git checkout pull/28010
$ git pull https://git.openjdk.org/jdk.git pull/28010/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 28010

View PR using the GUI difftool:
$ git pr show -t 28010

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/28010.diff

Using Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Oct 28, 2025

👋 Welcome back macarte! A progress list of the required criteria for merging this PR into pr/27965 will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

openjdk bot commented Oct 28, 2025

❗ This change is not yet ready to be integrated.
See the Progress checklist in the description for automated requirements.

@openjdk
Copy link

openjdk bot commented Oct 28, 2025

@macarte The following labels will be automatically applied to this pull request:

  • hotspot
  • jmx
  • serviceability

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing lists. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added the rfr Pull request is ready for review label Oct 28, 2025
@mlbridge
Copy link

mlbridge bot commented Oct 28, 2025

@openjdk
Copy link

openjdk bot commented Oct 29, 2025

⚠️ @macarte This pull request contains merges that bring in commits not present in the target repository. Since this is not a "merge style" pull request, these changes will be squashed when this pull request in integrated. If this is your intention, then please ignore this message. If you want to preserve the commit structure, you must change the title of this pull request to Merge <project>:<branch> where <project> is the name of another project in the OpenJDK organization (for example Merge jdk:master).

* }
* </pre></blockquote>
*
* @return {@code true} if a recording was in progress and has been ended successfully; {@code false} otherwise.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Someone is bound to ask what happens if the "endRecording" operation is performed concurrently and there is recording in progress. Does one or all return true? I don't think it matters, the bigger issue here is that returning false means the recording has already ended or it failed. If it failed, why did it fail? I realize the intention is to add some properties and further operations to this MXBean but I think it would be good to think through if starting with a boolean returning operation is going to be problematic in the future.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see a couple of cases for when endRecording is called:

  1. Within the same process to generate a cache - given the api will only return true to one caller, that caller is the only one who can be responsible for taking further action (copying the cache somewhere, etc). Already ended or failed makes no difference operationally.

  2. From a monitoring process - again only the successful case matters. All failures (already ended or failed) are indistinguishable. No further action can be taken by the observer. It's only the success case that matters

@egahlin
Copy link
Member

egahlin commented Nov 3, 2025

Can this be done using a diagnostic command, e.g. AOT.stop? It would allow the recording to be stopped from jcmd and the DiagnosticCommandMBean, without the need for a separate MXBean.

@macarte
Copy link
Contributor Author

macarte commented Nov 3, 2025

Can this be done using a diagnostic command, e.g. AOT.stop? It would allow the recording to be stopped from jcmd and the DiagnosticCommandMBean, without the need for a separate MXBean.

Thank you for the suggestion

To answer your first question, we do have a diagnostic command (AOT.end_recording) and it would precede the AOT MXBean into mainline and its PR is here: #27965

The longer goal for this MXBean is to provide additional methods that would aid in monitoring (isRecording, currentRecordingLength etc.), however we decided to reduce the scope of the MXBean for main line while we continue to test the monitoring functionality in leyden/premain

Historically the diagnostic command came after the MXBean in leyden/premain, however I decided to implement the diagnostic command with the necessary JVM hooks first to simplify review

So technically we could delay this PR and still have the required functionality in mainline, I'd like to hear from the other reviewers on this matter

@egahlin
Copy link
Member

egahlin commented Nov 4, 2025

To answer your first question, we do have a diagnostic command (AOT.end_recording) and it would precede the AOT MXBean into mainline and its PR is here: #27965

Ah, I didn't know that.

(I don’t have a strong opinion on this, but for consistency you might want the jcmd commands for AOT recording to use the same naming convention for starting, stopping, and checking the status of a recording as JFR: JFR.start, JFR.stop, JFR.check, JFR.dump and JFR.configure, where applicable. Initially, we had start_recording, but we later shortened it to start to avoid unnecessary typing)

The longer goal for this MXBean is to provide additional methods that would aid in monitoring (isRecording, currentRecordingLength etc.), however we decided to reduce the scope of the MXBean for main line while we continue to test the monitoring functionality in leyden/premain

Historically the diagnostic command came after the MXBean in leyden/premain, however I decided to implement the diagnostic command with the necessary JVM hooks first to simplify review

Ok.

* <p>For more information about creating and using the AOT artifacts, and detailed
* specification of the corresponding JVM command-line options, please refer
* to https://openjdk.org/jeps/483 and https://openjdk.org/jeps/514.
*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use bare URLs. Change these to

... please refer to JEPs <a href="https://openjdk.org/jeps/483">483</a> and
<a href="https://openjdk.org/jeps/514">514</a>.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@openjdk openjdk bot removed the csr Pull request needs approved CSR before integration label Nov 11, 2025
…ke AOT.end_recording"

Commit was intended for parent branch (that this branch is based on)

This reverts commit bff7cb7.
@macarte macarte requested a review from mbreinhold November 13, 2025 18:53
@openjdk openjdk bot removed the rfr Pull request is ready for review label Nov 13, 2025
@openjdk openjdk bot added the rfr Pull request is ready for review label Nov 13, 2025
@AlanBateman
Copy link
Contributor

I went through the plumbing to check the registration with the platform MBeanServer and everything looks okay (and consistent with how the other JDK-specific management interfaces are setup and registered).

* @return {@code true} if a recording was in progress and has been ended
* successfully; {@code false} otherwise.
*/
public boolean endRecording();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nit is that we usually use 4-space rather than 2-space indent in the java sources. You might want to check the /** .. */ comments in a few of the files as they are misaligned in a few places.

* @summary Sanity test for HotSpotAOTCache MXBean
* @requires vm.cds.write.archived.java.heap
* @library /test/jdk/lib/testlibrary /test/lib
* /test/hotspot/jtreg/runtime/cds/appcds/aotCache/test-classes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is test-classes used?

import jdk.test.lib.helpers.ClassFileInstaller;
import jdk.test.lib.process.OutputAnalyzer;

public class HotSpotAOTCacheMXBeanTest {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition to testing the endRecording operation, we also need to test both the direct and indirect access to the MXBean. The test currently obtains a proxy with newPlatformMXBeanProxy (good) but the direct access with ManagementFactory.getPlatformMXBean is not tested right now.

Another thing to test is that getObjectName returns the expected object name.

out.shouldContain("Failed to stop recording");
}
out.shouldNotContain("HotSpotAOTCacheMXBean is not available");
out.shouldNotContain("IOException occurred!");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you considering have the child terminate with an exception so the exit status is non-0. If you get a success status then the output should have the expected strings. A non-0 would failure, and the test fails.

public Map<String, HotSpotAOTCacheMXBean> nameToMBeanMap() {
HotSpotAOTCacheMXBean impl = this.impl;
if (impl == null) {
this.impl = impl = new HotSpotAOTCacheImpl(ManagementFactoryHelper.getVMManagement());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assignment is unusual. Are we trying to avoid a synchronized block? Other nameToMBeanMap() methods are like:
return Collections.singletonMap(ManagementFactory.MEMORY_MXBEAN_NAME, ManagementFactoryHelper.getMemoryMXBean());

..where the ManagementFactoryHelper.getMemoryMXBean() method is synchronized and creates the impl if needed.

Copy link
Contributor

@AlanBateman AlanBateman Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a correctness issue with this. Maybe in the future we will be able to use LazyConstant here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I'm just pointing out that we have a load of existing nameToMBeanMap() methods that do things differently.
OK I now see this one is doing what the new VirtualThreadSchedulerMXBean did.

The others are different: commonly the nameToMBeanMap() methods in PlatformMBeanProviderImpl.java are synchronized, or they call a getXXMXBean() method which is synchronized.

Maybe these old methods don't need to be synchronized, if this all gets done at startup in PlatformMBeanProviderImpl init(), the mbeans will always be created once.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The older code pre-dates unmodifiable maps (JEP 269), it could be modernized some time.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks yes would be good to do that some time.
It looks like an effort with the older accesors to enforce that they are singletons. That may not be important for all the mxbeans.

@openjdk-notifier openjdk-notifier bot changed the base branch from pr/27965 to master November 26, 2025 02:07
@openjdk-notifier
Copy link

The parent pull request that this pull request depends on has now been integrated and the target branch of this pull request has been updated. This means that changes from the dependent pull request can start to show up as belonging to this pull request, which may be confusing for reviewers. To remedy this situation, simply merge the latest changes from the new target branch into this pull request by running commands similar to these in the local repository for your personal fork:

git checkout JDK-8369736
git fetch https://git.openjdk.org/jdk.git master
git merge FETCH_HEAD
# if there are conflicts, follow the instructions given by git merge
git commit -m "Merge master"
git push

@openjdk
Copy link

openjdk bot commented Nov 26, 2025

@macarte this pull request can not be integrated into master due to one or more merge conflicts. To resolve these merge conflicts and update this pull request you can run the following commands in the local repository for your personal fork:

git checkout JDK-8369736
git fetch https://git.openjdk.org/jdk.git master
git merge FETCH_HEAD
# resolve conflicts and follow the instructions given by git merge
git commit -m "Merge master"
git push

@openjdk openjdk bot added merge-conflict Pull request has merge conflict with target branch and removed rfr Pull request is ready for review labels Nov 26, 2025
@openjdk openjdk bot removed the merge-conflict Pull request has merge conflict with target branch label Nov 26, 2025
@openjdk openjdk bot added the rfr Pull request is ready for review label Nov 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

7 participants