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"); + } + } +}