Skip to content

Commit 7b99a84

Browse files
author
Christian Wimmer
committed
Remove the old class initialization strategy
1 parent 5597913 commit 7b99a84

25 files changed

+467
-1823
lines changed

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

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2024, 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
@@ -46,11 +46,25 @@ public interface RuntimeClassInitializationSupport {
4646

4747
void initializeAtBuildTime(String name, String reason);
4848

49-
void rerunInitialization(String name, String reason);
49+
@Deprecated
50+
default void rerunInitialization(String name, String reason) {
51+
/*
52+
* There is no more difference between initializing a class at run-time and re-running the
53+
* class initializer at run time.
54+
*/
55+
initializeAtRunTime(name, reason);
56+
}
5057

5158
void initializeAtRunTime(Class<?> aClass, String reason);
5259

53-
void rerunInitialization(Class<?> aClass, String reason);
60+
@Deprecated
61+
default void rerunInitialization(Class<?> aClass, String reason) {
62+
/*
63+
* There is no more difference between initializing a class at run-time and re-running the
64+
* class initializer at run time.
65+
*/
66+
initializeAtRunTime(aClass, reason);
67+
}
5468

5569
void initializeAtBuildTime(Class<?> aClass, String reason);
5670
}

substratevm/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
This changelog summarizes major changes to GraalVM Native Image.
44

55
## GraalVM for JDK 23 (Internal Version 24.1.0)
6+
* (GR-51520) The old class initialization strategy, which was deprecated in GraalVM for JDK 22, is removed. The option `StrictImageHeap` no longer has any effect.
67
* (GR-51106) Fields that are accessed via a `VarHandle` or `MethodHandle` are no longer marked as "unsafe accessed" when the `VarHandle`/`MethodHandle` can be fully intrinsified.
78
* (GR-49996) Ensure explicitly set image name (e.g., via `-o imagename`) is not accidentally overwritten by `-jar jarfile` option.
89
* (GR-48683) Together with Red Hat, we added partial support for the JFR event `OldObjectSample`.

substratevm/mx.substratevm/mx_substratevm.py

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,11 +1547,7 @@ def cinterfacetutorial(args):
15471547

15481548
@mx.command(suite.name, 'clinittest', 'Runs the ')
15491549
def clinittest(args):
1550-
def build_and_test_clinittest_images(native_image, args=None):
1551-
build_and_test_clinittest_image(native_image, args, True)
1552-
build_and_test_clinittest_image(native_image, args, False)
1553-
1554-
def build_and_test_clinittest_image(native_image, args, new_class_init_policy):
1550+
def build_and_test_clinittest_image(native_image, args):
15551551
args = [] if args is None else args
15561552
test_cp = classpath('com.oracle.svm.test')
15571553
build_dir = join(svmbuild_dir(), 'clinittest')
@@ -1561,11 +1557,6 @@ def build_and_test_clinittest_image(native_image, args, new_class_init_policy):
15611557
mx.rmtree(build_dir)
15621558
mx.ensure_dir_exists(build_dir)
15631559

1564-
if new_class_init_policy:
1565-
policy_args = svm_experimental_options(['-H:+SimulateClassInitializer']) + ['--features=com.oracle.svm.test.clinit.TestClassInitializationFeatureNewPolicyFeature']
1566-
else:
1567-
policy_args = svm_experimental_options(['-H:-StrictImageHeap', '-H:-SimulateClassInitializer']) + ['--features=com.oracle.svm.test.clinit.TestClassInitializationFeatureOldPolicyFeature']
1568-
15691560
# Build and run the example
15701561
binary_path = join(build_dir, 'clinittest')
15711562
native_image([
@@ -1575,9 +1566,10 @@ def build_and_test_clinittest_image(native_image, args, new_class_init_policy):
15751566
'-o', binary_path,
15761567
'-H:+ReportExceptionStackTraces',
15771568
'-H:Class=com.oracle.svm.test.clinit.TestClassInitialization',
1569+
'--features=com.oracle.svm.test.clinit.TestClassInitializationFeature',
15781570
] + svm_experimental_options([
15791571
'-H:+PrintClassInitialization',
1580-
]) + policy_args + args)
1572+
]) + args)
15811573
mx.run([binary_path])
15821574

15831575
# Check the reports for initialized classes
@@ -1591,16 +1583,8 @@ def checkLine(line, marker, init_kind, msg, wrongly_initialized_lines):
15911583
"Classes marked with " + marker + " must have init kind " + init_kind + " and message " + msg)]
15921584
with open(classes_file) as f:
15931585
for line in f:
1594-
if new_class_init_policy:
1595-
checkLine(line, "MustBeSafeEarly", "SIMULATED", "classes are initialized at run time by default", wrongly_initialized_lines)
1596-
checkLine(line, "MustBeSafeLate", "SIMULATED", "classes are initialized at run time by default", wrongly_initialized_lines)
1597-
checkLine(line, "MustBeSimulated", "SIMULATED", "classes are initialized at run time by default", wrongly_initialized_lines)
1598-
checkLine(line, "MustBeDelayed", "RUN_TIME", "classes are initialized at run time by default", wrongly_initialized_lines)
1599-
else:
1600-
checkLine(line, "MustBeSafeEarly", "BUILD_TIME", "class proven as side-effect free before analysis", wrongly_initialized_lines)
1601-
checkLine(line, "MustBeSafeLate", "BUILD_TIME", "class proven as side-effect free after analysis", wrongly_initialized_lines)
1602-
checkLine(line, "MustBeSimulated", "RUN_TIME", "classes are initialized at run time by default", wrongly_initialized_lines)
1603-
checkLine(line, "MustBeDelayed", "RUN_TIME", "classes are initialized at run time by default", wrongly_initialized_lines)
1586+
checkLine(line, "MustBeSimulated", "SIMULATED", "classes are initialized at run time by default", wrongly_initialized_lines)
1587+
checkLine(line, "MustBeDelayed", "RUN_TIME", "classes are initialized at run time by default", wrongly_initialized_lines)
16041588

16051589
if len(wrongly_initialized_lines) > 0:
16061590
msg = ""
@@ -1613,7 +1597,7 @@ def checkLine(line, marker, init_kind, msg, wrongly_initialized_lines):
16131597

16141598
check_class_initialization(all_classes_file)
16151599

1616-
native_image_context_run(build_and_test_clinittest_images, args)
1600+
native_image_context_run(build_and_test_clinittest_image, args)
16171601

16181602

16191603
class SubstrateJvmFuncsFallbacksBuilder(mx.Project):

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JNIRegistrationUtil.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ protected static boolean isWindows() {
6565
return Platform.includedIn(Platform.WINDOWS.class);
6666
}
6767

68-
protected static void rerunClassInit(FeatureAccess access, String... classNames) {
68+
protected static void initializeAtRunTime(FeatureAccess access, String... classNames) {
6969
RuntimeClassInitializationSupport classInitSupport = ImageSingletons.lookup(RuntimeClassInitializationSupport.class);
7070
for (String className : classNames) {
71-
classInitSupport.rerunInitialization(clazz(access, className), "for JDK native code support via JNI");
71+
classInitSupport.initializeAtRunTime(clazz(access, className), "for JDK native code support via JNI");
7272
}
7373
}
7474

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JavaNetHttpFeature.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public void afterRegistration(AfterRegistrationAccess access) {
5656
public void duringSetup(DuringSetupAccess access) {
5757
RuntimeClassInitializationSupport rci = ImageSingletons.lookup(RuntimeClassInitializationSupport.class);
5858
rci.initializeAtRunTime("jdk.internal.net.http", "for reading properties at run time");
59-
rci.rerunInitialization("jdk.internal.net.http.websocket.OpeningHandshake", "contains a SecureRandom reference");
59+
rci.initializeAtRunTime("jdk.internal.net.http.websocket.OpeningHandshake", "contains a SecureRandom reference");
6060
}
6161

6262
@Override

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RecomputedFields.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ private void processFieldUpdater(Object updater) {
296296
class InnocuousForkJoinWorkerThreadFeature implements InternalFeature {
297297
@Override
298298
public void duringSetup(DuringSetupAccess access) {
299-
ImageSingletons.lookup(RuntimeClassInitializationSupport.class).rerunInitialization(access.findClassByName("java.util.concurrent.ForkJoinWorkerThread$InnocuousForkJoinWorkerThread"),
299+
ImageSingletons.lookup(RuntimeClassInitializationSupport.class).initializeAtRunTime(access.findClassByName("java.util.concurrent.ForkJoinWorkerThread$InnocuousForkJoinWorkerThread"),
300300
"innocuousThreadGroup must be initialized at run time");
301301
}
302302
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ protected void setupNativeImage(OptionValues options, Map<Method, CEntryPointDat
895895
ImageSingletons.add(LinkAtBuildTimeSupport.class, new LinkAtBuildTimeSupport(loader, classLoaderSupport));
896896
ImageSingletons.add(ObservableImageHeapMapProvider.class, new ObservableImageHeapMapProviderImpl());
897897

898-
ClassInitializationSupport classInitializationSupport = ClassInitializationSupport.create(originalMetaAccess, loader);
898+
ClassInitializationSupport classInitializationSupport = new ClassInitializationSupport(originalMetaAccess, loader);
899899
ImageSingletons.add(RuntimeClassInitializationSupport.class, classInitializationSupport);
900900
ClassInitializationFeature.processClassInitializationOptions(classInitializationSupport);
901901

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SecurityServicesFeature.java

Lines changed: 23 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@
8080
import javax.security.auth.callback.CallbackHandler;
8181
import javax.security.auth.login.Configuration;
8282

83-
import jdk.graal.compiler.options.Option;
8483
import org.graalvm.nativeimage.ImageSingletons;
8584
import org.graalvm.nativeimage.hosted.RuntimeJNIAccess;
8685
import org.graalvm.nativeimage.hosted.RuntimeReflection;
@@ -107,6 +106,7 @@
107106
import com.oracle.svm.util.ModuleSupport;
108107
import com.oracle.svm.util.ReflectionUtil;
109108

109+
import jdk.graal.compiler.options.Option;
110110
import sun.security.jca.ProviderList;
111111
import sun.security.provider.NativePRNG;
112112
import sun.security.x509.OIDMap;
@@ -239,63 +239,50 @@ public void duringSetup(DuringSetupAccess a) {
239239
RuntimeClassInitializationSupport rci = ImageSingletons.lookup(RuntimeClassInitializationSupport.class);
240240
/*
241241
* The SecureRandom implementations open the /dev/random and /dev/urandom files which are
242-
* used as sources for entropy. These files are opened in the static initializers. That's
243-
* why we rerun the static initializers at runtime. We cannot completely delay the static
244-
* initializers execution to runtime because the SecureRandom classes are needed by the
245-
* native image generator too, e.g., by Files.createTempDirectory().
242+
* used as sources for entropy. These files are opened in the static initializers.
246243
*/
247-
rci.rerunInitialization(NativePRNG.class, "for substitutions");
248-
rci.rerunInitialization(NativePRNG.Blocking.class, "for substitutions");
249-
rci.rerunInitialization(NativePRNG.NonBlocking.class, "for substitutions");
244+
rci.initializeAtRunTime(NativePRNG.class, "for substitutions");
245+
rci.initializeAtRunTime(NativePRNG.Blocking.class, "for substitutions");
246+
rci.initializeAtRunTime(NativePRNG.NonBlocking.class, "for substitutions");
250247

251-
rci.rerunInitialization(clazz(access, "sun.security.provider.SeedGenerator"), "for substitutions");
252-
rci.rerunInitialization(clazz(access, "sun.security.provider.SecureRandom$SeederHolder"), "for substitutions");
248+
rci.initializeAtRunTime(clazz(access, "sun.security.provider.SeedGenerator"), "for substitutions");
249+
rci.initializeAtRunTime(clazz(access, "sun.security.provider.SecureRandom$SeederHolder"), "for substitutions");
253250

254251
/*
255252
* sun.security.provider.AbstractDrbg$SeederHolder has a static final EntropySource seeder
256-
* field that needs to be re-initialized at run time because it captures the result of
253+
* field that needs to be initialized at run time because it captures the result of
257254
* SeedGenerator.getSystemEntropy().
258255
*/
259-
rci.rerunInitialization(clazz(access, "sun.security.provider.AbstractDrbg$SeederHolder"), "for substitutions");
256+
rci.initializeAtRunTime(clazz(access, "sun.security.provider.AbstractDrbg$SeederHolder"), "for substitutions");
260257
if (isMscapiModulePresent) {
261258
/* PRNG.<clinit> creates a Cleaner (see JDK-8210476), which starts its thread. */
262-
rci.rerunInitialization(clazz(access, "sun.security.mscapi.PRNG"), "for substitutions");
259+
rci.initializeAtRunTime(clazz(access, "sun.security.mscapi.PRNG"), "for substitutions");
263260
}
264-
rci.rerunInitialization(clazz(access, "sun.security.provider.FileInputStreamPool"), "for substitutions");
261+
rci.initializeAtRunTime(clazz(access, "sun.security.provider.FileInputStreamPool"), "for substitutions");
265262
/* java.util.UUID$Holder has a static final SecureRandom field. */
266-
rci.rerunInitialization(clazz(access, "java.util.UUID$Holder"), "for substitutions");
263+
rci.initializeAtRunTime(clazz(access, "java.util.UUID$Holder"), "for substitutions");
267264

268-
/*
269-
* The classes below have a static final SecureRandom field. Note that if the classes are
270-
* not found as reachable by the analysis registering them for class initialization rerun
271-
* doesn't have any effect.
272-
*/
273-
rci.rerunInitialization(clazz(access, "sun.security.jca.JCAUtil$CachedSecureRandomHolder"), "for substitutions");
274-
rci.rerunInitialization(clazz(access, "com.sun.crypto.provider.SunJCE$SecureRandomHolder"), "for substitutions");
275-
optionalClazz(access, "sun.security.krb5.Confounder").ifPresent(clazz -> rci.rerunInitialization(clazz, "for substitutions"));
276-
optionalClazz(access, "sun.security.krb5.Config").ifPresent(clazz -> rci.rerunInitialization(clazz, "Reset the value of lazily initialized field sun.security.krb5.Config#singleton"));
265+
/* The classes below have a static final SecureRandom field. */
266+
rci.initializeAtRunTime(clazz(access, "sun.security.jca.JCAUtil$CachedSecureRandomHolder"), "for substitutions");
267+
rci.initializeAtRunTime(clazz(access, "com.sun.crypto.provider.SunJCE$SecureRandomHolder"), "for substitutions");
268+
optionalClazz(access, "sun.security.krb5.Confounder").ifPresent(clazz -> rci.initializeAtRunTime(clazz, "for substitutions"));
269+
optionalClazz(access, "sun.security.krb5.Config").ifPresent(clazz -> rci.initializeAtRunTime(clazz, "Reset the value of lazily initialized field sun.security.krb5.Config#singleton"));
277270

278-
rci.rerunInitialization(clazz(access, "sun.security.jca.JCAUtil"), "JCAUtil.def holds a SecureRandom.");
271+
rci.initializeAtRunTime(clazz(access, "sun.security.jca.JCAUtil"), "JCAUtil.def holds a SecureRandom.");
279272

280273
/*
281274
* When SSLContextImpl$DefaultManagersHolder sets-up the TrustManager in its initializer it
282275
* gets the value of the -Djavax.net.ssl.trustStore and -Djavax.net.ssl.trustStorePassword
283-
* properties from the build machine. Re-runing its initialization at run time is required
284-
* to use the run time provided values.
276+
* properties from the build machine. Running its initialization at run time is required to
277+
* use the run time provided values.
285278
*/
286-
rci.rerunInitialization(clazz(access, "sun.security.ssl.SSLContextImpl$DefaultManagersHolder"), "for reading properties at run time");
279+
rci.initializeAtRunTime(clazz(access, "sun.security.ssl.SSLContextImpl$DefaultManagersHolder"), "for reading properties at run time");
287280

288281
/*
289282
* SSL debug logging enabled by javax.net.debug system property is setup during the class
290-
* initialization of either sun.security.ssl.Debug or sun.security.ssl.SSLLogger. (In JDK 8
291-
* this was implemented in sun.security.ssl.Debug, the logic was moved to
292-
* sun.security.ssl.SSLLogger in JDK11 but not yet backported to all JDKs. See JDK-8196584
293-
* for details.) We cannot prevent these classes from being initialized at image build time,
294-
* so we have to reinitialize them at run time to honour the run time passed value for the
295-
* javax.net.debug system property.
283+
* initialization.
296284
*/
297-
optionalClazz(access, "sun.security.ssl.Debug").ifPresent(c -> rci.rerunInitialization(c, "for reading properties at run time"));
298-
optionalClazz(access, "sun.security.ssl.SSLLogger").ifPresent(c -> rci.rerunInitialization(c, "for reading properties at run time"));
285+
rci.initializeAtRunTime(clazz(access, "sun.security.ssl.SSLLogger"), "for reading properties at run time");
299286
}
300287

301288
@Override

0 commit comments

Comments
 (0)