Repository navigation
[GR-51046] Verify all objects reachable through build-time-initialized static fields - #14722
Open
graalvmbot wants to merge 1 commit into
Open
graalvmbot wants to merge 1 commit into
graalvmbot wants to merge 1 commit into
Conversation
graalvmbot
force-pushed
the
dlano/GR-51046/predictable-buildtime-init
branch
6 times, most recently
from
October 22, 2026 18:00
e7bb624 to
9a3a8a3
Compare
graalvmbot
force-pushed
the
dlano/GR-51046/predictable-buildtime-init
branch
from
October 22, 2026 19:30
9a3a8a3 to
5505643
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds
--future-defaults=predictable-build-time-initialization.By default, Native Image verifies that objects included in the executable's image heap are instances
of build-time initialized classes and are allowed in the image heap.
With this option, verification extends to any object referenced directly or indirectly by static
fields of build-time initialized classes that could become part of the image heap, regardless of
the results of reachability analysis.
Why?
Correctness of the build should not depend on reachability analysis.
User-facing changes
This is a breaking change introduced behind
--future-defaults=predictable-build-time-initialization.The verification works as follows:
build-time initialized class and every object referenced transitively through instance fields or array elements.
with a
FieldValueTransformer, followed by replacing the object with anObjectReplacer.Verification applies only to the resulting object.
FieldValueTransformer, verification of that value is deferred until it becomes available.beforeImageWriteat the latest.initialized at build time and must satisfy Native Image's restrictions on objects allowed in the
image heap.
identifies the violation, provides a reference path from a build-time initialized class to the
offending object, and suggests possible resolutions.
As a result, enabling this option can cause a previously successful build to fail even without
application code changes, for example: when an unused field was previously unchecked.
This feature does not change the contents of the executable: checking a field does not cause its
contents to be included.
Example
This example shows the difference in behavior.
The build-time initialized class
Rootholds a single static field that is not deemed reachable by the static analysis.The field references, through a
Wrapper, an instance of a run-time initialized classUnreachableValue.Previously, this program built successfully. However, an unrelated code change could make the
field reachable and cause the build to fail.
With
--future-defaults=predictable-build-time-initialization, the build fails predictably evenwhile the field remains unreachable, with the following message:
The error message identifies:
UnreachableValueRoot, which was previously missing.Root.unreachable.valueRootat run time, which is the safer option.UnreachableValueat build time.The suggested resolution shows that initializing
Rootat run time safely prevents this exceptionby preventing the root's static state from being persisted in the image heap.
Public API Changes
The public
FeatureAPI changes regardingFieldValueTransformers as follows:BeforeAnalysisAccess.registerBeforeFieldValueAccessHandler(BiConsumer<BeforeFieldValueAccess, Class<?>>, Class<?>)registers a handler that can register field value transformers on demand, before field values are accessed.
declared by that class, passing the declaring class as the handler's second argument.
BeforeFieldValueAccessis a new interface:registerFieldValueTransformer(Field, FieldValueTransformer), which the handleruses to register a transformer for a field before any field declared by the same class is accessed.
BeforeAnalysisAccessextends this interface because both interfaces share the method forregistering field value transformers.
--future-defaults=predictable-build-time-initialization, registration ofFieldValueTransformers can only be done before analysis starts or in abeforeFieldValueAccesshandler.These changes are required to allow a field's value to be accessed through a field value
transformer without affecting the reachability status of the field or its declaring class, and
therefore without requiring a reachability handler for that class to be invoked.
Accessing the value allows the verification described above without changing the image contents
determined by analysis.
Review Entry Points
PredictableBuildTimeInitializationFeaturecontains the main implementation. It is invoked fromNativeImageGeneratorafter allbeforeAnalysiscallbacks have completed and class initializationconfiguration has been sealed.
HeapObjectReplacer,HeapObjectConstantReplacer, and their implementations distinguishreplacements that require reachable objects or use internal operations to modify the image heap or hosted/
analysis universe.
FieldValueTransformerRequiresUniversemarks transformers that use internal operations tomodify the image heap or analysis/hosted universe.
PredictableBuildTimeInitializationLookupLayerand its associated type and field classes provideaccess to substituted types without creating new analysis types.
FieldValueInterceptionSupportnow supports non-analysis fields and handlesbeforeFieldValueAccesscallbacks.Limitations
FieldValueTransformerRequiresUniverse) orreplacers (
HeapObjectConstantReplacer) still depends on reachability.HeapObjectConstantReplaceris internal-only. If a user-implemented replacer modifies anunrelated class, it could still theoretically change the image contents. This limitation is
acceptable because it limits the changes required in user code for this feature.
--future-defaults=predictable-build-time-initializationand have already verified their roots.