Load plugin.yml/plugin.groovy earlier so @Conditional* annotations can be used#15409
Load plugin.yml/plugin.groovy earlier so @Conditional* annotations can be used#15409jdaugherty wants to merge 1 commit intoapache:7.1.xfrom
Conversation
1232204 to
e109334
Compare
46f5e8f to
9f81969
Compare
| * @return the plugin's property source from the environment, or {@code null} if the | ||
| * GrailsApplication main context is not yet available or no matching property source exists | ||
| */ | ||
| @Deprecated(forRemoval = true) |
There was a problem hiding this comment.
I think that if it's deprecated it should say why.
There was a problem hiding this comment.
I was proposing this be removed because I don't see a usage for it - you can fetch the configuration but when would it be valid to look at the shipped config? btw, i had marked this as draft to see what @matrei thinks of this. This is a rather large change for 7.0.x so we may want to do some further testing.
|
You're right—deprecation annotations should include a reason for clarity. For this method, the reason could be that plugin property sources are now handled early by GrailsPluginEnvironmentPostProcessor. |
|
If this does not require changes in end Grails apps I am OK with this going into 7.0.x, if we think the risk is too high, then 7.1.x is also OK. |
There was a problem hiding this comment.
Looks solid. A few minor items to take a look at.
The GrailsPluginConfigurationClass test removed the "plugin with both yml and groovy throws exception" test. That validation still exists in GrailsPluginEnvironmentPostProcessor.readPluginConfiguration() (line 293), but there's no unit test covering it in the new code. The GrailsPluginEnvironmentPostProcessorSpec should add a test for this.
| * {@link org.grails.plugins.AbstractGrailsPlugin#readPluginConfiguration}. If both | ||
| * exist, a {@link RuntimeException} is thrown.</p> | ||
| */ | ||
| PluginInfo extractPluginInfo(Class<?> pluginClass) { |
There was a problem hiding this comment.
calls pluginClass.getDeclaredConstructor().newInstance() to read loadAfter/loadBefore/dependsOn. At this point in the Spring Boot lifecycle, there's no GrailsApplication, no application context, no plugin manager. If any plugin's no-arg constructor has side effects or requires dependencies, this could fail.
The code handles this gracefully (catches exceptions, continues with default ordering), but plugins with complex constructors will silently get default ordering rather than their declared ordering. This could subtly change the order configs are loaded compared to the existing behavior.
There was a problem hiding this comment.
I'd argue at this point they shoudln't be using Holders either. These dependencies would have to be autowired and that would happen after the constructor creation, so i view this as low risk.
grails-core/src/main/groovy/org/grails/config/GrailsPluginEnvironmentPostProcessor.java
Outdated
Show resolved
Hide resolved
grails-core/src/main/groovy/org/grails/config/GrailsPluginEnvironmentPostProcessor.java
Outdated
Show resolved
Hide resolved
462035b to
ee32e61
Compare
|
This change is incomplete since the plugin configuration will be loaded potentially when the plugin is disabled. We may be able to post process already loaded configuration and remove them, but I'm not sure without further research. Here's the loading order in Spring: • SpringApplication.run(...) The problem is the plugin manager has different discovery mechanisms (but very similar). Worst, one of those mechanisms appears to require the application context, which won't exist when we need to load configuration. I think the need for the application context (or rather the parent application context) isn't actually used though. I'm doing further research on this to see how best to unify the plugin manager mechanisms so we can share the logic in both places. |
|
I've been working on this and will likely push a significant update in the next day or so. The core issue is the plugin filtering needs shared between the environment & the application post processors. The problem: the plugin manager is what currently does this filtering & it's a bean. The environment post processor can't use a bean b/c the context doesn't exist yet. The only practical place the filtering is used is when in unit tests it filters the plugins. I think the right solution is either moving the filter further out & sharing it between the plugin manager / EPP, or just moving the plugin manager away from being a bean completely. |
ee32e61 to
406aa4a
Compare
406aa4a to
d7175cf
Compare
Fixes #15408
Assisted-by: OpenCode <opencode@opencode.ai>
Assisted-by: Claude <claude@anthropic.com>