Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GR-49525] Mechanism to move JDK initialization to run time. #10531

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -67,4 +67,11 @@ default void rerunInitialization(Class<?> aClass, String reason) {
}

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

/**
* Returns if the <code>className</code> 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);
}
3 changes: 2 additions & 1 deletion substratevm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ 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-59135) Verify if hosted options passed to `native-image` exist prior to starting the builder. Provide suggestions how to fix unknown options early on.
* (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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1271,6 +1271,10 @@ public Boolean getValueOrDefault(UnmodifiableEconomicMap<OptionKey<?>, 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<Boolean> 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<Boolean> InitializeJDKAtBuildTimeMigration = new HostedOptionKey<>(false);

@APIOption(name = "exact-reachability-metadata", defaultValue = "")//
@Option(help = "file:doc-files/ExactReachabilityMetadataHelp.txt")//
public static final HostedOptionKey<AccumulatingLocatableMultiOptionValue.Strings> ThrowMissingRegistrationErrors = new HostedOptionKey<>(AccumulatingLocatableMultiOptionValue.Strings.build());
Expand Down
Original file line number Diff line number Diff line change
@@ -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;

import java.util.function.Predicate;

import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport;

public class MarkedAsBuildTimeInitialized implements Predicate<String> {
@Override
public boolean test(String className) {
return ImageSingletons.lookup(RuntimeClassInitializationSupport.class).isMarkedForBuildTimeInitialization(className);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.oracle.svm.core.annotate.Substitute;
import com.oracle.svm.core.annotate.TargetClass;
import com.oracle.svm.core.jdk.JDKLatest;
import com.oracle.svm.core.jdk.MarkedAsBuildTimeInitialized;
import com.oracle.svm.util.ReflectionUtil;

/**
Expand All @@ -46,7 +47,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) //
Expand All @@ -63,7 +64,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) //
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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
}
}