diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py
index 005ac2ba7d29..c20ab8be1883 100644
--- a/substratevm/mx.substratevm/suite.py
+++ b/substratevm/mx.substratevm/suite.py
@@ -356,9 +356,6 @@
"com.oracle.svm.core.graal.amd64",
"com.oracle.svm.core.graal.aarch64",
],
- "requires" : [
- "jdk.management",
- ],
"requiresConcealed" : {
"jdk.internal.vm.ci" : [
"jdk.vm.ci.code",
@@ -379,9 +376,6 @@
"dependencies": [
"com.oracle.svm.core.graal.amd64",
],
- "requires" : [
- "jdk.management",
- ],
"requiresConcealed" : {
"jdk.internal.vm.ci" : [
"jdk.vm.ci.code",
diff --git a/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/PosixSubstrateOperatingSystemMXBean.java b/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/PosixSubstrateOperatingSystemMXBean.java
deleted file mode 100644
index 4a7888a9bb99..000000000000
--- a/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/PosixSubstrateOperatingSystemMXBean.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2019, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.svm.core.posix;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import org.graalvm.nativeimage.StackValue;
-import org.graalvm.nativeimage.hosted.Feature;
-
-import com.oracle.svm.core.annotate.AutomaticFeature;
-import com.oracle.svm.core.jdk.management.ManagementFeature;
-import com.oracle.svm.core.jdk.management.ManagementSupport;
-import com.oracle.svm.core.jdk.management.SubstrateOperatingSystemMXBean;
-import com.oracle.svm.core.posix.headers.Resource;
-import com.oracle.svm.core.posix.headers.Times;
-import com.oracle.svm.core.posix.headers.Unistd;
-import com.sun.management.UnixOperatingSystemMXBean;
-
-class PosixSubstrateOperatingSystemMXBean extends SubstrateOperatingSystemMXBean implements UnixOperatingSystemMXBean {
-
- /**
- * Returns the CPU time used by the process on which the SVM process is running in nanoseconds.
- * The returned value is of nanoseconds precision but not necessarily nanoseconds accuracy. This
- * method returns -1 if the the platform does not support this operation.
- *
- * @return the CPU time used by the process in nanoseconds, or -1 if this operation is
- * not supported.
- */
- @Override
- public long getProcessCpuTime() {
- long clkTck = Unistd.sysconf(Unistd._SC_CLK_TCK());
- if (clkTck == -1) {
- // sysconf failed - not able to get clock tick
- return -1;
- }
- long nsPerTick = TimeUnit.SECONDS.toNanos(1) / clkTck;
- Times.tms time = StackValue.get(Times.tms.class);
- Times.times(time);
- return (time.tms_utime() + time.tms_stime()) * nsPerTick;
- }
-
- @Override
- public long getMaxFileDescriptorCount() {
- Resource.rlimit rlp = StackValue.get(Resource.rlimit.class);
- if (Resource.getrlimit(Resource.RLIMIT_NOFILE(), rlp) < 0) {
- throwUnchecked(PosixUtils.newIOExceptionWithLastError("getrlimit failed"));
- }
- return rlp.rlim_cur().rawValue();
- }
-
- @Override
- public long getOpenFileDescriptorCount() {
- int maxFileDescriptor = (int) Unistd.sysconf(Unistd._SC_OPEN_MAX());
- long count = 0;
- for (int i = 0; i <= maxFileDescriptor; i++) {
- if (PosixStat.isOpen(i)) {
- count++;
- }
- }
- return count;
- }
-
- @SuppressWarnings("unchecked")
- private static void throwUnchecked(Throwable exception) throws T {
- throw (T) exception;
- }
-}
-
-@AutomaticFeature
-class PosixSubstrateOperatingSystemMXBeanFeature implements Feature {
- @Override
- public List> getRequiredFeatures() {
- return Arrays.asList(ManagementFeature.class);
- }
-
- @Override
- public void afterRegistration(Feature.AfterRegistrationAccess access) {
- ManagementSupport.getSingleton().addPlatformManagedObjectSingleton(UnixOperatingSystemMXBean.class, new PosixSubstrateOperatingSystemMXBean());
- }
-}
diff --git a/substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsSubstrateOperatingSystemMXBean.java b/substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsSubstrateOperatingSystemMXBean.java
deleted file mode 100644
index 04281f9fd0df..000000000000
--- a/substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsSubstrateOperatingSystemMXBean.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2019, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.svm.core.windows;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.graalvm.nativeimage.Platform;
-import org.graalvm.nativeimage.Platforms;
-import org.graalvm.nativeimage.hosted.Feature;
-
-import com.oracle.svm.core.annotate.AutomaticFeature;
-import com.oracle.svm.core.jdk.management.ManagementFeature;
-import com.oracle.svm.core.jdk.management.ManagementSupport;
-import com.oracle.svm.core.jdk.management.SubstrateOperatingSystemMXBean;
-
-class WindowsSubstrateOperatingSystemMXBean extends SubstrateOperatingSystemMXBean {
-
-}
-
-@Platforms(Platform.WINDOWS.class)
-@AutomaticFeature
-class WindowsSubstrateOperatingSystemMXBeanFeature implements Feature {
- @Override
- public List> getRequiredFeatures() {
- return Arrays.asList(ManagementFeature.class);
- }
-
- @Override
- public void afterRegistration(Feature.AfterRegistrationAccess access) {
- ManagementSupport.getSingleton().addPlatformManagedObjectSingleton(com.sun.management.OperatingSystemMXBean.class, new WindowsSubstrateOperatingSystemMXBean());
- }
-}
diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/LibManagementExtSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/LibManagementExtSupport.java
new file mode 100644
index 000000000000..01d6c659ce4b
--- /dev/null
+++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/LibManagementExtSupport.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.svm.core.jdk.management;
+
+import static com.oracle.svm.core.c.function.CEntryPointOptions.NoEpilogue;
+import static com.oracle.svm.core.c.function.CEntryPointOptions.NoPrologue;
+import static com.oracle.svm.core.c.function.CEntryPointOptions.Publish;
+import static org.graalvm.nativeimage.c.function.CFunction.Transition.NO_TRANSITION;
+
+import org.graalvm.nativeimage.IsolateThread;
+import org.graalvm.nativeimage.StackValue;
+import org.graalvm.nativeimage.c.function.CEntryPoint;
+import org.graalvm.nativeimage.c.function.CFunction;
+import org.graalvm.nativeimage.c.function.CLibrary;
+import org.graalvm.nativeimage.c.type.CCharPointer;
+import org.graalvm.word.UnsignedWord;
+import org.graalvm.word.WordFactory;
+
+import com.oracle.svm.core.annotate.Uninterruptible;
+import com.oracle.svm.core.c.CGlobalData;
+import com.oracle.svm.core.c.CGlobalDataFactory;
+import com.oracle.svm.core.c.function.CEntryPointOptions;
+import com.oracle.svm.core.headers.LibC;
+
+public final class LibManagementExtSupport {
+ private static final CGlobalData ERRMSG_FORMAT = CGlobalDataFactory.createCString("errno: %d error: %s\n");
+
+ /**
+ * Reimplementation of the native {@code throw_internal_error} function in Java.
+ */
+ @Uninterruptible(reason = "No Java context.")
+ @CEntryPoint(name = "throw_internal_error", include = CEntryPoint.NotIncludedAutomatically.class)
+ @CEntryPointOptions(prologue = NoPrologue.class, epilogue = NoEpilogue.class, publishAs = Publish.SymbolOnly)
+ private static void throwInternalError(IsolateThread env, CCharPointer msg) {
+ /*
+ * Ported from `src/jdk.management/share/native/libmanagement_ext/management_ext.c`.
+ */
+ CCharPointer errmsg = StackValue.get(128);
+
+ snprintf(errmsg, WordFactory.unsigned(128), ERRMSG_FORMAT.get(), LibC.errno(), msg);
+ jnuThrowInternalError(env, errmsg);
+ }
+
+ @CFunction(transition = NO_TRANSITION)
+ private static native int snprintf(CCharPointer str, UnsignedWord size, CCharPointer format, int errno, CCharPointer msg);
+
+ @CLibrary(value = "java", requireStatic = true)
+ @CFunction(value = "JNU_ThrowInternalError", transition = NO_TRANSITION)
+ private static native void jnuThrowInternalError(IsolateThread env, CCharPointer msg);
+}
diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/ManagementSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/ManagementSupport.java
index 07bd12ccd2ec..d6de16d1bd68 100644
--- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/ManagementSupport.java
+++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/ManagementSupport.java
@@ -25,6 +25,7 @@
package com.oracle.svm.core.jdk.management;
import java.lang.management.ManagementFactory;
+import java.lang.management.OperatingSystemMXBean;
import java.lang.management.PlatformManagedObject;
import java.util.ArrayList;
import java.util.Collections;
@@ -33,6 +34,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.function.Supplier;
import javax.management.DynamicMBean;
import javax.management.JMException;
@@ -48,10 +50,13 @@
import org.graalvm.nativeimage.IsolateThread;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;
+import org.graalvm.nativeimage.impl.InternalPlatform;
+import com.oracle.svm.core.SubstrateUtil;
import com.oracle.svm.core.annotate.Uninterruptible;
import com.oracle.svm.core.thread.ThreadListener;
import com.oracle.svm.core.util.UserError;
+import com.oracle.svm.core.util.VMError;
import com.sun.jmx.mbeanserver.MXBeanLookup;
/**
@@ -60,15 +65,14 @@
* parts: The beans (implementations of {@link PlatformManagedObject}) themselves; and the singleton
* {@link ManagementFactory#getPlatformMBeanServer() MBean server}.
*
- * Support for {@link PlatformManagedObject}: All MXBean that provide VM introspection are allocated
- * eagerly at image build time, and stored in {@link #platformManagedObjectsMap} as well as
- * {@link #platformManagedObjectsSet}. The registration is decentralized: while some general beans
- * are registered in this class, the OS specific and GC specific beans are registered in the
- * respective OS or GC code. To find all registrations, look for the usages of
- * {@link #addPlatformManagedObjectSingleton} and {@link #addPlatformManagedObjectList}. Eager
- * allocation of all the beans avoids the complicated registry that the JDK maintains for lazy
- * loading (the code in PlatformComponent - note that this code and even the package of the class is
- * significantly different between JDK 8 and JDK 11).
+ * Support for {@link PlatformManagedObject}: All MXBean that provide VM introspection are
+ * registered (but not necessarily allocated) eagerly at image build time, and stored in
+ * {@link #platformManagedObjectsMap} as well as {@link #platformManagedObjectsSet}. The
+ * registration is decentralized: while some general beans are registered in this class, the GC
+ * specific beans are registered in the respective GC code. To find all registrations, look for the
+ * usages of {@link #addPlatformManagedObjectSingleton} and {@link #addPlatformManagedObjectList}.
+ * Eager registration of all the beans avoids the complicated registry that the JDK maintains for
+ * lazy loading (the code in PlatformComponent).
*
* Support for {@link ManagementFactory#getPlatformMBeanServer()}: The {@link MBeanServer} that
* makes all MXBean available too is allocated lazily at run time. This has advantages and
@@ -113,6 +117,9 @@ public final class ManagementSupport implements ThreadListener {
private final SubstrateRuntimeMXBean runtimeMXBean;
private final SubstrateThreadMXBean threadMXBean;
+ /* Initialized lazily at run time. */
+ private OperatingSystemMXBean osMXBean;
+
/** The singleton MBean server for the platform, initialized lazily at run time. */
MBeanServer platformMBeanServer;
@@ -128,7 +135,7 @@ public final class ManagementSupport implements ThreadListener {
/*
* Register the platform objects defined in this package. Note that more platform objects
- * are registered in OS and GC specific code.
+ * are registered in GC specific code.
*/
addPlatformManagedObjectSingleton(java.lang.management.ClassLoadingMXBean.class, classLoadingMXBean);
addPlatformManagedObjectSingleton(java.lang.management.CompilationMXBean.class, compilationMXBean);
@@ -140,6 +147,30 @@ public final class ManagementSupport implements ThreadListener {
*/
addPlatformManagedObjectList(java.lang.management.MemoryPoolMXBean.class, Collections.emptyList());
addPlatformManagedObjectList(java.lang.management.BufferPoolMXBean.class, Collections.emptyList());
+ /*
+ * Register the platform object for the OS using a supplier that lazily initializes it at
+ * run time.
+ */
+ doAddPlatformManagedObjectSingleton(getOsMXBeanInterface(), (PlatformManagedObjectSupplier) this::getOsMXBean);
+ }
+
+ private static Class> getOsMXBeanInterface() {
+ if (Platform.includedIn(InternalPlatform.PLATFORM_JNI.class)) {
+ return Platform.includedIn(Platform.WINDOWS.class)
+ ? com.sun.management.OperatingSystemMXBean.class
+ : com.sun.management.UnixOperatingSystemMXBean.class;
+ }
+ return java.lang.management.OperatingSystemMXBean.class;
+ }
+
+ private synchronized OperatingSystemMXBean getOsMXBean() {
+ if (osMXBean == null) {
+ Object osMXBeanImpl = Platform.includedIn(InternalPlatform.PLATFORM_JNI.class)
+ ? new Target_com_sun_management_internal_OperatingSystemImpl(null)
+ : new Target_sun_management_BaseOperatingSystemImpl(null);
+ osMXBean = SubstrateUtil.cast(osMXBeanImpl, OperatingSystemMXBean.class);
+ }
+ return osMXBean;
}
@Fold
@@ -251,7 +282,7 @@ synchronized MBeanServer getPlatformMBeanServer() {
/* Modified version of JDK 11: ManagementFactory.getPlatformMBeanServer */
platformMBeanServer = MBeanServerFactory.createMBeanServer();
for (PlatformManagedObject platformManagedObject : platformManagedObjectsSet) {
- addMXBean(platformMBeanServer, platformManagedObject);
+ addMXBean(platformMBeanServer, handleLazyPlatformManagedObjectSingleton(platformManagedObject));
}
}
return platformMBeanServer;
@@ -287,7 +318,7 @@ T getPlatformMXBean(Class mxbeanInterface)
} else if (result instanceof List) {
throw new IllegalArgumentException(mxbeanInterface.getName() + " can have more than one instance");
}
- return mxbeanInterface.cast(result);
+ return mxbeanInterface.cast(handleLazyPlatformManagedObjectSingleton(result));
}
@SuppressWarnings("unchecked")
@@ -299,7 +330,33 @@ List getPlatformMXBeans(Class mxbeanInte
if (result instanceof List) {
return (List) result;
} else {
- return Collections.singletonList(mxbeanInterface.cast(result));
+ return Collections.singletonList(mxbeanInterface.cast(handleLazyPlatformManagedObjectSingleton(result)));
}
}
+
+ /**
+ * A {@link PlatformManagedObject} supplier that is itself a {@link PlatformManagedObject} for
+ * easier integration with the rest of the {@link ManagementSupport} machinery.
+ *
+ * This in particular allows for transparent storage in {@link #platformManagedObjectsMap} and
+ * {@link #platformManagedObjectsSet} at the expense of
+ * {@linkplain #handleLazyPlatformManagedObjectSingleton special handling} when retrieving
+ * stored platform objects.
+ */
+ private interface PlatformManagedObjectSupplier extends Supplier, PlatformManagedObject {
+ @Override
+ default ObjectName getObjectName() {
+ throw VMError.shouldNotReachHere();
+ }
+ }
+
+ /**
+ * Provides {@link PlatformManagedObjectSupplier} handling when retrieving singleton platform
+ * objects from {@link #platformManagedObjectsMap} and {@link #platformManagedObjectsSet}.
+ */
+ private static PlatformManagedObject handleLazyPlatformManagedObjectSingleton(Object object) {
+ assert object instanceof PlatformManagedObject;
+ return object instanceof PlatformManagedObjectSupplier ? ((PlatformManagedObjectSupplier) object).get()
+ : (PlatformManagedObject) object;
+ }
}
diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/SubstrateOperatingSystemMXBean.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/SubstrateOperatingSystemMXBean.java
deleted file mode 100644
index 94cd58acdb5a..000000000000
--- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/SubstrateOperatingSystemMXBean.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 2019, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.svm.core.jdk.management;
-
-import java.lang.management.ManagementFactory;
-
-import javax.management.ObjectName;
-
-import org.graalvm.nativeimage.Platform;
-import org.graalvm.nativeimage.Platforms;
-
-import com.oracle.svm.core.SubstrateUtil;
-import com.oracle.svm.core.heap.PhysicalMemory;
-import com.oracle.svm.core.util.VMError;
-
-import sun.management.Util;
-
-public abstract class SubstrateOperatingSystemMXBean extends SubstrateOperatingSystemMXBeanBase implements com.sun.management.OperatingSystemMXBean {
-
- @Platforms(Platform.HOSTED_ONLY.class)
- protected SubstrateOperatingSystemMXBean() {
- }
-
- @Override
- public ObjectName getObjectName() {
- return Util.newObjectName(ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME);
- }
-
- @Override
- public String getName() {
- return System.getProperty("os.name");
- }
-
- @Override
- public String getArch() {
- return SubstrateUtil.getArchitectureName();
- }
-
- @Override
- public String getVersion() {
- return System.getProperty("os.version");
- }
-
- @Override
- public int getAvailableProcessors() {
- return Runtime.getRuntime().availableProcessors();
- }
-
- @SuppressWarnings("deprecation") // getTotalPhysicalMemorySize is deprecated after JDK 11
- @Override
- public long getTotalPhysicalMemorySize() {
- return PhysicalMemory.size().rawValue();
- }
-
- @Override
- public double getSystemLoadAverage() {
- return -1;
- }
-
- @Override
- public long getCommittedVirtualMemorySize() {
- throw VMError.unsupportedFeature(MSG);
- }
-
- @Override
- public long getTotalSwapSpaceSize() {
- throw VMError.unsupportedFeature(MSG);
- }
-
- @Override
- public long getFreeSwapSpaceSize() {
- throw VMError.unsupportedFeature(MSG);
- }
-
- @Override
- public long getProcessCpuTime() {
- throw VMError.unsupportedFeature(MSG);
- }
-
- @SuppressWarnings("deprecation") // getFreePhysicalMemorySize is deprecated after JDK 11
- @Override
- public long getFreePhysicalMemorySize() {
- throw VMError.unsupportedFeature(MSG);
- }
-
- @SuppressWarnings("deprecation") // getSystemCpuLoad is deprecated after JDK 11
- @Override
- public double getSystemCpuLoad() {
- throw VMError.unsupportedFeature(MSG);
- }
-
- @Override
- public double getProcessCpuLoad() {
- throw VMError.unsupportedFeature(MSG);
- }
-}
diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/SubstrateOperatingSystemMXBeanBase.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/Target_com_sun_management_internal_OperatingSystemImpl.java
similarity index 58%
rename from substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/SubstrateOperatingSystemMXBeanBase.java
rename to substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/Target_com_sun_management_internal_OperatingSystemImpl.java
index dab9ceccd728..dc8dc4999f24 100644
--- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/SubstrateOperatingSystemMXBeanBase.java
+++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/Target_com_sun_management_internal_OperatingSystemImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,29 +24,17 @@
*/
package com.oracle.svm.core.jdk.management;
-import com.oracle.svm.core.util.VMError;
+import com.oracle.svm.core.SubstrateUtil;
+import com.oracle.svm.core.annotate.Substitute;
+import com.oracle.svm.core.annotate.TargetClass;
-/**
- * Base class for defining methods introduced after JDK 11 by JDK-8226575.
- *
- * Putting these in a class that does not implement {@link com.sun.management.OperatingSystemMXBean}
- * avoids javac errors related these methods being annotated by {@link Override}.
- */
-public abstract class SubstrateOperatingSystemMXBeanBase {
- static final String MSG = "OperatingSystemMXBean methods";
-
- // Will be removed after [GR-20166] is implemented.
- public double getCpuLoad() {
- throw VMError.unsupportedFeature(MSG);
- }
-
- public abstract long getTotalPhysicalMemorySize();
-
- public long getTotalMemorySize() {
- return getTotalPhysicalMemorySize();
- }
+import sun.management.VMManagement;
- public long getFreeMemorySize() {
- throw VMError.unsupportedFeature(MSG);
+@TargetClass(className = "com.sun.management.internal.OperatingSystemImpl")
+final class Target_com_sun_management_internal_OperatingSystemImpl {
+ @Substitute
+ Target_com_sun_management_internal_OperatingSystemImpl(@SuppressWarnings("unused") VMManagement vm) {
+ /* Workaround until we enable container support (GR-37365). */
+ SubstrateUtil.cast(this, Target_sun_management_BaseOperatingSystemImpl.class).loadavg = new double[1];
}
}
diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/Target_sun_management_BaseOperatingSystemImpl.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/Target_sun_management_BaseOperatingSystemImpl.java
new file mode 100644
index 000000000000..3a934b557cba
--- /dev/null
+++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/management/Target_sun_management_BaseOperatingSystemImpl.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.svm.core.jdk.management;
+
+import com.oracle.svm.core.annotate.Alias;
+import com.oracle.svm.core.annotate.Substitute;
+import com.oracle.svm.core.annotate.TargetClass;
+
+import sun.management.VMManagement;
+
+@SuppressWarnings("static-method")
+@TargetClass(className = "sun.management.BaseOperatingSystemImpl")
+final class Target_sun_management_BaseOperatingSystemImpl {
+ @Alias double[] loadavg;
+
+ @Alias
+ Target_sun_management_BaseOperatingSystemImpl(@SuppressWarnings("unused") VMManagement vm) {
+ }
+
+ @Substitute
+ public double getSystemLoadAverage() {
+ return -1; /* Workaround until we add support for `Unsafe.getLoadAverage` (GR-37414). */
+ }
+
+ /*
+ * The following substitutions eliminate the use of the `BaseOperatingSystemImpl.jvm` field,
+ * which we set to `null` to avoid dealing with `VMManagementImpl` that we do not support.
+ */
+ @Substitute
+ public String getName() {
+ return System.getProperty("os.name");
+ }
+
+ @Substitute
+ public String getArch() {
+ return System.getProperty("os.arch");
+ }
+
+ @Substitute
+ public String getVersion() {
+ return System.getProperty("os.version");
+ }
+
+ @Substitute
+ public int getAvailableProcessors() {
+ return Runtime.getRuntime().availableProcessors();
+ }
+}
diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JNIRegistrationManagementExt.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JNIRegistrationManagementExt.java
new file mode 100644
index 000000000000..512a9493541e
--- /dev/null
+++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JNIRegistrationManagementExt.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.svm.hosted.jdk;
+
+import java.lang.reflect.Method;
+
+import org.graalvm.nativeimage.IsolateThread;
+import org.graalvm.nativeimage.c.type.CCharPointer;
+import org.graalvm.nativeimage.hosted.Feature;
+
+import com.oracle.svm.core.annotate.AutomaticFeature;
+import com.oracle.svm.core.jdk.JNIRegistrationUtil;
+import com.oracle.svm.core.jdk.NativeLibrarySupport;
+import com.oracle.svm.core.jdk.PlatformNativeLibrarySupport;
+import com.oracle.svm.core.jdk.management.LibManagementExtSupport;
+import com.oracle.svm.hosted.FeatureImpl.BeforeAnalysisAccessImpl;
+import com.oracle.svm.hosted.c.NativeLibraries;
+import com.oracle.svm.hosted.code.CEntryPointCallStubSupport;
+import com.oracle.svm.hosted.code.CEntryPointData;
+import com.oracle.svm.util.ReflectionUtil;
+
+@AutomaticFeature
+public class JNIRegistrationManagementExt extends JNIRegistrationUtil implements Feature {
+ private NativeLibraries nativeLibraries;
+
+ @Override
+ public void beforeAnalysis(BeforeAnalysisAccess access) {
+ nativeLibraries = ((BeforeAnalysisAccessImpl) access).getNativeLibraries();
+
+ rerunClassInit(access, "com.sun.management.internal.OperatingSystemImpl");
+
+ access.registerReachabilityHandler(this::linkManagementExt, clazz(access, "com.sun.management.internal.OperatingSystemImpl"));
+ PlatformNativeLibrarySupport.singleton().addBuiltinPkgNativePrefix("com_sun_management_internal_OperatingSystemImpl");
+ }
+
+ private void linkManagementExt(@SuppressWarnings("unused") DuringAnalysisAccess access) {
+ /*
+ * Note that we register `management_ext` as a non-JNI static library. This avoids pulling
+ * in `JNI_OnLoad`, which is fine since we're only interested in the native methods of the
+ * `OperatingSystemImpl` class anyway.
+ */
+ nativeLibraries.addStaticNonJniLibrary("management_ext", "java");
+ if (isWindows()) {
+ nativeLibraries.addDynamicNonJniLibrary("psapi");
+ } else {
+ /*
+ * Register our port of the native function `throw_internal_error`. This avoids linking
+ * the entire object file of the original function, which is necessary to prevent linker
+ * errors such as JDK-8264047.
+ */
+ Method method = ReflectionUtil.lookupMethod(LibManagementExtSupport.class, "throwInternalError", IsolateThread.class, CCharPointer.class);
+ CEntryPointCallStubSupport.singleton().registerStubForMethod(method, () -> CEntryPointData.create(method));
+ }
+ }
+
+ @Override
+ public void afterAnalysis(AfterAnalysisAccess access) {
+ if (NativeLibrarySupport.singleton().isPreregisteredBuiltinLibrary("awt_headless")) {
+ /*
+ * Ensure that `management_ext` comes before `awt_headless` on the linker command line.
+ * This is necessary to prevent linker errors such as JDK-8264047.
+ */
+ nativeLibraries.addStaticNonJniLibrary("management_ext", "awt_headless");
+ }
+ }
+}