jdaugherty opened a new pull request, #16795:
URL: https://github.com/apache/grails-core/pull/16795

   ## Description
   
   Since #16552, a non-empty configuration list is presented to Spring's 
`Environment` only under its indexed names, such as `app.names[0]`, so that 
Spring Boot binds it element by element. A `${...}` placeholder that names the 
list itself no longer finds a value:
   
   ```groovy
   // application.yml: app.names: [first, second]
   @Value('${app.names}')
   List<String> names   // 8.0.0: [first, second]    8.0.x: ['${app.names}']
   ```
   
   Grails leaves a placeholder it cannot resolve as written, so the application 
starts and the injection point silently receives the placeholder text. The 
upgrade notes said the application would fail to start with `Could not resolve 
placeholder`. An application that injects a list of trusted certificates this 
way fails much later, when `${...}` is parsed as a certificate.
   
   `GrailsPlaceholderConfigurer` now resolves such a placeholder, after the 
environment and the local properties, to the elements of the list joined by 
commas, which Spring converts to the `List` or array the placeholder is 
injected into, as it did before #16552. The list is read with Spring Boot's 
`Binder`, so it comes from the property source of the highest priority that 
sets it, as `@ConfigurationProperties` binding reads it, and the placeholders 
in its elements are resolved.
   
   The resolution lives in the configurer only. The `Environment` still 
presents the list by its indexed names, so #16550 stays fixed and 
`environment.getProperty('app.names')` is still `null`. A placeholder naming a 
list of objects, such as `springdoc.group-configs`, is still not resolved.
   
   This reverses the part of #16552 that documented `@Value` as unable to read 
a list. The Grails settings that #16552 moved to binding are unaffected. The 
configuration guide and the Grails 8 upgrade notes now describe the placeholder 
for both kinds of list, including that an unresolvable one is left as written 
rather than failing startup.
   
   The change from #16552 is on 8.0.x after the 8.0.0 tag, and on 8.1.x, 9.0.x 
and 9.1.x by merge; no 7.x line has it. This PR targets 8.0.x so the fix merges 
up with it, and it applies to 9.0.x without conflicts.
   
   ### Validation
   
   - `GrailsPlaceholderConfigurerSpec`: five of the new features failed before 
the change, each injecting `${app.names}` or `${app.origins}` literally; all 11 
features pass after it, on 8.0.x and on 9.0.x.
   - `./gradlew :grails-core:test :grails-core:codeStyle --rerun-tasks`: 1,053 
tests, no failures, 3 skipped; Checkstyle and CodeNarc clean.
   - `./gradlew :grails-testing-support-core:test`, which registers the same 
configurer: 47 tests, no failures.
   - A Grails 9 application that injects 
`@Value('${trifleet.security.certificates}') List<String>`, a list set in a 
plugin's Groovy configuration, received `['${trifleet.security.certificates}']` 
and failed in `BootStrap` parsing it as a certificate. With this change applied 
to 9.0.x it receives the certificate and installs its trust store.
   - `git diff --check`.
   - Not run: `./gradlew build --rerun-tasks` and the repository-wide 
`./gradlew clean aggregateViolations :grails-test-report:check --continue`.
   
   ## Contributor Checklist
   
   ### Issue and Scope
   
   - [x] This PR is linked to an existing issue that has been **acknowledged or 
approved** by the project team. If no approved issue exists, please give 
background on why this change is necessary. Tickets are preferred for release 
change log history.
     - No issue: the background is above. It follows up #16552 / #16550.
   - [x] This PR addresses the **complete scope** of the linked issue. Partial 
implementations or unfinished work should not be submitted for review.
   - [x] This PR contains a **single, focused change**. Unrelated changes 
should be submitted as separate pull requests.
   - [x] This PR targets the **correct branch** for the type of change:
       - **Patch release branches** (e.g., `7.0.x`): Bug fixes only. No new 
features or API changes.
       - **Minor release branches** (e.g., `7.1.x`): New features are welcome, 
but breaking existing APIs must be avoided.
       - **Major release branches** (e.g., `8.0.x`): Reserved for major 
changes. Breaking API changes are permitted.
   
   ### Code Quality
   
   - [x] I have **added or updated tests** that cover the changes introduced in 
this PR. All code contributions are expected to include appropriate test 
coverage.
   - [ ] I have verified that all existing tests pass by running `./gradlew 
build --rerun-tasks`.
     - The affected modules' tests passed, as listed above. CI will run the 
full build.
   - [x] My code follows the project's **code style** guidelines. The affected 
module's `codeStyle` task passed.
   - [x] This PR does **not** include mass reformatting, style-only changes, or 
large-scale refactoring unless it was **explicitly approved** in the linked 
issue. Unsolicited reformatting will not be accepted.
   
   ### Licensing and Attribution
   
   - [x] All contributed code is provided under the [Apache License 
2.0](https://www.apache.org/licenses/LICENSE-2.0), and new source files include 
the appropriate **Apache license header**.
   - [x] I have the necessary rights to submit this contribution and confirm it 
is my own original work (see [Legal 
Notice](https://github.com/apache/grails-core/blob/8.0.x/CONTRIBUTING.md#i-want-to-contribute)).
   
   ### Documentation
   
   - [x] If this PR introduces user-facing changes, I have included or updated 
the relevant documentation.
   - [x] If this PR adds a new feature, I have updated the **What's New** 
section of the Grails Guide. — Not applicable: bug fix.
   - [x] If this PR introduces breaking changes or changes that require user 
action during an upgrade, I have updated the **Upgrade Notes** for the 
corresponding version in the Grails Guide.
   - [x] The PR description clearly explains **what** was changed and **why**.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to