From ceaf4df9ff5f8f44b2e53637bc23eeb42c163b52 Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Thu, 9 Oct 2025 12:44:08 +0200 Subject: [PATCH 1/4] Crema: set protectionDomain when defining classes --- .../src/com/oracle/svm/core/hub/DynamicHubCompanion.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHubCompanion.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHubCompanion.java index 1511b4b38fab..7e883c19996f 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHubCompanion.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHubCompanion.java @@ -158,17 +158,17 @@ public final class DynamicHubCompanion { @Platforms(Platform.HOSTED_ONLY.class) static DynamicHubCompanion createHosted(Module module, DynamicHub superHub, String sourceFileName, int modifiers, Object classLoader, Class nestHost, String simpleBinaryName, Object declaringClass, String signature, Object classData) { - return new DynamicHubCompanion(module, superHub, sourceFileName, modifiers, classLoader, nestHost, simpleBinaryName, declaringClass, signature, classData); + return new DynamicHubCompanion(module, superHub, sourceFileName, modifiers, classLoader, nestHost, simpleBinaryName, declaringClass, signature, classData, null); } static DynamicHubCompanion createAtRuntime(Module module, DynamicHub superHub, String sourceFileName, int modifiers, ClassLoader classLoader, String simpleBinaryName, Object declaringClass, String signature, ClassDefinitionInfo info) { assert RuntimeClassLoading.isSupported(); - return new DynamicHubCompanion(module, superHub, sourceFileName, modifiers, classLoader, info.dynamicNest, simpleBinaryName, declaringClass, signature, info.classData); + return new DynamicHubCompanion(module, superHub, sourceFileName, modifiers, classLoader, info.dynamicNest, simpleBinaryName, declaringClass, signature, info.classData, info.protectionDomain); } private DynamicHubCompanion(Module module, DynamicHub superHub, String sourceFileName, int modifiers, - Object classLoader, Class nestHost, String simpleBinaryName, Object declaringClass, String signature, Object classData) { + Object classLoader, Class nestHost, String simpleBinaryName, Object declaringClass, String signature, Object classData, ProtectionDomain protectionDomain) { this.module = module; this.superHub = superHub; this.sourceFileName = sourceFileName; @@ -180,6 +180,7 @@ private DynamicHubCompanion(Module module, DynamicHub superHub, String sourceFil this.classLoader = classLoader; this.classData = classData; + this.protectionDomain = protectionDomain; } public void setHubMetadata(RuntimeDynamicHubMetadata hubMetadata) { From ba1a090fdf4e57fdd61da5e2cbcddcb55208611a Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Thu, 9 Oct 2025 12:44:37 +0200 Subject: [PATCH 2/4] Ensure boot class loader classes have a null CodeSource --- .../src/com/oracle/svm/core/hub/DynamicHub.java | 6 +++++- .../svm/core/jdk/ProtectionDomainSupport.java | 15 +++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) 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 048ba7b8eaa8..187a17958a36 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 @@ -1976,7 +1976,11 @@ public Object[] getSigners() { @Substitute public ProtectionDomain getProtectionDomain() { if (companion.protectionDomain == null) { - companion.protectionDomain = ProtectionDomainSupport.allPermDomain(); + if (getClassLoader() == null) { + companion.protectionDomain = ProtectionDomainSupport.bootAllPermDomain(); + } else { + companion.protectionDomain = ProtectionDomainSupport.allPermDomain(); + } } return companion.protectionDomain; } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/ProtectionDomainSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/ProtectionDomainSupport.java index f976aefbf3f6..ac4e4d1bf0a8 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/ProtectionDomainSupport.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/ProtectionDomainSupport.java @@ -32,8 +32,6 @@ import java.security.cert.Certificate; import java.util.function.Supplier; -import jdk.graal.compiler.options.Option; -import jdk.graal.compiler.options.OptionType; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; @@ -42,6 +40,8 @@ import com.oracle.svm.core.option.HostedOptionKey; import com.oracle.svm.core.util.LazyFinalReference; +import jdk.graal.compiler.options.Option; +import jdk.graal.compiler.options.OptionType; import sun.security.util.SecurityConstants; /** @@ -69,10 +69,21 @@ public static class Options { } private final LazyFinalReference allPermDomain = new LazyFinalReference<>(this::createAllPermDomain); + private final LazyFinalReference bootAllPermDomain = new LazyFinalReference<>(ProtectionDomainSupport::createBootAllPermDomain); /** Remains null as long as the reachability handler has not triggered. */ Supplier executableURLSupplier; + public static ProtectionDomain bootAllPermDomain() { + return ImageSingletons.lookup(ProtectionDomainSupport.class).bootAllPermDomain.get(); + } + + private static ProtectionDomain createBootAllPermDomain() { + java.security.Permissions perms = new java.security.Permissions(); + perms.add(SecurityConstants.ALL_PERMISSION); + return new java.security.ProtectionDomain(null, perms); + } + public static ProtectionDomain allPermDomain() { return ImageSingletons.lookup(ProtectionDomainSupport.class).allPermDomain.get(); } From c0c6676fd650f346bd94841e73508728fd8f151c Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Thu, 9 Oct 2025 12:45:13 +0200 Subject: [PATCH 3/4] Initialize jdk.internal.jrtfs.SystemImage at runtime if JRTFS is enabled --- .../com/oracle/svm/core/jdk/JRTSupport.java | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java index 7f3d2d5d17e1..c2b092855f63 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JRTSupport.java @@ -31,13 +31,14 @@ import java.nio.ByteBuffer; import java.nio.file.FileSystem; import java.nio.file.Path; -import java.util.Arrays; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.BooleanSupplier; +import org.graalvm.nativeimage.hosted.RuntimeClassInitialization; + import com.oracle.svm.core.annotate.Alias; import com.oracle.svm.core.annotate.Delete; import com.oracle.svm.core.annotate.RecomputeFieldValue; @@ -49,6 +50,7 @@ import com.oracle.svm.core.jdk.JRTSupport.JRTEnabled; import com.oracle.svm.core.option.HostedOptionKey; import com.oracle.svm.core.util.VMError; +import com.oracle.svm.util.ReflectionUtil; import jdk.graal.compiler.options.Option; import jdk.graal.compiler.options.OptionType; @@ -84,17 +86,14 @@ public boolean getAsBoolean() { } @AutomaticallyRegisteredFeature -class JRTDisableFeature implements InternalFeature { - - @Override - public boolean isInConfiguration(IsInConfigurationAccess access) { - return !JRTSupport.Options.AllowJRTFileSystem.getValue(); - } - - @SuppressWarnings("unchecked") +class JRTFeature implements InternalFeature { @Override public void beforeAnalysis(BeforeAnalysisAccess access) { - ServiceCatalogSupport.singleton().removeServicesFromServicesCatalog("java.nio.file.spi.FileSystemProvider", new HashSet<>(Arrays.asList("jdk.internal.jrtfs.JrtFileSystemProvider"))); + if (JRTSupport.Options.AllowJRTFileSystem.getValue()) { + RuntimeClassInitialization.initializeAtRunTime(ReflectionUtil.lookupClass("jdk.internal.jrtfs.SystemImage")); + } else { + ServiceCatalogSupport.singleton().removeServicesFromServicesCatalog("java.nio.file.spi.FileSystemProvider", Set.of("jdk.internal.jrtfs.JrtFileSystemProvider")); + } } } From 0ee2f179fc70fd1f7ebc68d498982b1db9b8fc35 Mon Sep 17 00:00:00 2001 From: Gilles Duboscq Date: Fri, 10 Oct 2025 09:47:35 +0200 Subject: [PATCH 4/4] imx_substratevm_benchmark: Set java.home while running Dotty --- .../mx_substratevm_benchmark.py | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/substratevm/mx.substratevm/mx_substratevm_benchmark.py b/substratevm/mx.substratevm/mx_substratevm_benchmark.py index 141eb020710c..2cb4d56b4700 100644 --- a/substratevm/mx.substratevm/mx_substratevm_benchmark.py +++ b/substratevm/mx.substratevm/mx_substratevm_benchmark.py @@ -194,15 +194,21 @@ def run(self, benchmarks, bmSuiteArgs) -> mx_benchmark.DataPoints: def extra_run_arg(self, benchmark, args, image_run_args): run_args = super(RenaissanceNativeImageBenchmarkSuite, self).extra_run_arg(benchmark, args, image_run_args) - if benchmark == "dotty" and self.version() not in ["0.9.0", "0.10.0", "0.11.0", "0.12.0", "0.13.0"]: - # Before Renaissance 0.14.0, mx was manually placing all dependencies on the same classpath at build time - # and at run time. As of Renaissance 0.14.0, we use the standalone mode which uses the classpath defined - # in the manifest file at build time only. Dotty is a special benchmark since it also needs to know - # this classpath at runtime to be able to perform compilations. The location of the fatjar must then be - # explicitly passed also to the final image. - return ["-Djava.class.path={}".format(self.standalone_jar_path(self.benchmarkName()))] + run_args - else: - return run_args + return self._extra_native_run_args(benchmark) + run_args + + def _extra_native_run_args(self, benchmark): + if benchmark == "dotty": + # Dotty uses -H:+AllowJRTFileSystem which requires setting java.home at run time. + dotty_extra_run_args = ['-Djava.home=' + mx.get_jdk().home] + if self.version() not in ["0.9.0", "0.10.0", "0.11.0", "0.12.0", "0.13.0"]: + # Before Renaissance 0.14.0, mx was manually placing all dependencies on the same classpath at build time + # and at run time. As of Renaissance 0.14.0, we use the standalone mode which uses the classpath defined + # in the manifest file at build time only. Dotty is a special benchmark since it also needs to know + # this classpath at runtime to be able to perform compilations. The location of the fatjar must then be + # explicitly passed also to the final image. + dotty_extra_run_args += ["-Djava.class.path={}".format(self.standalone_jar_path(self.benchmarkName()))] + return dotty_extra_run_args + return [] def renaissance_additional_lib(self, lib): return mx.library(lib).get_path(True) @@ -219,16 +225,7 @@ def extra_profile_run_arg(self, benchmark, args, image_run_args, should_strip_ru extra_profile_run_args = mx_sdk_benchmark.adjust_arg_with_number('-r', 1, user_args) else: extra_profile_run_args = user_args - - if benchmark == "dotty" and self.version() not in ["0.9.0", "0.10.0", "0.11.0", "0.12.0", "0.13.0"]: - # Before Renaissance 0.14.0, mx was manually placing all dependencies on the same classpath at build time - # and at run time. As of Renaissance 0.14.0, we use the standalone mode which uses the classpath defined - # in the manifest file at build time only. Dotty is a special benchmark since it also needs to know - # this classpath at runtime to be able to perform compilations. The location of the fatjar must then be - # explicitly passed also to the final image. - return ["-Djava.class.path={}".format(self.standalone_jar_path(self.benchmarkName()))] + extra_profile_run_args - else: - return extra_profile_run_args + return self._extra_native_run_args(benchmark) + extra_profile_run_args def skip_agent_assertions(self, benchmark, args): user_args = super(RenaissanceNativeImageBenchmarkSuite, self).skip_agent_assertions(benchmark, args)