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

Adopt new GraalVM reachability metadata format #33847

Closed
bclozel opened this issue Nov 6, 2024 · 0 comments
Closed

Adopt new GraalVM reachability metadata format #33847

bclozel opened this issue Nov 6, 2024 · 0 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) theme: aot An issue related to Ahead-of-time processing type: enhancement A general enhancement
Milestone

Comments

@bclozel
Copy link
Member

bclozel commented Nov 6, 2024

As of Spring Framework 7.0, we should completely adopt the new GraalVM reachability metadata format. This format has been simplified and now has a dedicated JSON schema.

There are a few notable behavior changes.

The registration of resources has changed, this is already described in a separate issue, see #31340.

The metadata conditions have changed from "typeReachable" from "typeReached". Previously, "typeReachable" would imply that a type is reachable through static analysis. This depends too much on the capabilities of the static analysis and can be hard to predict. Instead, "typeReached" means that the type "A type is reached at run time, right before the class-initialization routine starts for that type (class or interface), or any of the type’s subtypes are reached." This changes the metadata format but shouldn't change much for our support. This would only affect projects and apps that use a condition with a type that is not strictly initialized, like an interface.

The metadata for proxy generation is now part of the reflection metadata. This doesn't change our RuntimeHints API but we should adapt our JSON serialization format accordingly.

Several convenience reflection flags have been removed. "allDeclaredConstructors", "allPublicConstructors", "allDeclaredMethods", "allPublicMethods" enable reflective invocation of constructors and methods, and are still supported. "queryAllPublicConstructors", "queryAllDeclaredConstructors", "queryAllPublicMethods", "queryAllDeclaredMethods", "allPublicClasses", "allDeclaredClasses" enable reflective introspection and have been removed since this is now done automatically as soon as a reflection metadata entry is added for the declaring type. As a result, several parts of our RuntimeHints will be made useless; we should decide whether we want to deprecate it or just ignore its results during the JSON metadata generation.

We can test the new reachability behavior by using a VM option:

To get an overview of all places in your code where missing registrations occur, without committing to the exact behavior, you can pass -XX:MissingRegistrationReportingMode=Warn when starting the application.

To detect places where the application accidentally ignores a missing registration error (with catch (Throwable t) blocks), pass -XX:MissingRegistrationReportingMode=Exit when starting the application. The application will then unconditionally print the error message with the stack trace and exit immediately. This behavior is ideal for running application tests to guarantee all metadata is included.

@bclozel bclozel added in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement theme: aot An issue related to Ahead-of-time processing labels Nov 6, 2024
@bclozel bclozel added this to the 7.0.x milestone Nov 6, 2024
@bclozel bclozel self-assigned this Nov 6, 2024
@bclozel bclozel modified the milestones: 7.0.x, 7.0.0-M1 Nov 29, 2024
bclozel added a commit that referenced this issue Nov 29, 2024
As of GraalVM 23, a new and simplified reachability metadata format is
available. Metadata now consists of a single
"reachability-metadata.json" file that contains all the information
previously spread in multiple files. The new format does not include
some introspection flags, as they're now automatically included when a
hint is registered against a type.
Also, "typeReachable" has been renamed as "typeReached" to highlight the
fact that the event considered is the static initialization of the type,
not when the static analysis performed during native compilation is
reaching the type.

This new format ships with a JSON schema, which this commit is tested
against.

See gh-33847
bclozel added a commit that referenced this issue Nov 29, 2024
The `RuntimeHints` API mainly reflects what is needed to write GraalVM
reachability metadata. The latest GraalVM version simplified its
format. This commit applies relevant simplifications as parts of it are
not needed anymore.

The new metadata format implies methods, constructors and fields
introspection as soon as a reflection hint is registered for a type. As
a result, `ExecutableMode.INTROSPECT`, and all `MemberCategory` values
except `MemberCategory.INVOKE_*` are being deprecated.
They have no replacement, as registering a type hint is enough.
In practice, it is enough to replace this:

```
hints.reflection().registerType(MyType.class, MemberCategory.DECLARED_FIELDS);
```

By this:
```
hints.reflection().registerType(MyType.class);
```

As for `MemberCategory.PUBLIC_FIELDS` and `MemberCategory.DECLARED_FIELDS`,
values were replaced by `INVOKE_PUBLIC_FIELDS` and
`INVOKE_DECLARED_FIELDS` to make their original intent clearer and align
with the rest of the API. Note, if you were using those values for
reflection only, you can safely remove those hints in favor of a simple
type hint.

See gh-33847
bclozel added a commit that referenced this issue Nov 29, 2024
This Java agent has been designed to instrument specific JDK calls for
reflective introspection and invocations. This is useful for testing
runtime hints in integration tests.

As of GraalVM 23, there is a new VM option that does this in a much more
efficient and precise fashion. Developers can use the
`-XX:MissingRegistrationReportingMode` with the "Warn" or "Exit" value.
The option will look for reachability metadata and emit logs in "Warn"
mode or immediately exit the application with in "Exit" mode.

This commit deprecates the `RuntimeHintsAgent` in favor of this new,
more reliable option.

See gh-33847
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) theme: aot An issue related to Ahead-of-time processing type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

1 participant