quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.87k stars 2.71k forks source link

Enable `--exact-reachability-metadata` with Mandrel >= 23.1 (GraalVM for JDK 21) #41995

Open zakkak opened 4 months ago

zakkak commented 4 months ago

Description

Background

Starting with Mandrel 23.0 (GraalVM for JDK 17) an option -H:+ThrowMissingRegistrationErrors was introduced to throw an exception

when it is impossible to tell whether a reflective query should fail because the queried element has not been registered at build-time, or because it doesn't exist.

See https://github.com/oracle/graal/pull/6139

Starting with Mandrel 23.1 (GraalVM for JDK 21) the option was extended to also cover other elements, e.g., classes, resources, etc.

See https://github.com/oracle/graal/blob/release/graal-vm/23.1/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/doc-files/MissingRegistrationHelp.txt and https://github.com/oracle/graal/pull/6448

Starting with Mandrel 24.1 (GraalVM for JDK 23) the option will be available as a public flag (meaning it's no longer experimental) with the intention to ultimately become the default.

See https://github.com/oracle/graal/blob/release/graal-vm/24.1/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/doc-files/ExactReachabilityMetadataHelp.txt, https://github.com/oracle/graal/issues/5173#issuecomment-1752811101 and https://github.com/oracle/graal/pull/9036

Pros

Enabling the flag by default seems like a good idea since it will notify the users about elements that the code tries to access reflectively but have not been registered, which right now is leading in unexpected behavior without the users even knowing in some cases (for an example see https://github.com/quarkusio/quarkus/issues/37626).

Cons/Difficulties

The so far identified cons and difficulties of having this option enabled by default are:

  1. The exception is only thrown at runtime, so one needs to run the native executable to see if it will throw the exception. This requires several run-fix-build-run cycles which is tedious... The process can be sped up by using the native-image-agent to generate the reachability-metadata configuration, but it still depends highly on how good coverage the run will have.
  2. Some libraries "blindly" try to access resources, e.g. SmallRye tries to find various configuration files in a few places leading to an exception being thrown even if in Quarkus we know we don't need these resources. Registering the said resources resolves the issue, but comes with the drawback that if any of these resources happens to be found at build-time it will actually end up in the native-executable and get loaded at run-time, which right now is not and the effects of it are unknown (see https://github.com/quarkusio/quarkus/issues/41994)
  3. We need to make sure that registering things to avoid the exception doesn't change the intended behavior. E.g. if we don't want a configuration to be accessed at run-time we need to somehow make sure it's also not present at build-time so that it doesn't end up getting embedded in the native executable.

Implementation ideas

WIP PR https://github.com/quarkusio/quarkus/pull/36378

quarkus-bot[bot] commented 4 months ago

/cc @Karm (mandrel), @galderz (mandrel)