From 78cd3ec467e1dfb873b1b963acc9adc52f100c53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Wed, 24 May 2023 15:23:04 +0200 Subject: [PATCH 01/12] Make dependency to JDK module java.logging optional --- substratevm/mx.substratevm/suite.py | 1 - .../com/oracle/svm/hosted/LoggingFeature.java | 20 ++++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py index 04a2f12412de..1208339ab150 100644 --- a/substratevm/mx.substratevm/suite.py +++ b/substratevm/mx.substratevm/suite.py @@ -244,7 +244,6 @@ ], "requires" : [ "java.compiler", - "java.logging", "java.scripting", "jdk.httpserver", "jdk.jfr", diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/LoggingFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/LoggingFeature.java index 0386d4aef530..cf392601cdc6 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/LoggingFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/LoggingFeature.java @@ -25,15 +25,18 @@ package com.oracle.svm.hosted; import java.lang.reflect.Field; +import java.util.Optional; import java.util.logging.LogManager; import org.graalvm.compiler.options.Option; import org.graalvm.compiler.options.OptionType; import org.graalvm.nativeimage.hosted.RuntimeReflection; +import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; import com.oracle.svm.core.feature.InternalFeature; import com.oracle.svm.core.option.HostedOptionKey; -import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; +import com.oracle.svm.core.option.SubstrateOptionsParser; +import com.oracle.svm.core.util.UserError; import com.oracle.svm.core.util.VMError; import com.oracle.svm.hosted.FeatureImpl.DuringAnalysisAccessImpl; import com.oracle.svm.hosted.FeatureImpl.DuringSetupAccessImpl; @@ -41,9 +44,13 @@ @AutomaticallyRegisteredFeature public class LoggingFeature implements InternalFeature { + private static Optional requiredModule() { + return ModuleLayer.boot().findModule("java.logging"); + } + public static class Options { @Option(help = "Enable the feature that provides support for logging.")// - public static final HostedOptionKey EnableLoggingFeature = new HostedOptionKey<>(true); + public static final HostedOptionKey EnableLoggingFeature = new HostedOptionKey<>(requiredModule().isPresent()); @Option(help = "When enabled, logging feature details are printed.", type = OptionType.Debug) // public static final HostedOptionKey TraceLoggingFeature = new HostedOptionKey<>(false); @@ -57,11 +64,18 @@ public static class Options { @Override public boolean isInConfiguration(IsInConfigurationAccess access) { - return LoggingFeature.Options.EnableLoggingFeature.getValue(); + Boolean loggingEnabled = Options.EnableLoggingFeature.getValue(); + if (loggingEnabled && requiredModule().isEmpty()) { + throw UserError.abort("Option %s requires JDK module java.logging to be available", + SubstrateOptionsParser.commandArgument(Options.EnableLoggingFeature, "+")); + } + return loggingEnabled; } @Override public void duringSetup(DuringSetupAccess access) { + LoggingFeature.class.getModule().addReads(requiredModule().get()); + /* Ensure that the log manager is initialized and the initial configuration is read. */ LogManager.getLogManager(); loggersField = ((DuringSetupAccessImpl) access).findField("sun.util.logging.PlatformLogger", "loggers"); From 1792190c0bebd53378c2564c4a5716d0fa640b2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Wed, 24 May 2023 19:35:02 +0200 Subject: [PATCH 02/12] Remove dependency to java.scripting --- substratevm/mx.substratevm/suite.py | 2 - .../oracle/svm/core/jdk/NashornSupport.java | 49 ------------------- 2 files changed, 51 deletions(-) delete mode 100644 substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/NashornSupport.java diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py index 1208339ab150..cba0b82e0c71 100644 --- a/substratevm/mx.substratevm/suite.py +++ b/substratevm/mx.substratevm/suite.py @@ -244,7 +244,6 @@ ], "requires" : [ "java.compiler", - "java.scripting", "jdk.httpserver", "jdk.jfr", "jdk.management", @@ -1363,7 +1362,6 @@ "java.smartcardio", "java.net.http", "jdk.sctp", - "jdk.scripting.nashorn@11..14", "jdk.management.agent", "jdk.management.jfr", ], diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/NashornSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/NashornSupport.java deleted file mode 100644 index 6d6850da6fd7..000000000000 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/NashornSupport.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2021, 2021, 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; - -import java.util.function.BooleanSupplier; - -public final class NashornSupport { - - // Determine if the jdk.scripting.nashorn module (or jar) is available. If it's not, - // the boolean supplier should return false. - static class NashornAvailable implements BooleanSupplier { - - private static final String CLASSFILTER_NAME = "jdk.nashorn.api.scripting.ClassFilter"; - - @Override - public boolean getAsBoolean() { - try { - Class.forName(CLASSFILTER_NAME); - return true; - } catch (ClassNotFoundException e) { - return false; - } - } - - } -} From 09d3d63a55998a9149eafcc92b0dfd7dff978c54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Thu, 1 Jun 2023 16:28:08 +0200 Subject: [PATCH 03/12] Add temporary option to debug module dependencies --- .../com/oracle/svm/core/SubstrateOptions.java | 3 +++ .../hosted/NativeImageGeneratorRunner.java | 21 +++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java index d1f7ca97a9ab..68003ff2d805 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java @@ -676,6 +676,9 @@ private static void validateUseOldDebugInfo(HostedOptionKey optionKey) @Option(help = "Directory under which to create source file cache for Application or GraalVM classes")// public static final HostedOptionKey DebugInfoSourceCacheRoot = new HostedOptionKey<>("sources"); + @Option(help = "REMOVE ME")// + public static final HostedOptionKey ListRequiringModules = new HostedOptionKey<>(null); + public static Path getDebugInfoSourceCacheRoot() { try { return Paths.get(Path.getValue()).resolve(DebugInfoSourceCacheRoot.getValue()); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGeneratorRunner.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGeneratorRunner.java index 43196cc0c245..ec8cd554174f 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGeneratorRunner.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGeneratorRunner.java @@ -26,6 +26,7 @@ import java.io.File; import java.io.IOException; +import java.lang.module.ModuleDescriptor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.nio.file.Files; @@ -33,10 +34,12 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.ServiceLoader; +import java.util.Set; import java.util.TimerTask; import java.util.concurrent.ForkJoinPool; import java.util.function.Consumer; @@ -131,6 +134,21 @@ public void run() { if (!remainingArguments.isEmpty()) { throw UserError.abort("Unknown options: %s", String.join(" ", remainingArguments)); } + String nameOfModuleOthersRequire = SubstrateOptions.ListRequiringModules.getValue(imageClassLoader.classLoaderSupport.getParsedHostedOptions()); + if (nameOfModuleOthersRequire != null) { + Set requiringModules = new HashSet<>(); + for (Module module : ModuleLayer.boot().modules()) { + for (ModuleDescriptor.Requires requires : module.getDescriptor().requires()) { + if (requires.name().equals(nameOfModuleOthersRequire)) { + requiringModules.add(module); + } + } + } + System.out.println(requiringModules.stream() + .map(Module::getName) + .collect(Collectors.joining(", ", "Modules requiring " + nameOfModuleOthersRequire + ": ", ""))); + throw new InterruptImageBuilding(""); + } exitStatus = build(imageClassLoader); } catch (UserException e) { reportUserError(e.getMessage()); @@ -574,8 +592,7 @@ public static void reportUserError(Throwable e, OptionValues parsedHostedOptions } private static void reportUserException(Throwable e, OptionValues parsedHostedOptions, Consumer report) { - if (e instanceof UserException) { - UserException ue = (UserException) e; + if (e instanceof UserException ue) { for (String message : ue.getMessages()) { report.accept(message); } From b4770731186ab8fc08916e63262fa9e02d2052df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Thu, 1 Jun 2023 16:31:00 +0200 Subject: [PATCH 04/12] Replace hardcoded with optional module dependencies --- substratevm/mx.substratevm/suite.py | 23 ------ .../svm/core/jdk/JNIRegistrationUtil.java | 3 +- .../svm/core/jdk/JavaNetHttpFeature.java | 26 +++++- .../com/oracle/svm/hosted/LoggingFeature.java | 17 ++-- .../svm/hosted/SecurityServicesFeature.java | 81 +++++++++++++------ .../dashboard/DashboardDumpFeature.java | 7 +- .../hosted/jdk/JNIRegistrationJavaNio.java | 9 ++- .../svm/hosted/jdk/JNIRegistrationPrefs.java | 16 ++++ .../svm/hosted/jdk/JmxCommonFeature.java | 8 +- 9 files changed, 120 insertions(+), 70 deletions(-) diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py index cba0b82e0c71..43510672107b 100644 --- a/substratevm/mx.substratevm/suite.py +++ b/substratevm/mx.substratevm/suite.py @@ -244,7 +244,6 @@ ], "requires" : [ "java.compiler", - "jdk.httpserver", "jdk.jfr", "jdk.management", "jdk.management.jfr", @@ -291,9 +290,6 @@ "jdk.management.agent": [ "jdk.internal.agent", ], - "jdk.httpserver@19+": [ - "sun.net.httpserver.simpleserver", - ], "jdk.jfr": [ "jdk.jfr.events", "jdk.jfr.internal", @@ -612,9 +608,6 @@ ], "requires" : [ "java.instrument", - "java.security.sasl", - "java.smartcardio", - "java.xml.crypto", "jdk.jfr", "jdk.management", "jdk.unsupported", @@ -645,9 +638,6 @@ "com.sun.jmx.mbeanserver", # Needed for javadoc links (MXBeanIntrospector,DefaultMXBeanMappingFactory, MXBeanProxy) "sun.management", # Needed for javadoc links (MappedMXBeanType) ], - "java.rmi": [ - "sun.rmi.server", # Needed for javadoc links (UnicastRef, UnicastRef2) - ], "jdk.internal.vm.ci" : [ "jdk.vm.ci.meta", "jdk.vm.ci.code", @@ -662,11 +652,6 @@ "jdk.jfr.internal", "jdk.jfr.internal.jfc", ], - "java.management.rmi": [ - "com.sun.jmx.remote.internal.rmi", # Needed for javadoc links (ProxyRef) - "com.sun.jmx.remote.protocol.rmi", # Needed for javadoc links (ClientProvider, ServerProvider) - "javax.management.remote.rmi", # Needed for javadoc links (RMIServer, RMIServerImpl_Stub, RMIConnection, RMIConnectionImpl_Stub) - ], }, "javaCompliance" : "17+", "checkstyleVersion": "10.7.0", @@ -1357,11 +1342,6 @@ "requires": [ "java.management", "jdk.management", - "java.xml.crypto", - "java.security.sasl", - "java.smartcardio", - "java.net.http", - "jdk.sctp", "jdk.management.agent", "jdk.management.jfr", ], @@ -1413,9 +1393,6 @@ "java.management": [ "sun.management", ], - "java.xml.crypto": [ - "org.jcp.xml.dsig.internal.dom", - ], }, }, "noMavenJavadoc": True, diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JNIRegistrationUtil.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JNIRegistrationUtil.java index ff3b1e047625..9dde925b45cc 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JNIRegistrationUtil.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JNIRegistrationUtil.java @@ -84,7 +84,8 @@ protected static Optional> optionalClazz(FeatureAccess access, String c } protected static Optional optionalMethod(FeatureAccess access, String className, String methodName, Class... parameterTypes) { - return Optional.ofNullable(ReflectionUtil.lookupMethod(true, clazz(access, className), methodName, parameterTypes)); + return optionalClazz(access, className) + .flatMap(clazz -> Optional.ofNullable(ReflectionUtil.lookupMethod(true, clazz, methodName, parameterTypes))); } protected static Method method(FeatureAccess access, String className, String methodName, Class... parameterTypes) { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JavaNetHttpFeature.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JavaNetHttpFeature.java index e3a61efcbb6a..b5b7a83fa1d1 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JavaNetHttpFeature.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JavaNetHttpFeature.java @@ -24,6 +24,8 @@ */ package com.oracle.svm.core.jdk; +import java.util.Optional; + import org.graalvm.compiler.serviceprovider.JavaVersionUtil; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.RuntimeReflection; @@ -31,12 +33,26 @@ import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport; import com.oracle.svm.core.configure.ResourcesRegistry; -import com.oracle.svm.core.feature.InternalFeature; import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; +import com.oracle.svm.core.feature.InternalFeature; @AutomaticallyRegisteredFeature public class JavaNetHttpFeature extends JNIRegistrationUtil implements InternalFeature { + private static Optional requiredModule() { + return ModuleLayer.boot().findModule("java.net.http"); + } + + @Override + public boolean isInConfiguration(IsInConfigurationAccess access) { + return requiredModule().isPresent(); + } + + @Override + public void afterRegistration(AfterRegistrationAccess access) { + JavaNetHttpFeature.class.getModule().addReads(requiredModule().get()); + } + @Override public void duringSetup(DuringSetupAccess access) { RuntimeClassInitializationSupport rci = ImageSingletons.lookup(RuntimeClassInitializationSupport.class); @@ -59,13 +75,19 @@ private static void registerInitFiltersAccess(DuringAnalysisAccess a) { @AutomaticallyRegisteredFeature class SimpleWebServerFeature implements InternalFeature { + private static Optional requiredModule() { + return ModuleLayer.boot().findModule("jdk.httpserver"); + } + @Override public boolean isInConfiguration(IsInConfigurationAccess access) { - return JavaVersionUtil.JAVA_SPEC >= 19; + return JavaVersionUtil.JAVA_SPEC >= 19 && requiredModule().isPresent(); } @Override public void afterRegistration(AfterRegistrationAccess access) { + SimpleWebServerFeature.class.getModule().addReads(requiredModule().get()); + RuntimeClassInitializationSupport rci = ImageSingletons.lookup(RuntimeClassInitializationSupport.class); rci.initializeAtRunTime("sun.net.httpserver.simpleserver.SimpleFileServerImpl", "Allocates InetAddress in class initializer"); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/LoggingFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/LoggingFeature.java index cf392601cdc6..e78b7bcbdcac 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/LoggingFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/LoggingFeature.java @@ -26,7 +26,6 @@ import java.lang.reflect.Field; import java.util.Optional; -import java.util.logging.LogManager; import org.graalvm.compiler.options.Option; import org.graalvm.compiler.options.OptionType; @@ -40,6 +39,7 @@ import com.oracle.svm.core.util.VMError; import com.oracle.svm.hosted.FeatureImpl.DuringAnalysisAccessImpl; import com.oracle.svm.hosted.FeatureImpl.DuringSetupAccessImpl; +import com.oracle.svm.util.ReflectionUtil; @AutomaticallyRegisteredFeature public class LoggingFeature implements InternalFeature { @@ -75,9 +75,12 @@ public boolean isInConfiguration(IsInConfigurationAccess access) { @Override public void duringSetup(DuringSetupAccess access) { LoggingFeature.class.getModule().addReads(requiredModule().get()); - - /* Ensure that the log manager is initialized and the initial configuration is read. */ - LogManager.getLogManager(); + try { + /* Ensure that the log manager is initialized and the initial configuration is read. */ + ReflectionUtil.lookupMethod(access.findClassByName("java.util.logging.LogManager"), "getLogManager").invoke(null); + } catch (ReflectiveOperationException e) { + throw VMError.shouldNotReachHere("Reflective LogManager initialization failed", e); + } loggersField = ((DuringSetupAccessImpl) access).findField("sun.util.logging.PlatformLogger", "loggers"); } @@ -87,9 +90,9 @@ public void duringAnalysis(DuringAnalysisAccess a) { access.rescanRoot(loggersField); - if (!reflectionConfigured && access.getMetaAccess().optionalLookupJavaType(java.util.logging.Logger.class).isPresent()) { - registerForReflection(java.util.logging.ConsoleHandler.class); - registerForReflection(java.util.logging.SimpleFormatter.class); + if (!reflectionConfigured && access.getMetaAccess().optionalLookupJavaType(a.findClassByName("java.util.logging.Logger")).isPresent()) { + registerForReflection(a.findClassByName("java.util.logging.ConsoleHandler")); + registerForReflection(a.findClassByName("java.util.logging.SimpleFormatter")); reflectionConfigured = true; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SecurityServicesFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SecurityServicesFeature.java index 0cf9914daa74..59700a7c1411 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SecurityServicesFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SecurityServicesFeature.java @@ -56,10 +56,12 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -77,14 +79,6 @@ import javax.net.ssl.TrustManagerFactory; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.login.Configuration; -import javax.security.sasl.SaslClient; -import javax.security.sasl.SaslClientFactory; -import javax.security.sasl.SaslServer; -import javax.security.sasl.SaslServerFactory; -import javax.smartcardio.TerminalFactory; -import javax.xml.crypto.dsig.TransformService; -import javax.xml.crypto.dsig.XMLSignatureFactory; -import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory; import org.graalvm.compiler.options.Option; import org.graalvm.compiler.serviceprovider.JavaVersionUtil; @@ -158,13 +152,35 @@ public static class Options { private static final String[] emptyStringArray = new String[0]; /** The list of known service classes defined by the JCA. */ - private static final Class[] knownServices = {AlgorithmParameterGenerator.class, AlgorithmParameters.class, - CertPathBuilder.class, CertPathValidator.class, CertStore.class, CertificateFactory.class, - Cipher.class, Configuration.class, KeyAgreement.class, KeyFactory.class, - KeyGenerator.class, KeyInfoFactory.class, KeyManagerFactory.class, KeyPairGenerator.class, - KeyStore.class, Mac.class, MessageDigest.class, Policy.class, SSLContext.class, - SaslClientFactory.class, SaslServerFactory.class, SecretKeyFactory.class, SecureRandom.class, Signature.class, - TerminalFactory.class, TransformService.class, TrustManagerFactory.class, XMLSignatureFactory.class}; + private static final List> knownServices; + + static { + List> classList = new ArrayList<>(List.of( + AlgorithmParameterGenerator.class, AlgorithmParameters.class, + CertPathBuilder.class, CertPathValidator.class, CertStore.class, CertificateFactory.class, + Cipher.class, Configuration.class, KeyAgreement.class, KeyFactory.class, + KeyGenerator.class, KeyManagerFactory.class, KeyPairGenerator.class, + KeyStore.class, Mac.class, MessageDigest.class, Policy.class, SSLContext.class, + SecretKeyFactory.class, SecureRandom.class, Signature.class, TrustManagerFactory.class)); + + if (ModuleLayer.boot().findModule("java.security.sasl").isPresent()) { + classList.add(ReflectionUtil.lookupClass(false, "javax.security.sasl.SaslClientFactory")); + classList.add(ReflectionUtil.lookupClass(false, "javax.security.sasl.SaslServerFactory")); + } + if (ModuleLayer.boot().findModule("java.xml.crypto").isPresent()) { + classList.add(ReflectionUtil.lookupClass(false, "javax.xml.crypto.dsig.TransformService")); + classList.add(ReflectionUtil.lookupClass(false, "javax.xml.crypto.dsig.XMLSignatureFactory")); + classList.add(ReflectionUtil.lookupClass(false, "javax.xml.crypto.dsig.keyinfo.KeyInfoFactory")); + } + if (ModuleLayer.boot().findModule("java.smartcardio").isPresent()) { + classList.add(ReflectionUtil.lookupClass(false, "javax.smartcardio.TerminalFactory")); + } + knownServices = Collections.unmodifiableList(classList); + } + + private static Optional javaSmartcardioModule() { + return ModuleLayer.boot().findModule("java.smartcardio"); + } private ImageClassLoader loader; /** Given a service type will return its constructor parameters, if any. */ @@ -257,7 +273,7 @@ public void duringSetup(DuringSetupAccess a) { */ rci.rerunInitialization(clazz(access, "sun.security.jca.JCAUtil$CachedSecureRandomHolder"), "for substitutions"); rci.rerunInitialization(clazz(access, "com.sun.crypto.provider.SunJCE$SecureRandomHolder"), "for substitutions"); - rci.rerunInitialization(clazz(access, "sun.security.krb5.Confounder"), "for substitutions"); + optionalClazz(access, "sun.security.krb5.Confounder").ifPresent(clazz -> rci.rerunInitialization(clazz, "for substitutions")); rci.rerunInitialization(clazz(access, "sun.security.jca.JCAUtil"), "JCAUtil.def holds a SecureRandom."); @@ -318,9 +334,12 @@ public void beforeAnalysis(BeforeAnalysisAccess a) { } if (isPosix()) { - access.registerReachabilityHandler(SecurityServicesFeature::linkJaas, method(access, "com.sun.security.auth.module.UnixSystem", "getUnixInfo")); - /* Resolve calls to com_sun_security_auth_module_UnixSystem* as builtIn. */ - PlatformNativeLibrarySupport.singleton().addBuiltinPkgNativePrefix("com_sun_security_auth_module_UnixSystem"); + Optional optMethodGetUnixInfo = optionalMethod(access, "com.sun.security.auth.module.UnixSystem", "getUnixInfo"); + optMethodGetUnixInfo.ifPresent(m -> { + access.registerReachabilityHandler(SecurityServicesFeature::linkJaas, m); + /* Resolve calls to com_sun_security_auth_module_UnixSystem* as builtIn. */ + PlatformNativeLibrarySupport.singleton().addBuiltinPkgNativePrefix("com_sun_security_auth_module_UnixSystem"); + }); } if (isWindows()) { @@ -449,7 +468,7 @@ private static void linkJaas(DuringAnalysisAccess a) { } private static Set> computeKnownServices(BeforeAnalysisAccess access) { - Set> allKnownServices = new HashSet<>(Arrays.asList(knownServices)); + Set> allKnownServices = new HashSet<>(knownServices); for (String value : Options.AdditionalSecurityServiceTypes.getValue().values()) { for (String serviceClazzName : value.split(",")) { Class serviceClazz = access.findClassByName(serviceClazzName); @@ -460,7 +479,10 @@ private static Set> computeKnownServices(BeforeAnalysisAccess access) { return allKnownServices; } - private void registerSpecialReachabilityHandlers(BeforeAnalysisAccess access) { + private Class classSaslClient; + private Class classSaslServer; + + private void registerSASLReachabilityHandlers(BeforeAnalysisAccess access) { /* * Sasl does not conform to the JCA - the service has no getInstance method. We instead use * the Sasl facade class for our reachability handlers. @@ -475,10 +497,14 @@ private void registerSpecialReachabilityHandlers(BeforeAnalysisAccess access) { } Class saslClass = saslClassLookup.getOrFail(); + + classSaslClient = ReflectionUtil.lookupClass(false, "javax.security.sasl.SaslClient"); + classSaslServer = ReflectionUtil.lookupClass(false, "javax.security.sasl.SaslServer"); + Method createSaslClient = ReflectionUtil.lookupMethod(saslClass, "createSaslClient", String[].class, String.class, String.class, String.class, Map.class, CallbackHandler.class); - access.registerReachabilityHandler(a -> registerServices(a, createSaslClient, SaslClient.class), createSaslClient); + access.registerReachabilityHandler(a -> registerServices(a, createSaslClient, classSaslClient), createSaslClient); Method createSaslServer = ReflectionUtil.lookupMethod(saslClass, "createSaslServer", String.class, String.class, String.class, Map.class, CallbackHandler.class); - access.registerReachabilityHandler(a -> registerServices(a, createSaslServer, SaslServer.class), createSaslServer); + access.registerReachabilityHandler(a -> registerServices(a, createSaslServer, classSaslServer), createSaslServer); } catch (ReflectionUtil.ReflectionUtilError e) { trace(saslRegistrationFailureMessage, e); } @@ -516,7 +542,9 @@ private void registerServiceReachabilityHandlers(BeforeAnalysisAccess access) { } } - registerSpecialReachabilityHandlers(access); + if (ModuleLayer.boot().findModule("java.security.sasl").isPresent()) { + registerSASLReachabilityHandlers(access); + } /* * On Oracle JDK the SecureRandom service implementations are not automatically discovered @@ -544,9 +572,10 @@ private void registerServices(DuringAnalysisAccess access, Object trigger, Class registerServices(access, trigger, serviceType); } - private static String getServiceType(Class serviceClass) { + private String getServiceType(Class serviceClass) { + Objects.requireNonNull(serviceClass); // Checkstyle: allow Class.getSimpleName - if (serviceClass == SaslClient.class || serviceClass == SaslServer.class) { + if (serviceClass == classSaslClient || serviceClass == classSaslServer) { return serviceClass.getSimpleName() + "Factory"; } return serviceClass.getSimpleName(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/dashboard/DashboardDumpFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/dashboard/DashboardDumpFeature.java index a4a10dbbcde7..5c4acf6f92a3 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/dashboard/DashboardDumpFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/dashboard/DashboardDumpFeature.java @@ -32,16 +32,14 @@ import java.util.Collection; import java.util.Collections; import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; import org.graalvm.graphio.GraphOutput; import org.graalvm.graphio.GraphStructure; import com.oracle.graal.pointsto.reports.ReportUtils; import com.oracle.svm.core.SubstrateOptions; -import com.oracle.svm.core.feature.InternalFeature; import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; +import com.oracle.svm.core.feature.InternalFeature; import com.oracle.svm.hosted.FeatureImpl.AfterCompilationAccessImpl; import com.oracle.svm.hosted.FeatureImpl.AfterHeapLayoutAccessImpl; import com.oracle.svm.hosted.FeatureImpl.OnAnalysisExitAccessImpl; @@ -100,7 +98,8 @@ public DashboardDumpFeature() { try { GraphOutput.newBuilder(VoidGraphStructure.INSTANCE).build(Channels.newChannel(os)).close(); } catch (IOException ex) { - Logger.getLogger(DashboardDumpFeature.class.getName()).log(Level.SEVERE, null, ex); + // TODO Replace with LogUtils.warning once GR-40798 is merged + System.out.println("Warning: " + ex + " during Dashboard BGV dump header"); } }); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JNIRegistrationJavaNio.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JNIRegistrationJavaNio.java index 1b03adf858d5..f7d4073a47f0 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JNIRegistrationJavaNio.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JNIRegistrationJavaNio.java @@ -27,6 +27,7 @@ import java.net.InetAddress; import java.net.SocketAddress; import java.nio.ByteBuffer; +import java.util.Optional; import java.util.function.Consumer; import org.graalvm.compiler.serviceprovider.JavaVersionUtil; @@ -46,6 +47,10 @@ @AutomaticallyRegisteredFeature public class JNIRegistrationJavaNio extends JNIRegistrationUtil implements InternalFeature { + private static Optional jdkSctpModule() { + return ModuleLayer.boot().findModule("jdk.sctp"); + } + @Override public void duringSetup(DuringSetupAccess a) { rerunClassInit(a, "sun.nio.ch.IOUtil", "sun.nio.ch.ServerSocketChannelImpl", "sun.nio.ch.DatagramChannelImpl", "sun.nio.ch.FileChannelImpl", "sun.nio.ch.FileKey"); @@ -59,7 +64,7 @@ public void duringSetup(DuringSetupAccess a) { rerunClassInit(a, "sun.nio.ch.SimpleAsynchronousFileChannelImpl", "sun.nio.ch.SimpleAsynchronousFileChannelImpl$DefaultExecutorHolder", "sun.nio.ch.SinkChannelImpl", "sun.nio.ch.SourceChannelImpl"); rerunClassInit(a, "sun.nio.fs.UnixNativeDispatcher", "sun.nio.ch.UnixAsynchronousServerSocketChannelImpl"); - if (isLinux()) { + if (isLinux() && jdkSctpModule().isPresent()) { rerunClassInit(a, "sun.nio.ch.sctp.SctpChannelImpl"); } } else if (isWindows()) { @@ -88,7 +93,7 @@ public void beforeAnalysis(BeforeAnalysisAccess a) { if (isPosix()) { a.registerReachabilityHandler(JNIRegistrationJavaNio::registerUnixNativeDispatcherInit, method(a, "sun.nio.fs.UnixNativeDispatcher", "init")); - if (isLinux()) { + if (isLinux() && jdkSctpModule().isPresent()) { a.registerReachabilityHandler(JNIRegistrationJavaNio::registerSctpChannelImplInitIDs, method(a, "sun.nio.ch.sctp.SctpChannelImpl", "initIDs")); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JNIRegistrationPrefs.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JNIRegistrationPrefs.java index d0bca3c0b761..9283d4b389b0 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JNIRegistrationPrefs.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JNIRegistrationPrefs.java @@ -25,6 +25,7 @@ package com.oracle.svm.hosted.jdk; import java.util.ArrayList; +import java.util.Optional; import org.graalvm.nativeimage.Platforms; import org.graalvm.nativeimage.hosted.RuntimeJNIAccess; @@ -33,6 +34,7 @@ import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; import com.oracle.svm.core.feature.InternalFeature; import com.oracle.svm.core.jdk.JNIRegistrationUtil; +import com.oracle.svm.core.jdk.JavaNetHttpFeature; import com.oracle.svm.core.jdk.NativeLibrarySupport; import com.oracle.svm.core.util.VMError; import com.oracle.svm.hosted.FeatureImpl; @@ -42,6 +44,20 @@ @AutomaticallyRegisteredFeature public class JNIRegistrationPrefs extends JNIRegistrationUtil implements InternalFeature { + private static Optional requiredModule() { + return ModuleLayer.boot().findModule("java.prefs"); + } + + @Override + public boolean isInConfiguration(IsInConfigurationAccess access) { + return requiredModule().isPresent(); + } + + @Override + public void afterRegistration(AfterRegistrationAccess access) { + JavaNetHttpFeature.class.getModule().addReads(requiredModule().get()); + } + @Override public void beforeAnalysis(BeforeAnalysisAccess access) { /* diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JmxCommonFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JmxCommonFeature.java index 11f2221d93e4..879faba51f0d 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JmxCommonFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JmxCommonFeature.java @@ -26,8 +26,6 @@ package com.oracle.svm.hosted.jdk; -import java.lang.reflect.Method; -import java.rmi.Remote; import java.util.Arrays; import org.graalvm.nativeimage.ImageSingletons; @@ -148,11 +146,11 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { * Proxy registration also registers the methods of these MXBeans for reflection. This is * important because they are accessed in many places in the JMX infrastructure. For example: *
    - *
  • {@link com.sun.jmx.remote.internal.rmi.ProxyRef#invoke(Remote, Method, Object[], long)} + *
  • {@code com.sun.jmx.remote.internal.rmi.ProxyRef#invoke(Remote, Method, Object[], long)} *
  • *
  • {@code com.sun.jmx.mbeanserver.MXBeanIntrospector}
  • - *
  • {@link com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory}
  • - *
  • {@link com.sun.jmx.mbeanserver.MXBeanProxy}
  • + *
  • {@code com.sun.jmx.mbeanserver.DefaultMXBeanMappingFactory}
  • + *
  • {@code com.sun.jmx.mbeanserver.MXBeanProxy}
  • *
  • {@code javax.management.MBeanServerInvocationHandler#isLocal(Object, Method)}
  • *
*

From 902b0d93bfbf08ebd166994f2d7ad5e0fe36d66f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Thu, 1 Jun 2023 16:58:09 +0200 Subject: [PATCH 05/12] Remove unused module dependency to java.instrument --- substratevm/mx.substratevm/suite.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py index 43510672107b..66a16d65f79a 100644 --- a/substratevm/mx.substratevm/suite.py +++ b/substratevm/mx.substratevm/suite.py @@ -183,9 +183,6 @@ "sdk:GRAAL_SDK", "compiler:GRAAL", ], - "requires" : [ - "java.instrument", - ], "requiresConcealed" : { "java.base" : ["jdk.internal.module"], }, @@ -607,7 +604,6 @@ "com.oracle.graal.reachability" ], "requires" : [ - "java.instrument", "jdk.jfr", "jdk.management", "jdk.unsupported", From 4a1f211d2860eb3525e584b30f08cf17359b0c95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Mon, 5 Jun 2023 14:56:01 +0200 Subject: [PATCH 06/12] Remove SVM dependency to jdk.unsupported --- substratevm/mx.substratevm/suite.py | 11 ---- .../svm/core/posix/SunMiscSubstitutions.java | 18 ++--- .../svm/core/DumpHeapOnSignalFeature.java | 5 +- ...DumpRuntimeCompilationOnSignalFeature.java | 7 +- .../core/DumpThreadStacksOnSignalFeature.java | 7 +- .../com/oracle/svm/core/hub/DynamicHub.java | 7 +- .../svm/core/jdk/Target_sun_misc_Unsafe.java | 10 ++- .../MissingReflectionRegistrationUtils.java | 2 +- .../svm/hosted/NativeImageGenerator.java | 1 + .../SubstrateGraphBuilderPlugins.java | 65 ++++++++++--------- .../src/JvmFuncs_SignalImpl.h | 2 +- .../src/cSunMiscSignal.c | 2 +- .../svm/thirdparty/gson/GsonFeature.java | 28 +++++--- .../svm/truffle/tck/PermissionsFeature.java | 27 ++++++-- 14 files changed, 106 insertions(+), 86 deletions(-) diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py index 66a16d65f79a..2ca1acab9c39 100644 --- a/substratevm/mx.substratevm/suite.py +++ b/substratevm/mx.substratevm/suite.py @@ -244,7 +244,6 @@ "jdk.jfr", "jdk.management", "jdk.management.jfr", - "jdk.unsupported", ], "requiresConcealed" : { "java.base" : [ @@ -527,9 +526,6 @@ "dependencies": [ "com.oracle.graal.pointsto", ], - "requires" : [ - "jdk.unsupported" # sun.misc.Unsafe - ], "requiresConcealed" : { "java.base" : [ "jdk.internal.misc" @@ -606,7 +602,6 @@ "requires" : [ "jdk.jfr", "jdk.management", - "jdk.unsupported", ], "requiresConcealed" : { "java.base" : [ @@ -978,9 +973,6 @@ "dependencies": [ "com.oracle.svm.core", ], - "requires" : [ - "jdk.unsupported", - ], "checkstyle": "com.oracle.svm.core", "javaCompliance" : "17+", "annotationProcessors": [ @@ -1260,9 +1252,6 @@ "dependencies": [ "com.oracle.svm.hosted", ], - "requires" : [ - "jdk.unsupported", - ], "requiresConcealed": { "jdk.internal.vm.ci": [ "jdk.vm.ci.meta", diff --git a/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/SunMiscSubstitutions.java b/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/SunMiscSubstitutions.java index 87d49bc7ed6d..6317561f9f50 100644 --- a/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/SunMiscSubstitutions.java +++ b/substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/SunMiscSubstitutions.java @@ -80,14 +80,14 @@ private static void raise0(int signalNumber) { } /** - * Called by the VM to execute Java signal handlers. Except that in sun.misc.Signal, this method - * is private. + * Called by the VM to execute Java signal handlers. Except that in jdk.internal.misc.Signal, + * this method is private. */ @Alias static native void dispatch(int number); } -/** Support for Target_sun_misc_Signal. */ +/** Support for Target_jdk_internal_misc_Signal. */ final class Util_jdk_internal_misc_Signal { /** A thread to dispatch signals as they are raised. */ @@ -105,7 +105,7 @@ private Util_jdk_internal_misc_Signal() { /* All-static class. */ } - /** Constants for the longs from sun.misc.Signal. */ + /** Constants for the longs from jdk.internal.misc.Signal. */ private static final long sunMiscSignalDefaultHandler = 0; private static final long sunMiscSignalIgnoreHandler = 1; private static final long sunMiscSignalDispatchHandler = 2; @@ -182,9 +182,9 @@ private static void ensureInitialized() throws IllegalArgumentException { throw new IllegalArgumentException("C signal handling mechanism is in use."); } /* Report other failure. */ - Log.log().string("Util_sun_misc_Signal.ensureInitialized: CSunMiscSignal.create() failed.") + Log.log().string("Util_jdk_internal_misc_Signal.ensureInitialized: CSunMiscSignal.create() failed.") .string(" errno: ").signed(openErrno).string(" ").string(Errno.strerror(openErrno)).newline(); - throw VMError.shouldNotReachHere("Util_sun_misc_Signal.ensureInitialized: CSunMiscSignal.open() failed."); + throw VMError.shouldNotReachHere("Util_jdk_internal_misc_Signal.ensureInitialized: CSunMiscSignal.open() failed."); } /* Initialize the table of signal states. */ @@ -240,7 +240,7 @@ protected static int numberFromName(String javaSignalName) { return entry.getNumber(); } } - /* {@link sun.misc.Signal#findSignal(String)} expects a -1 on failure. */ + /* {@link jdk.internal.misc.Signal#findSignal(String)} expects a -1 on failure. */ return -1; } @@ -377,12 +377,12 @@ protected void setDispatcher(Signal.SignalDispatcher value) { protected static void await() { final int awaitResult = CSunMiscSignal.await(); - PosixUtils.checkStatusIs0(awaitResult, "Util_sun_misc_Signal.SignalState.await(): CSunMiscSignal.await() failed."); + PosixUtils.checkStatusIs0(awaitResult, "Util_jdk_internal_misc_Signal.SignalState.await(): CSunMiscSignal.await() failed."); } protected static void wakeUp() { final int awaitResult = CSunMiscSignal.post(); - PosixUtils.checkStatusIs0(awaitResult, "Util_sun_misc_Signal.SignalState.post(): CSunMiscSignal.post() failed."); + PosixUtils.checkStatusIs0(awaitResult, "Util_jdk_internal_misc_Signal.SignalState.post(): CSunMiscSignal.post() failed."); } /* diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/DumpHeapOnSignalFeature.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/DumpHeapOnSignalFeature.java index 30d293c3704c..212ae60d9c14 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/DumpHeapOnSignalFeature.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/DumpHeapOnSignalFeature.java @@ -38,8 +38,7 @@ import com.oracle.svm.core.jdk.RuntimeSupport; import com.oracle.svm.core.log.Log; -import sun.misc.Signal; -import sun.misc.SignalHandler; +import jdk.internal.misc.Signal; @AutomaticallyRegisteredFeature public class DumpHeapOnSignalFeature implements InternalFeature { @@ -64,7 +63,7 @@ public void execute(boolean isFirstIsolate) { } } -class DumpHeapReport implements SignalHandler { +class DumpHeapReport implements Signal.Handler { private static final TimeZone UTC_TIMEZONE = TimeZone.getTimeZone("UTC"); static void install() { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/DumpRuntimeCompilationOnSignalFeature.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/DumpRuntimeCompilationOnSignalFeature.java index 6f480f4f10b8..981fd5380bdd 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/DumpRuntimeCompilationOnSignalFeature.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/DumpRuntimeCompilationOnSignalFeature.java @@ -27,16 +27,15 @@ import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platform.WINDOWS; +import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; import com.oracle.svm.core.feature.InternalFeature; import com.oracle.svm.core.graal.RuntimeCompilation; import com.oracle.svm.core.heap.VMOperationInfos; import com.oracle.svm.core.jdk.RuntimeSupport; import com.oracle.svm.core.log.Log; import com.oracle.svm.core.thread.JavaVMOperation; -import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; -import sun.misc.Signal; -import sun.misc.SignalHandler; +import jdk.internal.misc.Signal; @AutomaticallyRegisteredFeature public class DumpRuntimeCompilationOnSignalFeature implements InternalFeature { @@ -61,7 +60,7 @@ public void execute(boolean isFirstIsolate) { } } -class DumpRuntimeCompilation implements SignalHandler { +class DumpRuntimeCompilation implements Signal.Handler { static void install() { Signal.handle(new Signal("USR2"), new DumpRuntimeCompilation()); } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/DumpThreadStacksOnSignalFeature.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/DumpThreadStacksOnSignalFeature.java index c687f82162d1..0fb26bbe6f5f 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/DumpThreadStacksOnSignalFeature.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/DumpThreadStacksOnSignalFeature.java @@ -29,6 +29,7 @@ import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platform.WINDOWS; +import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; import com.oracle.svm.core.feature.InternalFeature; import com.oracle.svm.core.heap.VMOperationInfos; import com.oracle.svm.core.jdk.RuntimeSupport; @@ -39,10 +40,8 @@ import com.oracle.svm.core.thread.JavaVMOperation; import com.oracle.svm.core.thread.PlatformThreads; import com.oracle.svm.core.thread.VMThreads; -import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; -import sun.misc.Signal; -import sun.misc.SignalHandler; +import jdk.internal.misc.Signal; @AutomaticallyRegisteredFeature public class DumpThreadStacksOnSignalFeature implements InternalFeature { @@ -67,7 +66,7 @@ public void execute(boolean isFirstIsolate) { } } -class DumpAllStacks implements SignalHandler { +class DumpAllStacks implements Signal.Handler { static void install() { Signal.handle(Platform.includedIn(WINDOWS.class) ? new Signal("BREAK") : new Signal("QUIT"), new DumpAllStacks()); } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHub.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHub.java index 328b05cf49b9..f3b3e7cc1b00 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHub.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHub.java @@ -74,7 +74,6 @@ import org.graalvm.compiler.core.common.NumUtil; import org.graalvm.compiler.core.common.SuppressFBWarnings; -import org.graalvm.compiler.serviceprovider.GraalUnsafeAccess; import org.graalvm.nativeimage.AnnotationAccess; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.Platform; @@ -1932,20 +1931,20 @@ final class Target_java_lang_Class_Atomic { static boolean casReflectionData(DynamicHub clazz, SoftReference> oldData, SoftReference> newData) { - return GraalUnsafeAccess.getUnsafe().compareAndSwapObject(clazz.getCompanion(), reflectionDataOffset, oldData, newData); + return Unsafe.getUnsafe().compareAndSetReference(clazz.getCompanion(), reflectionDataOffset, oldData, newData); } @Substitute static boolean casAnnotationType(DynamicHub clazz, AnnotationType oldType, AnnotationType newType) { - return GraalUnsafeAccess.getUnsafe().compareAndSwapObject(clazz.getCompanion(), annotationTypeOffset, oldType, newType); + return Unsafe.getUnsafe().compareAndSetReference(clazz.getCompanion(), annotationTypeOffset, oldType, newType); } @Substitute static boolean casAnnotationData(DynamicHub clazz, Target_java_lang_Class_AnnotationData oldData, Target_java_lang_Class_AnnotationData newData) { - return GraalUnsafeAccess.getUnsafe().compareAndSwapObject(clazz.getCompanion(), annotationDataOffset, oldData, newData); + return Unsafe.getUnsafe().compareAndSetReference(clazz.getCompanion(), annotationDataOffset, oldData, newData); } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Target_sun_misc_Unsafe.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Target_sun_misc_Unsafe.java index 4e566fff6d52..199f66daae43 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Target_sun_misc_Unsafe.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Target_sun_misc_Unsafe.java @@ -24,6 +24,8 @@ */ package com.oracle.svm.core.jdk; +import java.util.function.BooleanSupplier; + import com.oracle.svm.core.annotate.Alias; import com.oracle.svm.core.annotate.RecomputeFieldValue; import com.oracle.svm.core.annotate.RecomputeFieldValue.Kind; @@ -34,7 +36,7 @@ * of the corresponding (recomputed) fields of {@link jdk.internal.misc.Unsafe}. But copying a * recomputed value during image building does not recompute the value. See GR-12640. */ -@TargetClass(value = sun.misc.Unsafe.class) +@TargetClass(className = "sun.misc.Unsafe", onlyWith = JdkUnsupportedIsEnabled.class) final class Target_sun_misc_Unsafe { /* { Checkstyle: stop */ @@ -94,5 +96,11 @@ final class Target_sun_misc_Unsafe { private static int ARRAY_OBJECT_INDEX_SCALE; /* } Checkstyle: resume */ +} +class JdkUnsupportedIsEnabled implements BooleanSupplier { + @Override + public boolean getAsBoolean() { + return ModuleLayer.boot().findModule("jdk.unsupported").isPresent(); + } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/reflect/MissingReflectionRegistrationUtils.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/reflect/MissingReflectionRegistrationUtils.java index 79fc40515374..03a4e364d29e 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/reflect/MissingReflectionRegistrationUtils.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/reflect/MissingReflectionRegistrationUtils.java @@ -215,7 +215,7 @@ private static void printLine(StringBuilder sb, Object object) { Constructor.class.getTypeName(), Set.of("newInstance"), "java.lang.reflect.ReflectAccess", Set.of("newInstance"), "jdk.internal.access.JavaLangAccess", Set.of("getDeclaredPublicMethods"), - sun.misc.Unsafe.class.getName(), Set.of("allocateInstance"), + "sun.misc.Unsafe", Set.of("allocateInstance"), /* For jdk.internal.misc.Unsafe.allocateInstance(), which is intrinsified */ SubstrateAllocationSnippets.class.getName(), Set.of("instanceHubErrorStub")); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java index 0b97148c23c5..2d764621f02c 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java @@ -1377,6 +1377,7 @@ public T getInjectedArgument(Class type) { assert pluginsMetaAccess != null; SubstrateGraphBuilderPlugins.registerInvocationPlugins(annotationSubstitutionProcessor, + loader, pluginsMetaAccess, hostedSnippetReflection, plugins.getInvocationPlugins(), diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/SubstrateGraphBuilderPlugins.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/SubstrateGraphBuilderPlugins.java index b52aa2dfb5c7..671951b0ac9b 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/SubstrateGraphBuilderPlugins.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/SubstrateGraphBuilderPlugins.java @@ -155,6 +155,7 @@ import com.oracle.svm.core.util.UserError; import com.oracle.svm.core.util.VMError; import com.oracle.svm.hosted.FallbackFeature; +import com.oracle.svm.hosted.ImageClassLoader; import com.oracle.svm.hosted.ReachabilityRegistrationNode; import com.oracle.svm.hosted.meta.HostedField; import com.oracle.svm.hosted.meta.HostedMetaAccess; @@ -172,7 +173,6 @@ import jdk.vm.ci.meta.ResolvedJavaField; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; -import sun.reflect.ReflectionFactory; public class SubstrateGraphBuilderPlugins { @@ -183,6 +183,7 @@ public static class Options { } public static void registerInvocationPlugins(AnnotationSubstitutionProcessor annotationSubstitutions, + ImageClassLoader loader, MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection, InvocationPlugins plugins, @@ -196,7 +197,7 @@ public static void registerInvocationPlugins(AnnotationSubstitutionProcessor ann registerReflectionPlugins(plugins, replacements); registerImageInfoPlugins(metaAccess, plugins); registerProxyPlugins(snippetReflection, annotationSubstitutions, plugins, parsingReason); - registerSerializationPlugins(snippetReflection, plugins, parsingReason); + registerSerializationPlugins(loader, snippetReflection, plugins, parsingReason); registerAtomicUpdaterPlugins(metaAccess, snippetReflection, plugins, parsingReason); registerObjectPlugins(plugins); registerUnsafePlugins(metaAccess, plugins, snippetReflection, parsingReason); @@ -215,7 +216,7 @@ public static void registerInvocationPlugins(AnnotationSubstitutionProcessor ann } } - private static void registerSerializationPlugins(SnippetReflectionProvider snippetReflection, InvocationPlugins plugins, ParsingReason reason) { + private static void registerSerializationPlugins(ImageClassLoader loader, SnippetReflectionProvider snippetReflection, InvocationPlugins plugins, ParsingReason reason) { if (reason.duringAnalysis() && reason != ParsingReason.JITCompilation) { Registration serializationFilter = new Registration(plugins, ObjectInputFilter.Config.class); serializationFilter.register(new RequiredInvocationPlugin("createFilter", String.class) { @@ -235,40 +236,42 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec } }); - Registration customConstructor = new Registration(plugins, ReflectionFactory.class); - customConstructor.register(new RequiredInvocationPlugin("newConstructorForSerialization", Receiver.class, Class.class) { - @Override - public boolean isDecorator() { - return true; - } - - @Override - public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode clazz) { - if (nonNullJavaConstants(receiver.get(), clazz)) { - b.add(ReachabilityRegistrationNode.create(() -> RuntimeSerialization.register(snippetReflection.asObject(Class.class, clazz.asJavaConstant())), reason)); + if (ModuleLayer.boot().findModule("jdk.unsupported").isPresent()) { + Registration customConstructor = new Registration(plugins, loader.findClassOrFail("sun.reflect.ReflectionFactory")); + customConstructor.register(new RequiredInvocationPlugin("newConstructorForSerialization", Receiver.class, Class.class) { + @Override + public boolean isDecorator() { return true; } - return false; - } - }); - customConstructor.register(new RequiredInvocationPlugin("newConstructorForSerialization", Receiver.class, Class.class, Constructor.class) { - @Override - public boolean isDecorator() { - return true; - } + @Override + public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode clazz) { + if (nonNullJavaConstants(receiver.get(), clazz)) { + b.add(ReachabilityRegistrationNode.create(() -> RuntimeSerialization.register(snippetReflection.asObject(Class.class, clazz.asJavaConstant())), reason)); + return true; + } + return false; + } + }); - @Override - public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode clazz, ValueNode constructor) { - if (nonNullJavaConstants(receiver.get(), clazz, constructor)) { - var constructorDeclaringClass = snippetReflection.asObject(Constructor.class, constructor.asJavaConstant()).getDeclaringClass(); - b.add(ReachabilityRegistrationNode.create(() -> RuntimeSerialization.registerWithTargetConstructorClass(snippetReflection.asObject(Class.class, clazz.asJavaConstant()), - constructorDeclaringClass), reason)); + customConstructor.register(new RequiredInvocationPlugin("newConstructorForSerialization", Receiver.class, Class.class, Constructor.class) { + @Override + public boolean isDecorator() { return true; } - return false; - } - }); + + @Override + public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode clazz, ValueNode constructor) { + if (nonNullJavaConstants(receiver.get(), clazz, constructor)) { + var constructorDeclaringClass = snippetReflection.asObject(Constructor.class, constructor.asJavaConstant()).getDeclaringClass(); + b.add(ReachabilityRegistrationNode.create(() -> RuntimeSerialization.registerWithTargetConstructorClass(snippetReflection.asObject(Class.class, clazz.asJavaConstant()), + constructorDeclaringClass), reason)); + return true; + } + return false; + } + }); + } } } diff --git a/substratevm/src/com.oracle.svm.native.jvm.windows/src/JvmFuncs_SignalImpl.h b/substratevm/src/com.oracle.svm.native.jvm.windows/src/JvmFuncs_SignalImpl.h index e93637e0ee0a..e87735f037cc 100644 --- a/substratevm/src/com.oracle.svm.native.jvm.windows/src/JvmFuncs_SignalImpl.h +++ b/substratevm/src/com.oracle.svm.native.jvm.windows/src/JvmFuncs_SignalImpl.h @@ -96,7 +96,7 @@ static void os__signal_notify(int sig) { sig_sem__signal(); } -// sun.misc.Signal +// jdk.internal.misc.Signal // NOTE that this is a workaround for an apparent kernel bug where if // a signal handler for SIGBREAK is installed then that signal handler // takes priority over the console control handler for CTRL_CLOSE_EVENT. diff --git a/substratevm/src/com.oracle.svm.native.libchelper/src/cSunMiscSignal.c b/substratevm/src/com.oracle.svm.native.libchelper/src/cSunMiscSignal.c index e7a9300ae2f8..1922389ab7e0 100644 --- a/substratevm/src/com.oracle.svm.native.libchelper/src/cSunMiscSignal.c +++ b/substratevm/src/com.oracle.svm.native.libchelper/src/cSunMiscSignal.c @@ -49,7 +49,7 @@ * notifying of increments to the values of the counters. * * The other public functions here are operations on the data allocated here, for the convenience of - * the code in Target_sun_misc_Signal. + * the code in Target_jdk_internal_misc_Signal. * * The state for handling signals is global to a process, and has no knowledge of isolates. That * imposes the restriction that only one isolate at a time may register to receive signals. diff --git a/substratevm/src/com.oracle.svm.thirdparty/src/com/oracle/svm/thirdparty/gson/GsonFeature.java b/substratevm/src/com.oracle.svm.thirdparty/src/com/oracle/svm/thirdparty/gson/GsonFeature.java index 65f559b183b0..7a8b212ec184 100644 --- a/substratevm/src/com.oracle.svm.thirdparty/src/com/oracle/svm/thirdparty/gson/GsonFeature.java +++ b/substratevm/src/com.oracle.svm.thirdparty/src/com/oracle/svm/thirdparty/gson/GsonFeature.java @@ -24,10 +24,12 @@ */ package com.oracle.svm.thirdparty.gson; +import java.util.Optional; + import org.graalvm.nativeimage.hosted.Feature; import org.graalvm.nativeimage.hosted.RuntimeReflection; -import com.oracle.svm.core.util.VMError; +import com.oracle.svm.util.ReflectionUtil; /** * Support for the Gson library on SubstrateVM. @@ -41,20 +43,28 @@ */ public final class GsonFeature implements Feature { + private static Optional requiredModule() { + return ModuleLayer.boot().findModule("jdk.unsupported"); + } + @Override public boolean isInConfiguration(IsInConfigurationAccess access) { - return access.findClassByName("com.google.gson.Gson") != null; + /* `sun.misc.Unsafe` is in `jdk.unsupported` */ + return requiredModule().isPresent(); } @Override public void beforeAnalysis(BeforeAnalysisAccess access) { - try { - /* Reflection usage in com.google.gson.internal.UnsafeAllocator.create(). */ - RuntimeReflection.register(sun.misc.Unsafe.class); - RuntimeReflection.register(sun.misc.Unsafe.class.getDeclaredField("theUnsafe")); - RuntimeReflection.register(sun.misc.Unsafe.class.getDeclaredMethod("allocateInstance", Class.class)); - } catch (NoSuchFieldException | NoSuchMethodException ex) { - throw VMError.shouldNotReachHere(ex); + Class gsonClass = access.findClassByName("com.google.gson.Gson"); + if (gsonClass != null) { + access.registerReachabilityHandler(GsonFeature::makeUnsafeReflectivelyAccessible, gsonClass); } } + + private static void makeUnsafeReflectivelyAccessible(DuringAnalysisAccess a) { + Class unsafeClass = a.findClassByName("sun.misc.Unsafe"); + RuntimeReflection.register(unsafeClass); + RuntimeReflection.register(ReflectionUtil.lookupField(unsafeClass, "theUnsafe")); + RuntimeReflection.register(ReflectionUtil.lookupMethod(unsafeClass, "allocateInstance", Class.class)); + } } diff --git a/substratevm/src/com.oracle.svm.truffle.tck/src/com/oracle/svm/truffle/tck/PermissionsFeature.java b/substratevm/src/com.oracle.svm.truffle.tck/src/com/oracle/svm/truffle/tck/PermissionsFeature.java index 43439a065689..c75e6603ee4b 100644 --- a/substratevm/src/com.oracle.svm.truffle.tck/src/com/oracle/svm/truffle/tck/PermissionsFeature.java +++ b/substratevm/src/com.oracle.svm.truffle.tck/src/com/oracle/svm/truffle/tck/PermissionsFeature.java @@ -88,7 +88,6 @@ import jdk.vm.ci.meta.ModifiersProvider; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; -import sun.misc.Unsafe; /** * A Truffle TCK {@code Feature} detecting privileged calls done by Truffle language. The @@ -171,6 +170,8 @@ public boolean getAsBoolean() { private InlinedUnsafeMethodNode inlinedUnsafeCall; + private Class sunMiscUnsafe; + @Override public String getDescription() { return "Detects privileged calls in Truffle languages"; @@ -187,6 +188,10 @@ public void duringSetup(DuringSetupAccess access) { } reportFilePath = Paths.get(reportFile); + if (ModuleLayer.boot().findModule("jdk.unsupported").isPresent()) { + sunMiscUnsafe = access.findClassByName("sun.misc.Unsafe"); + } + FeatureImpl.DuringSetupAccessImpl accessImpl = (FeatureImpl.DuringSetupAccessImpl) access; accessImpl.getHostVM().keepAnalysisGraphs(); } @@ -203,7 +208,9 @@ public void afterAnalysis(AfterAnalysisAccess access) { DebugContext debugContext = accessImpl.getDebugContext(); try (DebugContext.Scope s = debugContext.scope(ClassUtil.getUnqualifiedName(getClass()))) { BigBang bb = accessImpl.getBigBang(); - inlinedUnsafeCall = new InlinedUnsafeMethodNode(bb); + if (sunMiscUnsafe != null) { + inlinedUnsafeCall = new InlinedUnsafeMethodNode(bb.getMetaAccess().lookupJavaType(sunMiscUnsafe)); + } WhiteListParser parser = new WhiteListParser(accessImpl.getImageClassLoader(), bb); ConfigurationParserUtils.parseAndRegisterConfigurations(parser, accessImpl.getImageClassLoader(), @@ -216,7 +223,9 @@ public void afterAnalysis(AfterAnalysisAccess access) { whiteList = parser.getLoadedWhiteList(); Set deniedMethods = new HashSet<>(); deniedMethods.addAll(findMethods(bb, SecurityManager.class, (m) -> m.getName().startsWith("check"))); - deniedMethods.addAll(findMethods(bb, sun.misc.Unsafe.class, ModifiersProvider::isPublic)); + if (sunMiscUnsafe != null) { + deniedMethods.addAll(findMethods(bb, sunMiscUnsafe, ModifiersProvider::isPublic)); + } // The type of the host Java NIO FileSystem. // The FileSystem obtained from the FileSystem.newDefaultFileSystem() is in the Truffle // package but @@ -225,7 +234,9 @@ public void afterAnalysis(AfterAnalysisAccess access) { // JDK 19 introduced BigInteger.parallelMultiply that uses the ForkJoinPool. // We deny this method but explicitly allow non-parallel multiply (cf. jre.json). deniedMethods.addAll(findMethods(bb, BigInteger.class, (m) -> m.getName().startsWith("parallel"))); - deniedMethods.add(inlinedUnsafeCall); + if (inlinedUnsafeCall != null) { + deniedMethods.add(inlinedUnsafeCall); + } Map> cg = callGraph(bb, deniedMethods, debugContext, (SVMHost) bb.getHostVM()); List> report = new ArrayList<>(); Set contextFilters = new HashSet<>(); @@ -307,7 +318,9 @@ private boolean callGraphImpl( StructuredGraph mGraph = hostVM.getAnalysisGraph(m); if (mGraph.hasUnsafeAccess() && !(isSystemClass(mNode) || isCompilerClass(mNode))) { debugContext.log(DebugContext.VERY_DETAILED_LEVEL, "Method: %s has unsafe access.", mName); - visited.computeIfAbsent(inlinedUnsafeCall, (e) -> new HashSet<>()).add(mNode); + if (inlinedUnsafeCall != null) { + visited.computeIfAbsent(inlinedUnsafeCall, (e) -> new HashSet<>()).add(mNode); + } } try { boolean callPathContainsTarget = false; @@ -829,8 +842,8 @@ private static final class InlinedUnsafeMethodNode extends BaseMethodNode { private final AnalysisType unsafe; - InlinedUnsafeMethodNode(BigBang bigBang) { - this.unsafe = bigBang.getMetaAccess().lookupJavaType(Unsafe.class); + InlinedUnsafeMethodNode(AnalysisType unsafe) { + this.unsafe = unsafe; } @Override From 88a632f5fe4528340e1d72573df4e70c57e9eb34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Tue, 13 Jun 2023 10:30:51 +0200 Subject: [PATCH 07/12] Implement builder module dependency check --- .../com/oracle/svm/core/SubstrateOptions.java | 4 +- .../hosted/NativeImageGeneratorRunner.java | 99 ++++++++++++++++--- 2 files changed, 85 insertions(+), 18 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java index 68003ff2d805..36d1626ff6c6 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java @@ -676,8 +676,8 @@ private static void validateUseOldDebugInfo(HostedOptionKey optionKey) @Option(help = "Directory under which to create source file cache for Application or GraalVM classes")// public static final HostedOptionKey DebugInfoSourceCacheRoot = new HostedOptionKey<>("sources"); - @Option(help = "REMOVE ME")// - public static final HostedOptionKey ListRequiringModules = new HostedOptionKey<>(null); + @Option(help = "Temporary option to disable checking of image builder module dependencies or increasing its verbosity", type = OptionType.Debug)// + public static final HostedOptionKey CheckBootModuleDependencies = new HostedOptionKey<>(1); public static Path getDebugInfoSourceCacheRoot() { try { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGeneratorRunner.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGeneratorRunner.java index ec8cd554174f..751d33e9724e 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGeneratorRunner.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGeneratorRunner.java @@ -26,7 +26,6 @@ import java.io.File; import java.io.IOException; -import java.lang.module.ModuleDescriptor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.nio.file.Files; @@ -34,7 +33,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -134,20 +133,10 @@ public void run() { if (!remainingArguments.isEmpty()) { throw UserError.abort("Unknown options: %s", String.join(" ", remainingArguments)); } - String nameOfModuleOthersRequire = SubstrateOptions.ListRequiringModules.getValue(imageClassLoader.classLoaderSupport.getParsedHostedOptions()); - if (nameOfModuleOthersRequire != null) { - Set requiringModules = new HashSet<>(); - for (Module module : ModuleLayer.boot().modules()) { - for (ModuleDescriptor.Requires requires : module.getDescriptor().requires()) { - if (requires.name().equals(nameOfModuleOthersRequire)) { - requiringModules.add(module); - } - } - } - System.out.println(requiringModules.stream() - .map(Module::getName) - .collect(Collectors.joining(", ", "Modules requiring " + nameOfModuleOthersRequire + ": ", ""))); - throw new InterruptImageBuilding(""); + + Integer checkDependencies = SubstrateOptions.CheckBootModuleDependencies.getValue(imageClassLoader.classLoaderSupport.getParsedHostedOptions()); + if (checkDependencies > 0) { + checkBootModuleDependencies(checkDependencies > 1); } exitStatus = build(imageClassLoader); } catch (UserException e) { @@ -175,6 +164,84 @@ public void run() { System.exit(exitStatus); } + private static void checkBootModuleDependencies(boolean verbose) { + Set allModules = ModuleLayer.boot().modules(); + List builderModules = allModules.stream().filter(m -> m.isNamed() && m.getName().startsWith("org.graalvm.nativeimage.")).toList(); + Set transitiveBuilderModules = new LinkedHashSet<>(); + for (Module svmModule : builderModules) { + transitiveReaders(svmModule, allModules, transitiveBuilderModules); + } + if (verbose) { + System.out.println(transitiveBuilderModules.stream() + .map(Module::getName) + .collect(Collectors.joining("\n", "All builder modules: \n", "\n"))); + } + + Set modulesBuilderDependsOn = new LinkedHashSet<>(); + for (Module builderModule : transitiveBuilderModules) { + transitiveRequires(verbose, builderModule, allModules, modulesBuilderDependsOn); + } + modulesBuilderDependsOn.removeAll(transitiveBuilderModules); + if (verbose) { + System.out.println(modulesBuilderDependsOn.stream() + .map(Module::getName) + .collect(Collectors.joining("\n", "All modules the builder modules depend on: \n", "\n"))); + } + + Set expectedBuilderDependencies = Set.of( + "java.base", + "java.management", + "jdk.management", + "jdk.management.agent", + "java.management.rmi", // READ-BY org.graalvm.nativeimage.builder + "java.rmi", + "java.logging", // READ-BY java.rmi READ-BY java.management.rmi + "java.naming", + "java.security.sasl", // READ-BY java.naming READ-BY java.management.rmi + "java.compiler", + "jdk.management.jfr", + "jdk.jfr"); + + Set unexpectedBuilderDependencies = modulesBuilderDependsOn.stream().map(Module::getName).collect(Collectors.toSet()); + unexpectedBuilderDependencies.removeAll(expectedBuilderDependencies); + if (!unexpectedBuilderDependencies.isEmpty()) { + throw VMError.shouldNotReachHere("Unexpected image builder module-dependencies: " + String.join(", ", unexpectedBuilderDependencies)); + } + } + + private static void transitiveReaders(Module readModule, Set potentialReaders, Set actualReaders) { + for (Module potentialReader : potentialReaders) { + if (potentialReader.canRead(readModule)) { + if (actualReaders.add(potentialReader)) { + transitiveReaders(potentialReader, potentialReaders, actualReaders); + } + } + } + } + + private static void transitiveRequires(boolean verbose, Module requiringModule, Set potentialNeededModules, Set actualNeededModules) { + for (Module potentialNeedModule : potentialNeededModules) { + if (requiringModule.canRead(potentialNeedModule)) { + /* Filter out GraalVM modules */ + if (potentialNeedModule.getName().startsWith("jdk.internal.vm.c") || /* JVMCI */ + /* graal */ + potentialNeedModule.getName().startsWith("org.graalvm.") || + /* enterprise graal */ + potentialNeedModule.getName().startsWith("com.oracle.graal.") || + /* llvm-backend optional dependencies */ + potentialNeedModule.getName().startsWith("com.oracle.svm.shadowed.")) { + continue; + } + if (actualNeededModules.add(potentialNeedModule)) { + if (verbose) { + System.out.println(requiringModule + " reads " + potentialNeedModule); + } + transitiveRequires(verbose, potentialNeedModule, potentialNeededModules, actualNeededModules); + } + } + } + } + public static void uninstallNativeImageClassLoader() { ClassLoader loader = ClassLoader.getSystemClassLoader(); if (loader instanceof NativeImageSystemClassLoader) { From 3df12b622d2a2a24a04d3584c00b2096793070ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Tue, 13 Jun 2023 11:46:02 +0200 Subject: [PATCH 08/12] Cleanup com.oracle.svm.thirdparty dependencies --- substratevm/mx.substratevm/suite.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py index 2ca1acab9c39..7b6244c1ab3c 100644 --- a/substratevm/mx.substratevm/suite.py +++ b/substratevm/mx.substratevm/suite.py @@ -971,7 +971,7 @@ "subDir": "src", "sourceDirs": ["src"], "dependencies": [ - "com.oracle.svm.core", + "com.oracle.svm.util", ], "checkstyle": "com.oracle.svm.core", "javaCompliance" : "17+", From 949406012a1bf3aae63e1ef7f2df953eaa0d2526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Tue, 13 Jun 2023 11:51:50 +0200 Subject: [PATCH 09/12] Style fixes --- .../oracle/svm/core/jdk/RecomputedFields.java | 6 ++-- .../hosted/NativeImageSystemClassLoader.java | 3 +- .../svm/hosted/SecurityServicesFeature.java | 4 --- .../svm/hosted/jdk/JmxClientFeature.java | 16 ++++------ .../svm/hosted/jdk/JmxCommonFeature.java | 14 ++++----- .../svm/hosted/jdk/JmxServerFeature.java | 29 +++++++++---------- .../SubstrateGraphBuilderPlugins.java | 2 +- .../svm/thirdparty/gson/GsonFeature.java | 2 +- 8 files changed, 33 insertions(+), 43 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RecomputedFields.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RecomputedFields.java index 335f89f1f051..f587cd7aad17 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RecomputedFields.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RecomputedFields.java @@ -234,9 +234,9 @@ final class Target_java_util_concurrent_atomic_AtomicLongFieldUpdater_LockedUpda } /** - * The atomic field updaters access fields using {@link sun.misc.Unsafe}. The static analysis needs - * to know about all these fields, so we need to find the original field (the updater only stores - * the field offset) and mark it as unsafe accessed. + * The atomic field updaters access fields using {@code Unsafe}. The static analysis needs to know + * about all these fields, so we need to find the original field (the updater only stores the field + * offset) and mark it as unsafe accessed. */ @AutomaticallyRegisteredFeature class AtomicFieldUpdaterFeature implements InternalFeature { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageSystemClassLoader.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageSystemClassLoader.java index 3b0b0cad9061..3a0491679f8e 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageSystemClassLoader.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageSystemClassLoader.java @@ -35,7 +35,6 @@ import java.util.List; import java.util.Set; import java.util.WeakHashMap; -import java.util.jar.JarFile; import com.oracle.svm.core.util.UserError; import com.oracle.svm.core.util.VMError; @@ -277,7 +276,7 @@ private List getActiveClassLoaders() { /** * This method is necessary for all custom system class loaders. It allows for the load of the * agent during startup. See - * {@link java.lang.instrument.Instrumentation#appendToSystemClassLoaderSearch(JarFile)} } + * {@code java.lang.instrument.Instrumentation#appendToSystemClassLoaderSearch(JarFile)} } * * @param classPathEntry the classpath entry that will be added to the class path */ diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SecurityServicesFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SecurityServicesFeature.java index 59700a7c1411..6b4ada7eeac5 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SecurityServicesFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SecurityServicesFeature.java @@ -178,10 +178,6 @@ public static class Options { knownServices = Collections.unmodifiableList(classList); } - private static Optional javaSmartcardioModule() { - return ModuleLayer.boot().findModule("java.smartcardio"); - } - private ImageClassLoader loader; /** Given a service type will return its constructor parameters, if any. */ private Function> ctrParamClassAccessor; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JmxClientFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JmxClientFeature.java index 1f37719af52f..585a9ff10ea2 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JmxClientFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JmxClientFeature.java @@ -35,10 +35,6 @@ import com.oracle.svm.core.util.VMError; import com.oracle.svm.util.ReflectionUtil; -import javax.management.remote.JMXServiceURL; -import java.io.ObjectOutput; -import java.util.Map; - @AutomaticallyRegisteredFeature public class JmxClientFeature extends JNIRegistrationUtil implements InternalFeature { @Override @@ -64,13 +60,13 @@ private static void configureJNI() { /** * This method configures reflection metadata only required by a JMX client. *
    - *
  • Register {@link com.sun.jmx.remote.protocol.rmi.ClientProvider} which can be reflectively + *
  • Register {@code com.sun.jmx.remote.protocol.rmi.ClientProvider} which can be reflectively * looked up on a code path starting from - * {@link javax.management.remote.JMXConnectorFactory#newJMXConnector(JMXServiceURL, Map)}
  • - *
  • Register {@link sun.rmi.server.UnicastRef2}, which can be reflectively accessed with - * {@link sun.rmi.server.UnicastRef2#getRefClass(ObjectOutput)}.
  • - *
  • Register {@link sun.rmi.server.UnicastRef}, which can be reflectively accessed with - * {@link sun.rmi.server.UnicastRef#getRefClass(ObjectOutput)}.
  • + * {@code javax.management.remote.JMXConnectorFactory#newJMXConnector(JMXServiceURL, Map)} + *
  • Register {@code sun.rmi.server.UnicastRef2}, which can be reflectively accessed with + * {@code sun.rmi.server.UnicastRef2#getRefClass(ObjectOutput)}.
  • + *
  • Register {@code sun.rmi.server.UnicastRef}, which can be reflectively accessed with + * {@code sun.rmi.server.UnicastRef#getRefClass(ObjectOutput)}.
  • *
*/ private static void configureReflection(BeforeAnalysisAccess access) { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JmxCommonFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JmxCommonFeature.java index 879faba51f0d..870e2e67b2c0 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JmxCommonFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JmxCommonFeature.java @@ -192,7 +192,7 @@ private static void configureJNI() { *
  • {@link javax.management.openmbean.CompositeData}
  • *
  • {@link javax.management.openmbean.ArrayType}
  • These * {@link javax.management.openmbean.OpenType}s are reflectively accessed at multiple points in - * the remote JMX infrastructure (See {@link sun.management.MappedMXBeanType}, + * the remote JMX infrastructure (See {@code sun.management.MappedMXBeanType}, * {@code com.sun.jmx.mbeanserver.MXBeanMapping#makeOpenClass(Type, javax.management.openmbean.OpenType)}) */ private static void configureSerialization(BeforeAnalysisAccess access) { @@ -254,11 +254,11 @@ private static void configureSerialization(BeforeAnalysisAccess access) { * This method configures reflection metadata shared between both JMX client and server. *
      *
    • All *Skel and *Stub classes must be registered for reflection along with - * their constructors. See {@link sun.rmi.server.Util} for an example.
    • + * their constructors. See {@code sun.rmi.server.Util} for an example. * *
    • All methods of *Info classes with static from methods must be registered * for reflection. For example see: - * {@link com.sun.management.GcInfo#from(javax.management.openmbean.CompositeData)} and + * {@code com.sun.management.GcInfo#from(javax.management.openmbean.CompositeData)} and * {@link java.lang.management.MemoryUsage#from(javax.management.openmbean.CompositeData)}. This * is because these classes have their methods reflectively accessed from their static * from methods. Remote JMX infrastructure uses the following pattern: the *Info @@ -266,11 +266,11 @@ private static void configureSerialization(BeforeAnalysisAccess access) { * static frommethod. (ie. SomeInfo would correspond to SomeInfoCompositeData extends * LazyCompositeData ).
    • * - *
    • {@link javax.management.remote.rmi.RMIServer} requires registration of all its methods as - * they are used from {@link javax.management.remote.rmi.RMIServerImpl_Stub}.
    • - *
    • {@link javax.management.remote.rmi.RMIConnection} requires registration of all its + *
    • {@code javax.management.remote.rmi.RMIServer} requires registration of all its methods as + * they are used from {@code javax.management.remote.rmi.RMIServerImpl_Stub}.
    • + *
    • {@code javax.management.remote.rmi.RMIConnection} requires registration of all its * methods as they are used from - * {@link javax.management.remote.rmi.RMIConnectionImpl_Stub}.
    • + * {@code javax.management.remote.rmi.RMIConnectionImpl_Stub}. *
    */ private static void configureReflection(BeforeAnalysisAccess access) { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JmxServerFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JmxServerFeature.java index 3026e72d4bdb..ba9315d8dd8b 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JmxServerFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JmxServerFeature.java @@ -26,29 +26,28 @@ package com.oracle.svm.hosted.jdk; -import com.oracle.svm.core.feature.InternalFeature; - import java.lang.management.PlatformManagedObject; - import java.util.Map; import java.util.Set; -import com.oracle.svm.core.jdk.NativeLibrarySupport; -import com.oracle.svm.hosted.FeatureImpl.BeforeAnalysisAccessImpl; -import com.oracle.svm.core.jdk.PlatformNativeLibrarySupport; -import org.graalvm.nativeimage.impl.ConfigurationCondition; +import javax.management.MBeanServer; +import javax.management.remote.JMXServiceURL; + import org.graalvm.nativeimage.ImageSingletons; -import com.oracle.svm.core.configure.ResourcesRegistry; -import com.oracle.svm.core.jdk.proxy.DynamicProxyRegistry; import org.graalvm.nativeimage.hosted.RuntimeReflection; +import org.graalvm.nativeimage.impl.ConfigurationCondition; + +import com.oracle.svm.core.VMInspectionOptions; +import com.oracle.svm.core.configure.ResourcesRegistry; +import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; +import com.oracle.svm.core.feature.InternalFeature; +import com.oracle.svm.core.jdk.NativeLibrarySupport; +import com.oracle.svm.core.jdk.PlatformNativeLibrarySupport; import com.oracle.svm.core.jdk.RuntimeSupport; import com.oracle.svm.core.jdk.management.ManagementAgentStartupHook; -import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; -import com.oracle.svm.core.VMInspectionOptions; import com.oracle.svm.core.jdk.management.ManagementSupport; - -import javax.management.MBeanServer; -import javax.management.remote.JMXServiceURL; +import com.oracle.svm.core.jdk.proxy.DynamicProxyRegistry; +import com.oracle.svm.hosted.FeatureImpl.BeforeAnalysisAccessImpl; @AutomaticallyRegisteredFeature public class JmxServerFeature implements InternalFeature { @@ -101,7 +100,7 @@ private static void configureProxy(BeforeAnalysisAccess access) { *
      *
    • Here we register all the custom MXBeans of Substrate VM. They will not be accounted for * by the native image tracing agent so a user may not know they need to register them.
    • - *
    • We also register {@link com.sun.jmx.remote.protocol.rmi.ServerProvider} which can be + *
    • We also register {@code com.sun.jmx.remote.protocol.rmi.ServerProvider} which can be * reflectively looked up on a code path starting from * {@link javax.management.remote.JMXConnectorServerFactory#newJMXConnectorServer(JMXServiceURL, Map, MBeanServer)} *
    • diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/SubstrateGraphBuilderPlugins.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/SubstrateGraphBuilderPlugins.java index 671951b0ac9b..cb8fcd9c29be 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/SubstrateGraphBuilderPlugins.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/SubstrateGraphBuilderPlugins.java @@ -265,7 +265,7 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec if (nonNullJavaConstants(receiver.get(), clazz, constructor)) { var constructorDeclaringClass = snippetReflection.asObject(Constructor.class, constructor.asJavaConstant()).getDeclaringClass(); b.add(ReachabilityRegistrationNode.create(() -> RuntimeSerialization.registerWithTargetConstructorClass(snippetReflection.asObject(Class.class, clazz.asJavaConstant()), - constructorDeclaringClass), reason)); + constructorDeclaringClass), reason)); return true; } return false; diff --git a/substratevm/src/com.oracle.svm.thirdparty/src/com/oracle/svm/thirdparty/gson/GsonFeature.java b/substratevm/src/com.oracle.svm.thirdparty/src/com/oracle/svm/thirdparty/gson/GsonFeature.java index 7a8b212ec184..c1b071018956 100644 --- a/substratevm/src/com.oracle.svm.thirdparty/src/com/oracle/svm/thirdparty/gson/GsonFeature.java +++ b/substratevm/src/com.oracle.svm.thirdparty/src/com/oracle/svm/thirdparty/gson/GsonFeature.java @@ -38,7 +38,7 @@ * to be registered manually by the user using the {@link RuntimeReflection runtime reflection * support} of Substrate VM. It is not feasible to automatically detect all necessary classes. *

      - * This feature registers parts of {@link sun.misc.Unsafe} as reflectively accessible. Gson uses it + * This feature registers parts of {@code sun.misc.Unsafe} as reflectively accessible. Gson uses it * internally to instantiate classes that do not have a no-argument constructor. */ public final class GsonFeature implements Feature { From 4ee7a81112a862af92a7b7f037da7192751df1ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Wed, 14 Jun 2023 14:57:57 +0200 Subject: [PATCH 10/12] Fix DashboardDumpFeature logging --- .../com/oracle/svm/hosted/dashboard/DashboardDumpFeature.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/dashboard/DashboardDumpFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/dashboard/DashboardDumpFeature.java index 5c4acf6f92a3..00a6abd25285 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/dashboard/DashboardDumpFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/dashboard/DashboardDumpFeature.java @@ -27,6 +27,7 @@ import java.io.File; import java.io.IOException; import java.io.PrintWriter; +import java.lang.System.Logger.Level; import java.nio.channels.Channels; import java.nio.file.Path; import java.util.Collection; @@ -98,8 +99,7 @@ public DashboardDumpFeature() { try { GraphOutput.newBuilder(VoidGraphStructure.INSTANCE).build(Channels.newChannel(os)).close(); } catch (IOException ex) { - // TODO Replace with LogUtils.warning once GR-40798 is merged - System.out.println("Warning: " + ex + " during Dashboard BGV dump header"); + System.getLogger(DashboardDumpFeature.class.getName()).log(Level.ERROR, "IOException during Dashboard BGV dump header", ex); } }); } From efce4a9f078666ba20ddfa7aaceedf0aeeb56552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Wed, 14 Jun 2023 16:23:30 +0200 Subject: [PATCH 11/12] Perform builder module dep check only if builder runs on module path --- .../src/com/oracle/svm/core/SubstrateOptions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java index 36d1626ff6c6..39b395f48dee 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java @@ -677,7 +677,7 @@ private static void validateUseOldDebugInfo(HostedOptionKey optionKey) public static final HostedOptionKey DebugInfoSourceCacheRoot = new HostedOptionKey<>("sources"); @Option(help = "Temporary option to disable checking of image builder module dependencies or increasing its verbosity", type = OptionType.Debug)// - public static final HostedOptionKey CheckBootModuleDependencies = new HostedOptionKey<>(1); + public static final HostedOptionKey CheckBootModuleDependencies = new HostedOptionKey<>(ModuleSupport.modulePathBuild ? 1 : 0); public static Path getDebugInfoSourceCacheRoot() { try { From 0ed02af52c2e9a8fd87153eb1dc4bbfb787bdb53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20W=C3=B6gerer?= Date: Thu, 15 Jun 2023 15:44:08 +0200 Subject: [PATCH 12/12] Update comment --- .../src/com/oracle/svm/hosted/NativeImageGeneratorRunner.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGeneratorRunner.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGeneratorRunner.java index 751d33e9724e..cb11c46b468d 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGeneratorRunner.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGeneratorRunner.java @@ -192,8 +192,8 @@ private static void checkBootModuleDependencies(boolean verbose) { "java.base", "java.management", "jdk.management", - "jdk.management.agent", - "java.management.rmi", // READ-BY org.graalvm.nativeimage.builder + "jdk.management.agent", // READ-BY org.graalvm.nativeimage.builder + "java.management.rmi", // READ-BY jdk.management.agent "java.rmi", "java.logging", // READ-BY java.rmi READ-BY java.management.rmi "java.naming",