Skip to content

Commit

Permalink
8080: Add support for enabling jfr on native images
Browse files Browse the repository at this point in the history
Co-authored-by: Robert Toyonaga <[email protected]>
Reviewed-by: clanger, bdutheil
  • Loading branch information
aptmac and Robert Toyonaga committed Jun 20, 2023
1 parent cf2fe2b commit 145050d
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -104,14 +104,21 @@ public String getVersion() {
}

private boolean isDynamicFlightRecorderSupported(IConnectionHandle handle) {
if (ConnectionToolkit.isSubstrateVM(handle)) {
// JFR may not have been built into the native image. Check that FlightRecorderMXBean is accessible from the MBean server.
return isAvailable(handle);
}
// All OpenJDK versions of JFR support dynamic enablement of JFR, so if there are no commercial features in play
// all is A-OK.
return !cfs.hasCommercialFeatures() || (ConnectionToolkit.isHotSpot(handle)
&& ConnectionToolkit.isJavaVersionAboveOrEqual(handle, JavaVersionSupport.DYNAMIC_JFR_SUPPORTED));
}

private boolean isFlightRecorderDisabled(IConnectionHandle handle) {
if (cfs != null && cfs.hasCommercialFeatures()) {
if (ConnectionToolkit.isSubstrateVM(handle)) {
// For native image, commercial features may be available but disabled while JFR is still enabled
return !isAvailable(handle);
} else if (cfs != null && cfs.hasCommercialFeatures()) {
return !cfs.isCommercialFeaturesEnabled() || JVMSupportToolkit.isFlightRecorderDisabled(handle, false);
} else {
return JVMSupportToolkit.isFlightRecorderDisabled(handle, false);
Expand All @@ -128,7 +135,7 @@ public FlightRecorderServiceV2(IConnectionHandle handle) throws ConnectionExcept
if (!isDynamicFlightRecorderSupported(handle) && isFlightRecorderDisabled(handle)) {
throw new ServiceNotAvailableException(""); //$NON-NLS-1$
}
if (JVMSupportToolkit.isFlightRecorderDisabled(handle, true)) {
if (!ConnectionToolkit.isSubstrateVM(handle) && JVMSupportToolkit.isFlightRecorderDisabled(handle, true)) {
throw new ServiceNotAvailableException(""); //$NON-NLS-1$
}
connection = handle;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,20 @@ public static boolean isHotSpot(IConnectionHandle connectionHandle) {
return vmName != null && JavaVMVersionToolkit.isHotspotJVMName(vmName);
}

/**
* Returns {@code true} if the connection handle is connected to a Substrate VM, {@code false}
* otherwise. This method requires the connection handle to be connected.
*
* @param connectionHandle
* the connection handle to check.
* @return {@code true} if the connection handle is connected to a Substrate VM, {@code false}
* otherwise.
*/
public static boolean isSubstrateVM(IConnectionHandle connectionHandle) {
String vmName = getVMName(connectionHandle);
return vmName != null && JavaVMVersionToolkit.isSubstrateVMName(vmName);
}

/**
* Returns {@code true} if the connection handle is associated with an Oracle built JVM,
* {@code false} otherwise. If the information is already present in the {@link JVMDescriptor},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
package org.openjdk.jmc.rjmx;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;

import org.openjdk.jmc.common.jvm.JVMDescriptor;
import org.openjdk.jmc.common.jvm.JVMType;
Expand All @@ -47,6 +48,8 @@
*/
public final class JVMSupportToolkit {

private final static String JFR_MBEAN_OBJECT_NAME = "jdk.management.jfr:type=FlightRecorder"; //$NON-NLS-1$

private JVMSupportToolkit() {
throw new IllegalArgumentException("Don't instantiate this toolkit"); //$NON-NLS-1$
}
Expand All @@ -66,7 +69,7 @@ public static String[] checkConsoleSupport(IConnectionHandle connection) {
if (ConnectionToolkit.isJRockit(connection)) {
title = Messages.JVMSupport_TITLE_JROCKIT_NOT_SUPPORTED;
message = Messages.JVMSupport_MESSAGE_JROCKIT_NOT_SUPPORTED;
} else if (!ConnectionToolkit.isHotSpot(connection)) {
} else if (!ConnectionToolkit.isHotSpot(connection) && !ConnectionToolkit.isSubstrateVM(connection)) {
title = Messages.JVMSupport_TITLE_UNKNOWN_JVM;
message = Messages.JVMSupport_MESSAGE_UNKNOWN_JVM;
} else if (!ConnectionToolkit.isJavaVersionAboveOrEqual(connection,
Expand Down Expand Up @@ -98,8 +101,12 @@ public static boolean hasFlightRecorder(IConnectionHandle connection) {
}
MBeanServerConnection server = connection.getServiceOrNull(MBeanServerConnection.class);
try {
HotspotManagementToolkit.getVMOption(server, "FlightRecorder");
return true;
if (ConnectionToolkit.isSubstrateVM(connection)) {
return server.isRegistered(new ObjectName(JFR_MBEAN_OBJECT_NAME));
} else {
HotspotManagementToolkit.getVMOption(server, "FlightRecorder");
return true;
}
} catch (Exception e) { // RuntimeMBeanException thrown if FlightRecorder is not present
return false;
}
Expand Down Expand Up @@ -179,6 +186,9 @@ public static String checkFlightRecorderSupport(IServerHandle handle, boolean sh
if (jvmInfo.getJvmType() == JVMType.UNKNOWN) {
return null;
}
if (jvmInfo.getJvmType() == JVMType.SUBSTRATE) {
return null;
}
if (jvmInfo.getJvmType() != JVMType.HOTSPOT) {
return getJfrNonHotSpotNotSupported(shortMessage);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,10 @@
public class JVMSupportToolkitTest {
private static final String NAME_OPEN_JDK = "OpenJDK 64-Bit Server VM";
private static final String NAME_ORACLE = "Java HotSpot(TM) 64-Bit Server VM";
private static final String NAME_SUBSTRATE = "Substrate VM";
private static final String VENDOR_OPEN_JDK = "Oracle Corporation";
private static final String VENDOR_ORACLE = "Oracle Corporation";
private static final String VENDOR_GRAAL = "GraalVM Community";
// FIXME: Add tests for the methods that take IConnectionHandle as a parameter.

private static final String SUPPORTED_MESSAGE = null;
Expand Down Expand Up @@ -161,4 +163,15 @@ public void testJdk7HotSpotOpenJDKNotSupported() {
String errorMessage = JVMSupportToolkit.checkFlightRecorderSupport(server, false);
assertNotNull(errorMessage);
}

@Test
public void testSubstrateVMSupported() {
ServerHandle server = new ServerHandle(
new ServerDescriptor(null, null,
new JVMDescriptor("20", JVMType.SUBSTRATE, JVMArch.UNKNOWN, null, null, NAME_SUBSTRATE,
VENDOR_GRAAL, null, false, null)),
new ConnectionDescriptorBuilder().hostName("localhost").port(0).build(), null);
String errorMessage = JVMSupportToolkit.checkFlightRecorderSupport(server, false);
assertEquals(SUPPORTED_MESSAGE, errorMessage);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ public enum JVMType {
* The JVM is Hotspot.
*/
HOTSPOT,
/**
* The JVM is Substrate VM.
*/
SUBSTRATE,
/**
* The JVM is unknown.
*/
Expand All @@ -67,6 +71,8 @@ public static JVMType getJVMType(String jvmName) {
return JVMType.JROCKIT;
} else if (JavaVMVersionToolkit.isHotspotJVMName(jvmName)) {
return JVMType.HOTSPOT;
} else if (JavaVMVersionToolkit.isSubstrateVMName(jvmName)) {
return JVMType.SUBSTRATE;
}
return JVMType.OTHER;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2020, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -91,8 +91,8 @@ private static boolean isNumber(String string) {
*
* @param vmName
* the JVM name to check.
* @return {@code true} of it is a JRockit, {@code false} if it isn't or if was not possible to
* tell.
* @return {@code true} if it is a JRockit, {@code false} if it isn't or if it was not possible
* to tell.
*/
public static boolean isJRockitJVMName(String vmName) {
if (vmName == null) {
Expand All @@ -106,8 +106,8 @@ public static boolean isJRockitJVMName(String vmName) {
*
* @param vmName
* the JVM name to check.
* @return {@code true} if it is a HotSpot, {@code false} if it isn't or if was not possible to
* tell.
* @return {@code true} if it is a HotSpot, {@code false} if it isn't or if it was not possible
* to tell.
*/
public static boolean isHotspotJVMName(String vmName) {
if (vmName == null) {
Expand All @@ -116,13 +116,28 @@ public static boolean isHotspotJVMName(String vmName) {
return vmName.startsWith("Java HotSpot") || isOpenJDKJVMName(vmName) || vmName.startsWith("SAP"); //$NON-NLS-1$ //$NON-NLS-2$;
}

/**
* Returns whether this is a Substrate VM or not.
*
* @param vmName
* the VM name to check.
* @return {@code true} if it is a Substrate VM, {@code false} if it isn't or if if was not
* possible to tell.
*/
public static boolean isSubstrateVMName(String vmName) {
if (vmName == null) {
return false;
}
return vmName.startsWith("Substrate VM"); //$NON-NLS-1$
}

/**
* Returns whether this is a OpenJDK JVM or not.
*
* @param vmName
* the JVM name to check.
* @return {@code true} if it is a OpenJDK JVM, {@code false} if it isn't or if was not possible
* to tell.
* @return {@code true} if it is a OpenJDK JVM, {@code false} if it isn't or if it was not
* possible to tell.
*/
public static boolean isOpenJDKJVMName(String vmName) {
if (vmName == null) {
Expand Down

0 comments on commit 145050d

Please sign in to comment.