Skip to content

Commit 2c4518d

Browse files
committed
Backwards-compatibility flag for run-time JDK
The -H:+InitializeJDKAtBuildTimeMigration flag is used in GraalVM 25+ to revert the initialization of the JDK to the state from GraalVM 24-. This flag is only a temporary mesaure until project adjust their build-time initialization configuration.
1 parent 06907ee commit 2c4518d

File tree

8 files changed

+105
-5
lines changed

8 files changed

+105
-5
lines changed

sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeClassInitializationSupport.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -67,4 +67,11 @@ default void rerunInitialization(Class<?> aClass, String reason) {
6767
}
6868

6969
void initializeAtBuildTime(Class<?> aClass, String reason);
70+
71+
/**
72+
* Returns if the <code>className</code> was marked for build-time initialization. The result
73+
* applies both if a package prefix or a fully-qualified class name were configured as build
74+
* time.
75+
*/
76+
boolean isMarkedForBuildTimeInitialization(String className);
7077
}

substratevm/CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ This changelog summarizes major changes to GraalVM Native Image.
44

55
## GraalVM for JDK 25
66
* (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.
7-
* (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`.
7+
* (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`.
88
* (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.
99
* (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.
1010
* (GR-59135) Verify if hosted options passed to `native-image` exist prior to starting the builder. Provide suggestions how to fix unknown options early on.
11+
* (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.
1112

1213
## GraalVM for JDK 24 (Internal Version 24.2.0)
1314
* (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.

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java

+4
Original file line numberDiff line numberDiff line change
@@ -1271,6 +1271,10 @@ public Boolean getValueOrDefault(UnmodifiableEconomicMap<OptionKey<?>, Object> v
12711271
deprecated = true, deprecationMessage = "This option was introduced to simplify migration to GraalVM 23.0 and will be removed in a future release")//
12721272
public static final HostedOptionKey<Boolean> AllowDeprecatedBuilderClassesOnImageClasspath = new HostedOptionKey<>(false);
12731273

1274+
@Option(help = "Initialize JDK classes at build time the same way it was done before GraalVM 25.", type = OptionType.Debug, //
1275+
deprecated = true, deprecationMessage = "This option was introduced to simplify migration to GraalVM 25 and will be removed in a future release")//
1276+
public static final HostedOptionKey<Boolean> InitializeJDKAtBuildTimeMigration = new HostedOptionKey<>(false);
1277+
12741278
@APIOption(name = "exact-reachability-metadata", defaultValue = "")//
12751279
@Option(help = "file:doc-files/ExactReachabilityMetadataHelp.txt")//
12761280
public static final HostedOptionKey<AccumulatingLocatableMultiOptionValue.Strings> ThrowMissingRegistrationErrors = new HostedOptionKey<>(AccumulatingLocatableMultiOptionValue.Strings.build());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.jdk;
26+
27+
import java.util.function.Predicate;
28+
29+
import org.graalvm.nativeimage.ImageSingletons;
30+
import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport;
31+
32+
public class MarkedAsBuildTimeInitialized implements Predicate<String> {
33+
@Override
34+
public boolean test(String className) {
35+
return ImageSingletons.lookup(RuntimeClassInitializationSupport.class).isMarkedForBuildTimeInitialization(className);
36+
}
37+
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/xml/Target_jdk_xml_internal_JdkCatalog.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import com.oracle.svm.core.annotate.Substitute;
3434
import com.oracle.svm.core.annotate.TargetClass;
3535
import com.oracle.svm.core.jdk.JDKLatest;
36+
import com.oracle.svm.core.jdk.MarkedAsBuildTimeInitialized;
3637
import com.oracle.svm.util.ReflectionUtil;
3738

3839
/**
@@ -46,7 +47,7 @@
4647
* Ideally, we would initialize all of {@code jdk.xml} at run time, but that is too intrusive at the
4748
* current point in time (GR-50683).
4849
*/
49-
@TargetClass(className = "jdk.xml.internal.JdkCatalog", onlyWith = JDKLatest.class)
50+
@TargetClass(className = "jdk.xml.internal.JdkCatalog", onlyWith = {JDKLatest.class, MarkedAsBuildTimeInitialized.class})
5051
public final class Target_jdk_xml_internal_JdkCatalog {
5152
@Alias //
5253
@RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Custom, declClass = JdkCatalogSupplier.class, isFinal = true) //
@@ -63,7 +64,7 @@ public static void init(String resolve) {
6364
final class Target_javax_xml_catalog_Catalog {
6465
}
6566

66-
@TargetClass(className = "javax.xml.catalog.CatalogImpl")
67+
@TargetClass(className = "javax.xml.catalog.CatalogImpl", onlyWith = MarkedAsBuildTimeInitialized.class)
6768
final class Target_javax_xml_catalog_CatalogImpl {
6869
@Alias //
6970
@RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset) //

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationFeature.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,12 @@ private void checkImageHeapInstance(DuringAnalysisAccess access, Object obj, Obj
197197
msg += """
198198
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.
199199
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.
200+
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.
200201
"""
201202
.replaceAll("\n", System.lineSeparator())
202203
.formatted(SubstrateOptionsParser.commandArgument(ClassInitializationOptions.ClassInitialization, proxyOrLambda ? proxyLambdaInterfaceCSV : typeName,
203-
"initialize-at-build-time", true, false));
204+
"initialize-at-build-time", true, false),
205+
SubstrateOptionsParser.commandArgument(SubstrateOptions.InitializeJDKAtBuildTimeMigration, "+"));
204206

205207
msg += System.lineSeparator() + "The following detailed trace displays from which field in the code the object was reached.";
206208
throw new UnsupportedFeatureException(msg);

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializationSupport.java

+5
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,11 @@ public void initializeAtBuildTime(String name, String reason) {
279279
}
280280
}
281281

282+
@Override
283+
public boolean isMarkedForBuildTimeInitialization(String className) {
284+
return InitKind.BUILD_TIME == classInitializationConfiguration.lookupKind(className).getLeft();
285+
}
286+
282287
static boolean isClassListedInStringOption(AccumulatingLocatableMultiOptionValue.Strings option, Class<?> clazz) {
283288
return option.values().contains(clazz.getName());
284289
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.hosted.jdk;
26+
27+
import static com.oracle.svm.core.SubstrateOptions.InitializeJDKAtBuildTimeMigration;
28+
29+
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
30+
import com.oracle.svm.core.feature.InternalFeature;
31+
32+
@AutomaticallyRegisteredFeature
33+
public class JDKInitializationMigrationFeature implements InternalFeature {
34+
35+
@Override
36+
public void afterRegistration(AfterRegistrationAccess access) {
37+
// Checkstyle: stop
38+
if (InitializeJDKAtBuildTimeMigration.getValue()) {
39+
/* Place all excluded entries from JDKInitializationFeature here. */
40+
}
41+
// Checkstyle: resume
42+
}
43+
}

0 commit comments

Comments
 (0)