Skip to content

[GR-73222] Make exact reflection a future default and exact reachability metadata a runtime option - #14158

Open
graalvmbot wants to merge 8 commits into
masterfrom
vj/GR-73222-exact-reflection-default
Open

[GR-73222] Make exact reflection a future default and exact reachability metadata a runtime option#14158
graalvmbot wants to merge 8 commits into
masterfrom
vj/GR-73222-exact-reflection-default

Conversation

@graalvmbot

Copy link
Copy Markdown
Collaborator

Summary

--exact-reachability-metadata used to serve two purposes at once: it made dynamic access exact, and it was the migration vehicle away from the legacy reflection behavior. This PR splits those two concerns:

  • --future-defaults=exact-reflection — the future default. It makes reflection, JNI, serialization, proxies, unsafe allocation and resource bundles exact, but keeps legacy behavior for Class.forName and ordinary resource lookups, so that enabling the future default does not turn every unregistered class name or missing resource into a MissingRegistrationError.
  • -XX:+ExactReachabilityMetadata — a global, immutable runtime option that additionally makes class-name lookup and ordinary resource lookup exact. --exact-reachability-metadata at build time only sets the executable's default for it.

The resulting state matrix:

--future-defaults=exact-reflection -XX:±ExactReachabilityMetadata Behavior
off off legacy behavior
off on full exact reachability metadata
on off exact reflection, legacy Class.forName and ordinary resources
on on full exact reachability metadata

Because exactness is now selected at executable startup, both behaviors have to be available in a single image: the build always encodes a superset of the metadata and the runtime filters it according to the active mode.

Option changes

  • SubstrateOptions.ThrowMissingRegistrationErrors (hosted, class/package-scoped) is replaced by SubstrateOptions.ConcealedOptions.ExactReachabilityMetadata, a RuntimeOptionKey<Boolean> with Immutable (startup-only, so lookup semantics cannot change while the application runs).
  • --exact-reachability-metadata stays as the @APIOption, now a boolean that sets the executable's runtime default. Package/class arguments are no longer accepted.
  • --exact-reachability-metadata-path and its help file are removed.
  • MissingRegistrationSupport no longer holds an OptionClassFilter; hosted plugins always behave as if exactness were on, so the metadata needed by either runtime mode is retained.

Predicate split

Every former throwMissingRegistrationErrors() check was audited and moved to exactly one of two predicates in MissingRegistrationUtils:

  • exactReflection() = exact-reflection future default or the runtime option. Used by DynamicHub class/member queries, hiding and negative queries, array creation, unsafe allocation (SubstrateAllocationSnippets), JNIReflectionDictionary class/method/field lookup, ClassLoader#defineClass, proxies, serialization and resource bundles.
  • exactReachabilityMetadata() = the runtime option only. Used by Class.forName/bootstrap/loaded-class lookup in ClassRegistries, array class names resolved through those entry points (so DynamicHub.arrayType() cannot leak a future-default error), and ordinary resource lookups in Resources and NativeImageResourceFileSystem.

FutureDefaultsOptions.exactReflection() is @Folded so the future-default half of the predicate is a build-time constant, while the runtime flag stays dynamic — this is required for the allocation snippets, which cannot parse a non-folded lookup.

Missing-registration reporting for JNI field/method access and for defineClass now returns/throws the error directly instead of relying on the caller to continue, which removes the previous sneakyThrow of ClassNotFoundException on the defineClass path.

Build-time metadata is now mode-independent

  • ResourcesFeature/Resources: resource include patterns and negative resource queries are always stored, so a missing resource can be distinguished from a resource covered by a glob at runtime in either mode.
  • NativeImageCodeCache: negative field/method/constructor query metadata is always encoded.
  • ReflectionDataBuilder: hiding fields/methods, declaring types of individually registered members, and implicit inner-class registrations are all recorded unconditionally, so the legacy and exact views coexist.
  • Fields that are only accessible because of legacy inference are marked with a new LEGACY_ACCESS_FLAG in the encoded metadata; RuntimeMetadataDecoderImpl hides their offset when exactness is active, so the Field object stays queryable but not accessible.
  • Types that are unsafe-allocatable only for legacy compatibility are marked with ADDITIONAL_FLAGS_LEGACY_UNSAFE_ALLOCATION_BIT in DynamicHub; in exact mode the hub falls back to the explicitly registered unsafe-allocation metadata.
  • RegistryAdapter/ReflectionRegistryAdapter: unresolvable configuration entries always become negative queries instead of throwing; with -H:+StrictConfiguration they are reported as warnings.

Documentation

  • ExactReachabilityMetadataHelp.txt rewritten for the boolean/runtime semantics; ExactReachabilityMetadataPathHelp.txt deleted.
  • FutureDefaultsHelp.txt describes what exact-reflection covers and points to -XX:+ExactReachabilityMetadata for the stronger mode.
  • ReachabilityMetadata.md, BuildOptions.md (regenerated table), the troubleshooting guide and the bundled Native Image skill references drop the package/path scoping and document the runtime option.

@oracle-contributor-agreement oracle-contributor-agreement Bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Aug 4, 2026
@graalvmbot
graalvmbot force-pushed the vj/GR-73222-exact-reflection-default branch from 9b80b04 to d38d8fa Compare August 6, 2026 16:09
@graalvmbot
graalvmbot force-pushed the vj/GR-73222-exact-reflection-default branch from 0067aed to fb639b7 Compare August 7, 2026 11:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

OCA Verified All contributors have signed the Oracle Contributor Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants