oracle / graal

GraalVM compiles Java applications into native executables that start instantly, scale fast, and use fewer compute resources šŸš€
https://www.graalvm.org
Other
20.45k stars 1.64k forks source link

[GR-53064] Require to explicitly specify all substitutions that are used in the Native Image build #8683

Open vjovanov opened 8 months ago

vjovanov commented 8 months ago

TL;DR

The Native Image substitutions are currently applied if they are found on the image-builder class path. This is problematic for the following reasons:

  1. The class-path scanning is necessary making the image build longer. Class-path scanning needs to be removed in the future.
  2. Users can not disable incorrect substitutions in third-party projects.
  3. Users and Native Image developers are not aware of substitutions that are applied to the project and substitutions can unexpectedly affect the semantics.

We need to make the usage of all substitutions explicit. This can be done via a new value Substitutions in the native-image.properties file. The value Substitutions would be a coma-separated list of all fully-qualified classes annotated with @TargetClass.

The explicitly specified values are susceptible to the --exclude-config flag. This will make it possible for people to disable third-party substitutions of a library. In conjuction to --exclude-config, we will provide -H:DisableSubstitutions=<fully-qualified-name-CSV> to disable individual substitutions as excluding the whole config of a library requires re-introducing the library configuration that is not related to substitutions.

The image build output will be modified to show the number of all user-space substitutions. The full list of classes will also be included into the crash reports for easier debugging.

Goals

  1. Make it possible to disable erroneous third-party substitutions.
  2. Make the class-path scanning unnecessary to find substitutions.
  3. Make users aware of the substitutions that were used in the image build and consequences of their usage.
  4. Provide a guide that explains how to avoid substitution usage.

Non-Goals

  1. Make abrupt breaking changes for existing code in the community.
  2. Disallow usage of substitutions in Native Image.

Migration

In the first step, the substitutions that are discovered on the class path but that are not specified in the Substitutions value would be output in a warning message:

Warning: The following substitutions were discovered on the class path but were not specified explicitly in the `native-image.properties` file. Please add the following entries to the class path: 
    'Substitutions=<C1>,..,<C2>' in <cp-entry-1>/META-INF/native-image/<artifact-id>/native-image.properties
...
    'Substitutions=<C3>,..,<C4>' in <cp-entry-n>/META-INF/native-image/<artifact-id>/native-image.properties

In case these files are not under your control please open a ticket for the library authors to include those entries or simply submit a PR.

Note that the usage of substitutions is unlikely necessary and the substitutions will likely not work well with layered native images. Please consult the following link to see how the substitutions can be removed: <link> 

In the next step we would convert the warning into an error message with a possibility to disable the error via a flag.

In the third step there would not even be an error anymore, but the substitutions would simply be ignored.

The time duration between steps 1, 2, and 3 is to be discussed as it depends on the number of substitutions used in the community.

turing85 commented 8 months ago

Can there be cases where users want to exclude specific substitutions instead of all substitutions within a native-image.properties? Should we have a possibility to exclude single substitutions within a native-image.properties?

vjovanov commented 8 months ago

@turing85 this is a good question. This also noted by @fniephaus. I think such flag would not hurt as long as it is not an API flag. I will update the writing to add such flag.

zakkak commented 2 months ago
  1. Make it possible to disable erroneous third-party substitutions.

This is implemented in https://github.com/oracle/graal/pull/9743 (not merged yet)