Honor EnvironmentAware application classes before early plugin registration#15979
Draft
codeconsole wants to merge 1 commit into
Draft
Honor EnvironmentAware application classes before early plugin registration#15979codeconsole wants to merge 1 commit into
codeconsole wants to merge 1 commit into
Conversation
…ration The retimed plugin lifecycle (apache#15934) drains plugin doWithSpring before any bean is created, so an application class using the documented externalized-configuration pattern — implementing EnvironmentAware and contributing property sources from setEnvironment — no longer runs before plugins read configuration. Plugins that resolve settings inside doWithSpring (the GORM plugins resolve their connection URLs there) silently fall back to the static yaml values: a Grails 7 app that injected its production MongoDB URL from a secret manager boots against the localhost default on 8.0. Replay the contract at the start of the early phase: for each stashed application source class that is a GrailsAutoConfiguration or GrailsApplicationClass and implements EnvironmentAware, invoke setEnvironment on a detached instance (the same approach the phase already uses for artefact scanning) before plugin loading, the config snapshot, and the doWithSpring drain. The real application bean still receives the standard callback when Spring creates it later, so implementations must stay idempotent — contribute a named property source, which replaces rather than accumulates.
✅ All tests passed ✅🏷️ Commit: a5a0b5f Learn more about TestLens at testlens.app. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
#15934 retimed plugin
doWithSpringto run before Spring Boot auto-configuration — and therefore before any bean is created. An application class using the long-documented externalized-configuration pattern:previously had
setEnvironmentinvoked (when the application configuration bean was instantiated) before plugin bean registration ran. After the retiming, plugins that resolve settings insidedoWithSpringread configuration the application has not customized yet. The GORM plugins resolve their connection URLs there — e.g.MongodbGrailsPlugin.doWithSpring()buildsMongoDbDataStoreSpringInitializerfromconfigat definition time — so an app that injects its production MongoDB URL from a secret manager insetEnvironmentsilently boots against the static yaml default (localhost) instead. Beans that read theEnvironmentat creation time (Redis, Elasticsearch,@Value) are unaffected, which makes the failure look like a Mongo-specific mystery. This is a real-world regression observed in production on the re-staged 8.0.0-M3.Fix
Replay the contract at the start of
GrailsEarlyPluginRegistrationPostProcessor: for each stashed application source class that is aGrailsAutoConfiguration/GrailsApplicationClassand implementsEnvironmentAware, invokesetEnvironmenton a detached instance — the same approach the phase already uses for artefact scanning (scanApplicationSource) — before plugin loading, thePropertySourcesConfigsnapshot, and thedoWithSpringdrain.The real application bean still receives the standard
EnvironmentAwarecallback when Spring creates it later, so implementations must be idempotent: contribute a named property source (re-adding a source with the same name replaces the earlier one) rather than accumulate state. This is documented on the new method and asserted in the spec (INVOCATIONS == 2, no duplicated source).Testing
New test in
EarlyPluginRegistrationOrderingSpec: a plugin that reads config indoWithSpring(as the GORM plugins do) observes the value contributed by the application'ssetEnvironment, not the default; the double-callback semantics are pinned. Full:grails-core:testand checkstyle pass.Happy to add an upgrade-notes entry in grails-doc ("
setEnvironmentonEnvironmentAwareapplication classes now runs twice; keep it idempotent") if wanted.