-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Limit external configuration sources parsing in native-mode #42140
base: main
Are you sure you want to change the base?
Conversation
@radcortez please take a look. I opened it as draft since there are way more reflective access being caught by The ones I am trying to understand now are ones generated because of the sources automatically added to the RunTimeConfigCustomizer. Do you think we could/should skip some of those when targeting native-mode, or are they all necessary? Since I have your attention I would also like to ask why you are not generating quarkus/core/deployment/src/main/java/io/quarkus/deployment/steps/ConfigGenerationBuildStep.java Line 688 in fc678ed
Thanks |
The idea is to discover all the services during the build and generate a config customizer that programmatically registers all the discovered services. I think we cannot skip any of the things we discover. Are you seeing issues with this?
We probably don't need the reflection registration anymore. We can try to drop it and check :) |
@@ -391,6 +392,17 @@ public void setupConfigOverride( | |||
|
|||
@BuildStep | |||
public void watchConfigFiles(BuildProducer<HotDeploymentWatchedFileBuildItem> watchedFiles) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The watched files include external files like .env
and {user.dir}/config/application{-profile}.properties
. Should these be registered as a resource with the native image?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anything accessed through java.lang.ClassLoader.getResources
(invoked by https://github.com/smallrye/smallrye-common/blob/c29bb1c00f484f5fa86f183e75c37af462ac6546/classloader/src/main/java/io/smallrye/common/classloader/ClassPathUtils.java#L84) needs to be registered (at least in theory).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
External files should be calling processAsPath
https://github.com/smallrye/smallrye-common/blob/c29bb1c00f484f5fa86f183e75c37af462ac6546/classloader/src/main/java/io/smallrye/common/classloader/ClassPathUtils.java#L132-L160 directly, without using the classloader:
For {user.dir}/config/application.properties
:
https://github.com/smallrye/smallrye-config/blob/e8d87ce1cfbf1e6f259a798c85498267dd12b32b/implementation/src/main/java/io/smallrye/config/AbstractLocationConfigSourceLoader.java#L118-L135
At least until now, we have never had issues loading these files and the native executable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, these "issues" are popping up when using -H:+ThrowMissingRegistrationErrors
(see #41995) which aims to help developers detect unregistered accesses to elements. What I suspect is that there are many places where Quarkus tries to access unregistered elements and just fails without a warning, but since there are other places or ways to get the same data back it works as expected.
So in many of these cases it might be OK to not register the elements, but at the same time the best practice would be to ensure hat Quarkus also doesn't try to access them at run-time (e.g. through substitutions or changing configuration).
List<String> configWatchedFiles = new ArrayList<>(); | ||
String userDir = System.getProperty("user.dir"); | ||
|
||
// Main files | ||
configWatchedFiles.add("META-INF/microprofile-config.yaml"); | ||
configWatchedFiles.add("META-INF/microprofile-config.yml"); | ||
configWatchedFiles.add("application.yaml"); | ||
configWatchedFiles.add("application.yml"); | ||
configWatchedFiles.add(Paths.get(userDir, "config", "application.yaml").toAbsolutePath().toString()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check previous comments about external files.
public class FileSystemOnlySourcesConfigBuilder implements ConfigBuilder { | ||
@Override | ||
public SmallRyeConfigBuilder configBuilder(final SmallRyeConfigBuilder builder) { | ||
return builder.withSources( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You want to disable the default sources which include the classpath lookup and then add the inFileSystem
: builder.setAddDefaultSources(false).addSystemSources().withSources(inFileSystem...)
public SmallRyeConfigBuilder configBuilder(final SmallRyeConfigBuilder builder) { | ||
return builder.withSources( | ||
inFileSystem(Paths.get(System.getProperty("user.dir"), "config", "application.properties").toUri().toString(), | ||
260, Thread.currentThread().getContextClassLoader())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the classloader set in the builder: io.smallrye.config.SmallRyeConfigBuilder#getClassLoader
.
Not necessarily, it kind of complicates the resource registration process so I am just trying to see if there is any opportunity for trimming down :) |
It looks like you are right. |
`SmallryeConfigBuilder` tries to access properties files from various sources, despite them not being available at run-time nor supported in native-mode, see quarkusio#41994 This patch also avoids getting a `MissingRegistrationError` when using `-H:+ThrowMissingRegistrationErrors` or `--exact-reachability-metadata`. Related to quarkusio#41994 and quarkusio#41995
fc678ed
to
628ee63
Compare
Hum, the goal was to avoid as many registrations as possible. Since this has been an ongoing process, there are probably some code leftovers that are not required anymore (the reflection registration of services, for instance). Let me know what you are seeing and we try to hax a few things. |
I think we can drop registrations of quarkus/core/deployment/src/main/java/io/quarkus/deployment/steps/ConfigBuildSteps.java Lines 31 to 51 in bf77189
for everything except |
If you run:
you will see a bunch of exceptions being thrown, indicating that the resulting native-image is trying to access elements that have not been registered at build time. Unfortunately the A couple of indicative examples:
|
Great. Thanks. Ok, let's try to trim these down. Did you run with these PR changes? It shouldn't be looking for |
Yes, it removes some of these warnings but not all. |
Yes, some of the warnings related to the lookups to the config files should be gone now. Looking into other warnings, I see many related to the Validator. The issue here is that we only register for reflection the config classes that have validation annotations. The config code still calls There is no quick fix for this. I guess the best option is to override the Validator and pass in a list of config classes that require validation to avoid that call. |
SmallryeConfigBuilder
tries to access properties files from various sources, despite them not being available at run-time nor supported in native-mode, see #41994This patch also avoids getting a
MissingRegistrationError
when using-H:+ThrowMissingRegistrationErrors
or--exact-reachability-metadata
.Related to #41994 and #41995
Supersedes #42103