Skip to content

Commit 67ca007

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 9bde10c commit 67ca007

File tree

6 files changed

+79
-24
lines changed

6 files changed

+79
-24
lines changed

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

+1-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
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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 com.oracle.svm.core.FutureDefaultsOptions;
30+
31+
public class JDKInitializedAtBuildTime implements Predicate<String> {
32+
@Override
33+
public boolean test(String className) {
34+
return !FutureDefaultsOptions.isJDKInitializedAtRunTime();
35+
}
36+
}

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
@@ -26,6 +26,7 @@
2626

2727
import java.util.Objects;
2828

29+
import com.oracle.svm.core.jdk.JDKInitializedAtBuildTime;
2930
import org.graalvm.nativeimage.hosted.FieldValueTransformer;
3031

3132
import com.oracle.svm.core.annotate.Alias;
@@ -45,7 +46,7 @@
4546
* Ideally, we would initialize all of {@code jdk.xml} at run time, but that is too intrusive at the
4647
* current point in time (GR-50683).
4748
*/
48-
@TargetClass(className = "jdk.xml.internal.JdkCatalog", onlyWith = JDKLatest.class)
49+
@TargetClass(className = "jdk.xml.internal.JdkCatalog", onlyWith = {JDKLatest.class, JDKInitializedAtBuildTime.class})
4950
public final class Target_jdk_xml_internal_JdkCatalog {
5051
@Alias //
5152
@RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Custom, declClass = JdkCatalogSupplier.class, isFinal = true) //
@@ -62,7 +63,7 @@ public static void init(String resolve) {
6263
final class Target_javax_xml_catalog_Catalog {
6364
}
6465

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

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,11 @@
4444
import java.util.function.Function;
4545
import java.util.stream.Collectors;
4646

47-
import jdk.graal.compiler.core.common.ContextClassLoaderScope;
48-
import org.graalvm.nativeimage.libgraal.hosted.LibGraalLoader;
4947
import org.graalvm.collections.EconomicSet;
5048
import org.graalvm.nativeimage.ImageSingletons;
5149
import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport;
5250
import org.graalvm.nativeimage.impl.clinit.ClassInitializationTracking;
51+
import org.graalvm.nativeimage.libgraal.hosted.LibGraalLoader;
5352

5453
import com.oracle.graal.pointsto.infrastructure.OriginalClassProvider;
5554
import com.oracle.graal.pointsto.meta.AnalysisType;
@@ -65,6 +64,7 @@
6564
import com.oracle.svm.util.LogUtils;
6665
import com.oracle.svm.util.ModuleSupport;
6766

67+
import jdk.graal.compiler.core.common.ContextClassLoaderScope;
6868
import jdk.graal.compiler.java.LambdaUtils;
6969
import jdk.internal.misc.Unsafe;
7070
import jdk.vm.ci.meta.MetaAccessProvider;

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JDKInitializationFeature.java

+27-18
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@
2626

2727
import java.lang.reflect.Field;
2828

29-
import com.oracle.svm.core.FutureDefaultsOptions;
3029
import org.graalvm.nativeimage.ImageSingletons;
3130
import org.graalvm.nativeimage.Platform;
3231
import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport;
3332

33+
import com.oracle.svm.core.FutureDefaultsOptions;
3434
import com.oracle.svm.core.ParsingReason;
3535
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
3636
import com.oracle.svm.core.feature.InternalFeature;
@@ -53,7 +53,7 @@
5353

5454
@AutomaticallyRegisteredFeature
5555
public class JDKInitializationFeature implements InternalFeature {
56-
private static final String JDK_CLASS_REASON = "Core JDK classes are initialized at build time";
56+
static final String JDK_CLASS_REASON = "Core JDK classes are initialized at build time";
5757

5858
@Override
5959
public void afterRegistration(AfterRegistrationAccess access) {
@@ -72,8 +72,10 @@ public void afterRegistration(AfterRegistrationAccess access) {
7272
rci.initializeAtBuildTime("java.net", JDK_CLASS_REASON);
7373
rci.initializeAtBuildTime("java.nio", JDK_CLASS_REASON);
7474
rci.initializeAtBuildTime("java.text", JDK_CLASS_REASON);
75+
7576
rci.initializeAtBuildTime("java.time", JDK_CLASS_REASON);
7677
rci.initializeAtRunTime("java.time.chrono.HijrahChronology", "Reads java.home in class initializer.");
78+
7779
rci.initializeAtBuildTime("java.util", JDK_CLASS_REASON);
7880
rci.initializeAtRunTime("java.util.concurrent.SubmissionPublisher", "Executor service must be recomputed");
7981

@@ -83,7 +85,6 @@ public void afterRegistration(AfterRegistrationAccess access) {
8385
rci.initializeAtBuildTime("javax.naming", JDK_CLASS_REASON);
8486
rci.initializeAtBuildTime("javax.net", JDK_CLASS_REASON);
8587
rci.initializeAtBuildTime("javax.tools", JDK_CLASS_REASON);
86-
rci.initializeAtBuildTime("javax.xml", JDK_CLASS_REASON);
8788

8889
rci.initializeAtBuildTime("jdk.internal", JDK_CLASS_REASON);
8990
rci.initializeAtBuildTime("jdk.jfr", "Needed for Native Image substitutions");
@@ -94,15 +95,6 @@ public void afterRegistration(AfterRegistrationAccess access) {
9495
rci.initializeAtBuildTime("jdk.net", JDK_CLASS_REASON);
9596
rci.initializeAtBuildTime("jdk.nio", JDK_CLASS_REASON);
9697
rci.initializeAtBuildTime("jdk.vm.ci", "Native Image classes are always initialized at build time");
97-
rci.initializeAtBuildTime("jdk.xml", JDK_CLASS_REASON);
98-
/*
99-
* The XML classes have cyclic class initializer dependencies, and class initialization can
100-
* deadlock/fail when initialization is started at the "wrong part" of the cycle.
101-
* Force-initializing the correct class of the cycle here, in addition to the
102-
* "whole package" initialization above, breaks the cycle because it triggers immediate
103-
* initilalization here before the static analysis is started.
104-
*/
105-
rci.initializeAtBuildTime("jdk.xml.internal.JdkXmlUtils", JDK_CLASS_REASON);
10698

10799
rci.initializeAtBuildTime("sun.invoke", JDK_CLASS_REASON);
108100
rci.initializeAtBuildTime("sun.launcher", JDK_CLASS_REASON);
@@ -145,11 +137,30 @@ public void afterRegistration(AfterRegistrationAccess access) {
145137

146138
/* XML-related */
147139
if (FutureDefaultsOptions.isJDKInitializedAtRunTime()) {
148-
// GR-50683 should remove this part
149-
rci.initializeAtBuildTime("com.sun.xml", JDK_CLASS_REASON);
150-
rci.initializeAtBuildTime("com.sun.org.apache", JDK_CLASS_REASON);
151-
rci.initializeAtBuildTime("com.sun.org.slf4j.internal", JDK_CLASS_REASON);
140+
/*
141+
* still initialization due to the security services that reach the XMLSecurityManager
142+
*/
143+
rci.initializeAtBuildTime("javax.xml.catalog.CatalogImpl", "Security providers initialized at build time: jdk.xml.internal.XMLSecurityManager");
144+
rci.initializeAtBuildTime("javax.xml.catalog.CatalogResolver$NotFoundAction$1", "Security providers initialized at build time: jdk.xml.internal.XMLSecurityManager");
145+
rci.initializeAtBuildTime("javax.xml.catalog.CatalogResolver$NotFoundAction$2", "Security providers initialized at build time: jdk.xml.internal.XMLSecurityManager");
146+
rci.initializeAtBuildTime("javax.xml.catalog.CatalogResolver$NotFoundAction$3", "Security providers initialized at build time: jdk.xml.internal.XMLSecurityManager");
147+
rci.initializeAtBuildTime("javax.xml.catalog.SystemSuffix", "Security providers initialized at build time: jdk.xml.internal.XMLSecurityManager");
148+
rci.initializeAtBuildTime("javax.xml.catalog.SystemEntry", "Security providers initialized at build time: jdk.xml.internal.XMLSecurityManager");
149+
rci.initializeAtBuildTime("javax.xml.catalog.CatalogFeatures", "Security providers initialized at build time: jdk.xml.internal.XMLSecurityManager");
150+
rci.initializeAtBuildTime("javax.xml.catalog.BaseEntry$CatalogEntryType", "Security providers initialized at build time: jdk.xml.internal.XMLSecurityManager");
151+
rci.initializeAtBuildTime("javax.xml.catalog.CatalogFeatures$State", "Security providers initialized at build time: jdk.xml.internal.XMLSecurityManager");
152+
rci.initializeAtBuildTime("javax.xml.catalog.PublicEntry", "Security providers initialized at build time: jdk.xml.internal.XMLSecurityManager");
152153
} else {
154+
rci.initializeAtBuildTime("jdk.xml", JDK_CLASS_REASON);
155+
/*
156+
* The XML classes have cyclic class initializer dependencies, and class initialization
157+
* can deadlock/fail when initialization is started at the "wrong part" of the cycle.
158+
* Force-initializing the correct class of the cycle here, in addition to the
159+
* "whole package" initialization above, breaks the cycle because it triggers immediate
160+
* initilalization here before the static analysis is started.
161+
*/
162+
rci.initializeAtBuildTime("jdk.xml.internal.JdkXmlUtils", JDK_CLASS_REASON);
163+
153164
rci.initializeAtBuildTime("com.sun.xml", JDK_CLASS_REASON);
154165
rci.initializeAtBuildTime("com.sun.org.apache", JDK_CLASS_REASON);
155166
rci.initializeAtBuildTime("com.sun.org.slf4j.internal", JDK_CLASS_REASON);
@@ -229,8 +240,6 @@ public void afterRegistration(AfterRegistrationAccess access) {
229240
rci.initializeAtRunTime("jdk.internal.foreign.abi.fallback.FFIABI", "Fails build-time initialization");
230241
rci.initializeAtRunTime("sun.reflect.misc.Trampoline", "Fails build-time initialization");
231242

232-
rci.initializeAtRunTime("com.sun.org.apache.xml.internal.serialize.HTMLdtd", "Fails build-time initialization");
233-
234243
rci.initializeAtRunTime("sun.security.ssl.SSLContextImpl$DefaultSSLContextHolder", "Stores secure random");
235244
rci.initializeAtRunTime("sun.security.ssl.SSLSocketFactoryImpl", "Stores secure random");
236245
rci.initializeAtRunTime("sun.security.provider.certpath.ssl.SSLServerCertStore", "Stores secure random");

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/xml/JavaxXmlClassAndResourcesLoaderFeature.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -35,13 +35,15 @@
3535
import static com.oracle.svm.hosted.xml.XMLParsersRegistration.TransformerClassesAndResources;
3636

3737
import org.graalvm.nativeimage.hosted.FieldValueTransformer;
38+
import java.lang.reflect.Method;
3839

3940
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
4041
import com.oracle.svm.core.feature.InternalFeature;
4142
import com.oracle.svm.core.jdk.JNIRegistrationUtil;
4243
import com.oracle.svm.util.ReflectionUtil;
4344

4445
import jdk.graal.compiler.serviceprovider.JavaVersionUtil;
46+
import org.graalvm.nativeimage.hosted.RuntimeClassInitialization;
4547

4648
@AutomaticallyRegisteredFeature
4749
public class JavaxXmlClassAndResourcesLoaderFeature extends JNIRegistrationUtil implements InternalFeature {
@@ -90,5 +92,12 @@ private static void initializeJdkCatalog() {
9092
// The constructor call prepareCatalog which will call JdkCatalog#init.
9193
ReflectionUtil.newInstance(xmlSecurityManager);
9294
}
95+
RuntimeClassInitialization.initializeAtBuildTime("jdk.xml.internal.SecuritySupport");
96+
/*
97+
* Loads all properties for jdk.xml.internal.SecuritySupport at build-time to avoid
98+
* java.home usage.
99+
*/
100+
Method readConfigMethod = ReflectionUtil.lookupMethod(ReflectionUtil.lookupClass("jdk.xml.internal.SecuritySupport"), "readConfig", String.class);
101+
ReflectionUtil.invokeMethod(readConfigMethod, null, "do initialize");
93102
}
94103
}

0 commit comments

Comments
 (0)