[GR-69577] Make --future-defaults=complete-reflection-types default #12521
+388
−141
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 makes the reflection registration code unconditionally consider types registered through the
"name"property ofreflect-config.jsonin the same way as those registered through the"type"property ofreachability-metadata.json, which enables a big reduction in the complexity of that code, which will be tackled as part of GR-67330. Reflective access registration will now only need to be specified in terms of classes, methods and fields, removing the need for fine-grained registration methods such asRuntimeReflection.registerAsQueried(Executable)orRuntimeReflection.registerNestMembers(Class).This update required several fixes to adapt some parts of the codebase to handle queried-only methods, which are now more prevalent. These fixes are split into separate commits to facilitate reviewing.
Metadata changes
Without this future default, users are able to create
reflect-config.jsonlike the following:[ { "name": "registered.ReflectionType", "queryAllDeclaredMethods": true, "queryAllPublicMethods": true, "queryAllDeclaredConstructors": true, "queryAllPublicConstructors": true, "allDeclaredClasses": true, "allPublicClasses": true, "allNestMembers": true, "allPermittedSubclasses": true, "allRecordComponents": true, "allSigners": true } ]This file is strictly equivalent to the following
reachability-metadata.jsonfile using our latest metadata format:{ "reflection": [ { "type": "registered.ReflectionType" } ] }The future default
--complete-reflection-typesmakes the followingreflect-config.jsonfile behave the same way as the two files above:[ { "name": "registered.ReflectionType", } ]This effectively deprecates all the extra fields present in the first
reflect-config.jsonfile, and allows a great simplification of the internal reflection logic since these fields can't be set individually anymore.Backwards compatibility
These changes cause a strict increase of reflection registrations. Users may see a small increase in image size, which has been documented in #7753 and deemed acceptable.
Existing code will not see reflective queries fail where they previously succeeded. However, there is one scenario which may cause failures. Code using the following pattern:
may rely on the fact that
getMethods()currently only returns the subset of methods that have been registered for reflection whenclazzwas registered through"name"inreflect-config.json. One of the consequences of this PR is thatgetMethods()will now either fail (when the class is not registered) or return the complete list of public methods for the class, some of which might satisfy theconditionand be invoked, triggering aMissingReflectionRegistrationErroras they have not been registered for reflective invocation.It is important to note here that this invocation is the expected behavior of the program, which was excluded by the user through incomplete reflection registration. This code pattern, where users rely on Native Image deviating from the standard Java behavior, is one of the primary reasons that led to the introduction of complete reflection types. It is therefore expected that users will have to adapt in this case. The fix for this type of issue is very simple: the user only has to add the missing method (or field, as
getFields()can be used in the same way) to the reachability metadata, which is made trivially easy by the new missing registration error messages introduced recently.