[GR-69858] Make Native Image security provider inclusion metadata-driven - #14159
Open
graalvmbot wants to merge 63 commits into
Open
[GR-69858] Make Native Image security provider inclusion metadata-driven#14159graalvmbot wants to merge 63 commits into
graalvmbot wants to merge 63 commits into
Conversation
graalvmbot
force-pushed
the
vj/GR-69858-reflection-sec-providers
branch
from
August 5, 2026 08:30
d5f7d38 to
970fe83
Compare
Security provider analysis changes the timing of reachability callbacks and exposed a race in JNIAccessFeature. Reachability callbacks add JNI classes, methods, and fields concurrently with duringAnalysis(), but duringAnalysis() previously iterated each positive-registration worklist and then cleared it. A registration added after the weakly consistent iterator had passed an entry, but before clear(), was silently discarded.
This could drop the JNI metadata registered for java.net.NetworkInterface. Its runtime native initializer then failed FindClass("java/net/NetworkInterface") with NoClassDefFoundError in the recurring-callback SVM test image.
Remove each observed positive registration atomically before processing it instead of clearing the worklists afterward. Registrations not observed by the current iteration, or added concurrently after removal, remain queued for the next analysis iteration.
This reverts commit a3b5ef097c6c26a4f20d564b7923618997aa25be.
graalvmbot
force-pushed
the
vj/GR-69858-reflection-sec-providers
branch
from
August 7, 2026 11:10
56a526d to
19aac29
Compare
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.
Summary
This change makes security provider inclusion consistent with Native Image reachability metadata.
Provider classes discovered during analysis are treated as candidates rather than being included automatically. A concrete provider and all of its valid, resolvable services are included when the provider has a supported construction path and reflection metadata registers:
provider()factory method.The new
--future-defaults=explicit-security-provider-registrationbehavior applies this requirement to providers selected through reachable JCA factories and security-service facades such as GSS and SASL. Without that future default, the existing service-driven inclusion behavior remains available for compatibility.The Tracing Agent and native metadata tracing record provider lookups so applications can collect the required metadata automatically.
User impact
The
-H:AdditionalSecurityProvidersand-H:AdditionalSecurityServiceTypesoptions are now deprecated. Applications should instead:reachability-metadata.json; or-H:Preserve=allto retain all JDK providers.For example, replace:
with reflection metadata such as:
{ "reflection": [ { "type": "com.example.security.CustomProvider", "methods": [ { "name": "<init>", "parameterTypes": [] } ] } ] }The deprecated provider option remains accepted for compatibility and is translated into the corresponding reflection registration.
Use
--future-defaults=explicit-security-provider-registrationto adopt the metadata requirement now. It is also enabled by the preferred--future-defaults=all. This transition is independent of--future-defaults=run-time-initialize-security-providers, which constructs the configured provider list at run time and filters out unregistered providers while preserving the order of those that remain.SecureRandomdoes not retain service-driven provider inclusion. A reachableSecureRandomacquisition path supplies a platform-owned conditional provider-registration signal. Native Image then processes each applicable configured provider using the same complete-provider semantics as reflection metadata. Applications do not need separate provider metadata for this case, and no provider is registered when no acquisition path is reachable.Standard missing-registration diagnostics
With exact reachability metadata enabled, an omitted provider loaded reflectively is reported through the regular reflection missing-registration path rather than a provider-specific error. The resulting
MissingReflectionRegistrationErroridentifies the provider class and prints the same ready-to-copy metadata entry as other missing reflection accesses, for example:{ "type": "com.example.security.CustomProvider" }Using the standard reflection path means existing missing-registration tooling handles provider failures automatically, while the Tracing Agent and native metadata tracing collect the same provider reflection metadata.
Programmatic provider registration through
Security.addProvider(...)andSecurity.insertProviderAt(...)is traced as provider reflection access as well.Architecture
Independent transition axes
SecurityProviderModemodels provider inclusion and provider-list initialization as independentaxes. Hosted code reads that mode instead of consulting future-default options piecemeal, and
mode-specific substitutions are selected at image build time. Run-time system properties therefore
cannot change the policy with which the image was built.
Candidates, signals, and plans
SecurityServicesFeaturecoordinates the build lifecycle. ReachableProvidersubtypes andMETA-INF/services/java.security.Providerentries discover candidate classes only; neither is aninclusion signal by itself.
SecurityProviderRegistrationPlannerrecords complete-provider intent and its provenance:-H:Preserve=all;SecureRandomsignal;Qualifying application metadata is read through a narrow
ReflectionRegistrationView. The plannerkeeps this input separate from reflection metadata emitted while realizing a plan, so generated
metadata cannot be mistaken for a new application signal.
Subtype callbacks only add candidates to concurrent collections. A serialized
duringAnalysispass consumes signals, realizes newly completed plans, and requests anotheranalysis iteration. This avoids scheduling analysis iterations from concurrent reachability
callbacks.
Complete-provider realization
SecurityProviderCatalogRegistrarrealizes each complete-provider plan. It selects the supportedconstruction path, processes every configured instance of the provider class, registers the union
of their valid and resolvable service catalogs, and records the JCE verification result.
Providers that Native Image can construct are marked as JDK-constructible. A provider class that
is registered for reflection but has no supported JDK construction path is recorded as
application-supplied-only: its verification result is preserved, but Native Image neither
reconstructs it nor infers its services.
Typed run-time manifest and enforcement
Hosted registration writes
SecurityProviderRuntimeState, a layered manifest keyed by providerclass name. Each entry combines an acquisition kind (
JDK_CONSTRUCTIBLEorAPPLICATION_SUPPLIED_ONLY) with the preserved JCE verification outcome. Entries from imagelayers are merged so a JDK-constructible registration wins while verification failures remain
available.
Run-time responsibilities are split into small services:
BuiltInSecurityProviderLoaderowns built-in provider aliases and construction;SecurityProviderRuntimeAccessowns metadata tracing and missing-registration diagnostics; andJceProviderVerificationSupportadapts manifest entries to the JDK verification contract.Both provider-list initialization modes use this manifest. In build-time-list mode, the hosted
provider list and verification cache are filtered after provider plans are complete. In
run-time-list mode, substitutions rebuild the configured list from saved initial security
properties and allow the JDK to construct only providers marked JDK-constructible.
Descriptors, tracing, and compatibility
Explicit registration preserves
java.security.Providerservice descriptors without treating themas registration signals. Provider lookup, enumeration, and programmatic registration are traced as
reflection type access by both native metadata tracing and the Tracing Agent, so the same metadata
drives subsequent builds.
Deprecated provider options and legacy service-reachability inclusion are confined to
LegacySecurityProviderCompatibility. Removing the transition behavior does not require changes tothe planner, catalog registrar, run-time manifest, or planned-default substitutions.
Hello World image size
Measured on 2026-07-24 using native-image optimization level 2, without
-Ob.The before images use CE master
fdc2690a6eand EE masterea2a8732e6.With
--future-defaults=all:Without
--future-defaults: