diff --git a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeClassInitializationSupport.java b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeClassInitializationSupport.java
index 508dba7cdbe6..d01871b05e45 100644
--- a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeClassInitializationSupport.java
+++ b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeClassInitializationSupport.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
@@ -67,4 +67,11 @@ default void rerunInitialization(Class> aClass, String reason) {
}
void initializeAtBuildTime(Class> aClass, String reason);
+
+ /**
+ * Returns if the className
was marked for build-time initialization. The result
+ * applies both if a package prefix or a fully-qualified class name were configured as build
+ * time.
+ */
+ boolean isMarkedForBuildTimeInitialization(String className);
}
diff --git a/substratevm/CHANGELOG.md b/substratevm/CHANGELOG.md
index 6b8cca4ef309..2353a617a899 100644
--- a/substratevm/CHANGELOG.md
+++ b/substratevm/CHANGELOG.md
@@ -4,9 +4,10 @@ This changelog summarizes major changes to GraalVM Native Image.
## GraalVM for JDK 25
* (GR-58668) Enabled [Whole-Program Sparse Conditional Constant Propagation (WP-SCCP)](https://github.com/oracle/graal/pull/9821) by default, improving the precision of points-to analysis in Native Image. This optimization enhances static analysis accuracy and scalability, potentially reducing the size of the final native binary.
-* (GR-59313) Deprecated class-level metadata extraction using `native-image-inspect` and removed option `DumpMethodsData`. Use class-level SBOMs instead by passing `--enable-sbom=class-level,export` to the `native-image` builder. The default value of option `IncludeMethodData` was changed to `false`.
+* (GR-59313) Deprecated class-level metadata extraction using `native-image-inspect` and removed option `DumpMethodsData`. Use class-level SBOMs instead by passing `--enable-sbom=class-level,export` to the `native-image` builder. The default value of option `IncludeMethodData` was changed to `false`.
* (GR-52400) The build process now uses 85% of system memory in containers and CI environments. Otherwise, it tries to only use available memory. If less than 8GB of memory are available, it falls back to 85% of system memory. The reason for the selected memory limit is now also shown in the build resources section of the build output.
* (GR-59864) Added JVM version check to the Native Image agent. The agent will abort execution if the JVM major version does not match the version it was built with, and warn if the full JVM version is different.
+* (GR-49525) Introduced build-time `-H:+InitializeJDKAtBuildTimeMigration` that reverts parts of the JDK initialization to pre GraalVM 25 state. This flag should be used only to quickly fix projects that fail until the correct class-initialization configuration is introduced for the project.
## GraalVM for JDK 24 (Internal Version 24.2.0)
* (GR-59717) Added `DuringSetupAccess.registerObjectReachabilityHandler` to allow registering a callback that is executed when an object of a specified type is marked as reachable during heap scanning.
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 f4346f18611f..eef83d85b69c 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
@@ -1261,6 +1261,10 @@ public Boolean getValueOrDefault(UnmodifiableEconomicMap, Object> v
deprecated = true, deprecationMessage = "This option was introduced to simplify migration to GraalVM 23.0 and will be removed in a future release")//
public static final HostedOptionKey AllowDeprecatedBuilderClassesOnImageClasspath = new HostedOptionKey<>(false);
+ @Option(help = "Initialize JDK classes at build time the same way it was done before GraalVM 25.", type = OptionType.Debug, //
+ deprecated = true, deprecationMessage = "This option was introduced to simplify migration to GraalVM 25 and will be removed in a future release")//
+ public static final HostedOptionKey InitializeJDKAtBuildTimeMigration = new HostedOptionKey<>(false);
+
@APIOption(name = "exact-reachability-metadata", defaultValue = "")//
@Option(help = "file:doc-files/ExactReachabilityMetadataHelp.txt")//
public static final HostedOptionKey ThrowMissingRegistrationErrors = new HostedOptionKey<>(AccumulatingLocatableMultiOptionValue.Strings.build());
diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/xml/MarkedAsBuildTimeInitialized.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/xml/MarkedAsBuildTimeInitialized.java
new file mode 100644
index 000000000000..83dba242ccb2
--- /dev/null
+++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/xml/MarkedAsBuildTimeInitialized.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2025, 2025, 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.xml;
+
+import java.util.function.Predicate;
+
+import org.graalvm.nativeimage.ImageSingletons;
+import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport;
+
+public class MarkedAsBuildTimeInitialized implements Predicate {
+ @Override
+ public boolean test(String className) {
+ return ImageSingletons.lookup(RuntimeClassInitializationSupport.class).isMarkedForBuildTimeInitialization(className);
+ }
+}
diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/xml/Target_jdk_xml_internal_JdkCatalog.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/xml/Target_jdk_xml_internal_JdkCatalog.java
index 80a7a605b64a..c9c50dc72868 100644
--- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/xml/Target_jdk_xml_internal_JdkCatalog.java
+++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/xml/Target_jdk_xml_internal_JdkCatalog.java
@@ -46,7 +46,7 @@
* Ideally, we would initialize all of {@code jdk.xml} at run time, but that is too intrusive at the
* current point in time (GR-50683).
*/
-@TargetClass(className = "jdk.xml.internal.JdkCatalog", onlyWith = JDKLatest.class)
+@TargetClass(className = "jdk.xml.internal.JdkCatalog", onlyWith = {JDKLatest.class, MarkedAsBuildTimeInitialized.class})
public final class Target_jdk_xml_internal_JdkCatalog {
@Alias //
@RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Custom, declClass = JdkCatalogSupplier.class, isFinal = true) //
@@ -63,7 +63,7 @@ public static void init(String resolve) {
final class Target_javax_xml_catalog_Catalog {
}
-@TargetClass(className = "javax.xml.catalog.CatalogImpl")
+@TargetClass(className = "javax.xml.catalog.CatalogImpl", onlyWith = MarkedAsBuildTimeInitialized.class)
final class Target_javax_xml_catalog_CatalogImpl {
@Alias //
@RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset) //
diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationFeature.java
index 94698eb2b6c6..48df6a6fc084 100644
--- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationFeature.java
+++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationFeature.java
@@ -197,10 +197,12 @@ private void checkImageHeapInstance(DuringAnalysisAccess access, Object obj, Obj
msg += """
If you are seeing this message after upgrading to a new GraalVM release, this means that some objects ended up in the image heap without their type being marked with --initialize-at-build-time.
To fix this, include %s in your configuration. If the classes do not originate from your code, it is advised to update all library or framework dependencies to the latest version before addressing this error.
+ If the classes originate from the JDK you can try to use %s to temporarily disable this error until the proper configuration is introduced for the project.
"""
.replaceAll("\n", System.lineSeparator())
.formatted(SubstrateOptionsParser.commandArgument(ClassInitializationOptions.ClassInitialization, proxyOrLambda ? proxyLambdaInterfaceCSV : typeName,
- "initialize-at-build-time", true, false));
+ "initialize-at-build-time", true, false),
+ SubstrateOptionsParser.commandArgument(SubstrateOptions.InitializeJDKAtBuildTimeMigration, "+"));
msg += System.lineSeparator() + "The following detailed trace displays from which field in the code the object was reached.";
throw new UnsupportedFeatureException(msg);
diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationSupport.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationSupport.java
index 19f005c69186..16bf80a90ae1 100644
--- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationSupport.java
+++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationSupport.java
@@ -279,6 +279,11 @@ public void initializeAtBuildTime(String name, String reason) {
}
}
+ @Override
+ public boolean isMarkedForBuildTimeInitialization(String className) {
+ return InitKind.BUILD_TIME == classInitializationConfiguration.lookupKind(className).getLeft();
+ }
+
static boolean isClassListedInStringOption(AccumulatingLocatableMultiOptionValue.Strings option, Class> clazz) {
return option.values().contains(clazz.getName());
}
diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JDKInitializationMigrationFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JDKInitializationMigrationFeature.java
new file mode 100644
index 000000000000..a9103f921b7b
--- /dev/null
+++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JDKInitializationMigrationFeature.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.svm.hosted.jdk;
+
+import static com.oracle.svm.core.SubstrateOptions.InitializeJDKAtBuildTimeMigration;
+
+import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
+import com.oracle.svm.core.feature.InternalFeature;
+
+@AutomaticallyRegisteredFeature
+public class JDKInitializationMigrationFeature implements InternalFeature {
+
+ @Override
+ public void afterRegistration(AfterRegistrationAccess access) {
+ // Checkstyle: stop
+ if (InitializeJDKAtBuildTimeMigration.getValue()) {
+ /* Place all excluded entries from JDKInitializationFeature here. */
+ }
+ // Checkstyle: resume
+ }
+}