Keep BeanBuilder DSL independent of XML setup#15824
Conversation
Avoid eager Spring XML reader setup when evaluating ordinary BeanBuilder DSLs so resources.groovy remains compatible with Spring Framework 7. Move XML reader and namespace support behind a lazy helper used only by XML import and xmlns paths. Add grails-spring regression coverage for plain DSL, XML import, and namespace support, and wire the module into the shared test configuration so those tests execute. Document the compatibility behavior in the Grails 8 upgrade and Spring DSL guides. Assisted-by: Hephaestus:openai/gpt-5.5 codex-review
There was a problem hiding this comment.
Pull request overview
This PR refactors grails.spring.BeanBuilder to keep the standard resources.groovy DSL path independent of Spring XML reader/context initialization, while preserving compatibility for XML-based imports (importBeans with XML resources) and Spring XML namespace DSL usage via xmlns. It also adds regression tests and documents the Grails 8 compatibility behavior in the guide and upgrade notes.
Changes:
- Introduced lazy, encapsulated XML/namespace support (
BeanBuilderXmlSupport) so XML infrastructure is only initialized when needed. - Updated
BeanBuilderto delegate XML import and namespace parsing to the new support class. - Added
grails-springregression tests and updated documentation to clarify Grails 8 behavior.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| grails-spring/src/test/groovy/grails/spring/BeanBuilderTests.groovy | Adds regressions covering plain DSL (no XML init), XML import, and xmlns namespace usage. |
| grails-spring/src/main/groovy/grails/spring/BeanBuilderXmlSupport.java | New helper to lazily manage Spring XML reader/context and namespace handler resolution. |
| grails-spring/src/main/groovy/grails/spring/BeanBuilder.java | Removes eager XML initialization and routes XML-related behavior through BeanBuilderXmlSupport. |
| grails-spring/build.gradle | Applies shared test-config.gradle for module test setup. |
| grails-doc/src/en/guide/upgrading/upgrading80x.adoc | Documents Grails 8 BeanBuilder/XML compatibility and recommended path. |
| grails-doc/src/en/guide/spring/theBeanBuilderDSLExplained.adoc | Clarifies that XML namespace support is compatibility-focused and initialized on-demand. |
| grails-doc/src/en/guide/spring/springdslAdditional.adoc | Notes continued resources.xml support and encourages resources.groovy for new definitions. |
| grails-doc/src/en/guide/introduction/whatsNew.adoc | Highlights the Grails 8 BeanBuilder behavior change at a high level. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| throw new BeanDefinitionParsingException( | ||
| new Problem("No namespace handler found for URI: " + uri, | ||
| new Location(readerContext.getResource()))); | ||
| new Location(getXmlSupport().getReaderContext(beanBuildResource).getResource()))); |
|
The suggested change is correct and aligns with the goal of avoiding unnecessary initialization of Spring XML infrastructure in the error path. By using This change effectively prevents the potential masking of the "No namespace handler found" error and improves performance in the exception path. grails-spring/src/main/groovy/grails/spring/BeanBuilder.java |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## 8.0.x #15824 +/- ##
==================================================
+ Coverage 49.3625% 49.3911% +0.0286%
- Complexity 16777 16798 +21
==================================================
Files 1986 1987 +1
Lines 93336 93363 +27
Branches 16337 16337
==================================================
+ Hits 46073 46113 +40
+ Misses 40134 40123 -11
+ Partials 7129 7127 -2
🚀 New features to boost your workflow:
|
Use the existing BeanBuilder resource when reporting missing XML namespace handlers so the error path does not create a reader context. Add coverage that fails if the XML reader path initializes while building the missing namespace error. Assisted-by: opencode:gpt-5.5 codex-review
✅ All tests passed ✅🏷️ Commit: 5b3d004 Learn more about TestLens at testlens.app. |
|
FYI: spring started enforcing certain configuration like AMPQ / rabbit to be associated to an application context. Why are we maintaining the link to the bean builder dsl that Spring has stated will no longer be supported? Can't we adjust the beanDsl to use a BeanRegistrar instead which is the programmatic way Spring suggests using now? |
Fixes #14915
Why this is needed
Grails 8 is moving onto Spring Framework 7, but existing applications still need their
grails-app/conf/spring/resources.groovyBeanBuilder DSL files to keep working without application-side changes.The problem with the previous implementation was that
BeanBuildereagerly initialized Spring XML reader/context infrastructure even for ordinary programmaticresources.groovybean definitions. That made the standard DSL path more tightly coupled to Spring XML internals than it needs to be.This PR keeps the public BeanBuilder DSL behavior backward compatible while avoiding that eager XML setup for the common
resources.groovypath.What changed
XmlReaderContext, and parser context setup into a lazyBeanBuilderXmlSupporthelper.BeanDefinitionpath.importBeanswith.xmlresources still loads XML bean definitions.xmlnsstill resolves Spring XML namespace handlers on demand.DynamicElementReaderstill receives the parser context it needs for namespace DSL usage.grails-springso module-local JUnit Platform tests are actually discovered and run.importBeansstill registers XML bean definitions.xmlnsnamespace support still works through the BeanBuilder DSL.resources.groovyfor new custom bean definitions.Compatibility behavior
No application changes are required for existing
resources.groovyBeanBuilder DSL files.Existing
resources.xml, XML imports, and Spring XML namespace DSL usage remain supported as compatibility paths. They now initialize XML support only when those XML features are actually used.Verification
Passed from the visible checkout on
fix/14915-beanbuilder-spring7:JAVA_HOME=/home/james/.jdks/corretto-21 PATH=/home/james/.jdks/corretto-21/bin:$PATH ./gradlew :grails-spring:test --rerun-tasksJAVA_HOME=/home/james/.jdks/corretto-21 PATH=/home/james/.jdks/corretto-21/bin:$PATH ./gradlew :grails-spring:codeStylegrails-springruntime classpath:PASS plain BeanBuilder DSL did not initialize XML supportReview gate:
f1e6f82bdd5a4035a8230306b3d519b03ac1a61aas GREEN..omo/run-continuationsession metadata. That file was not staged or committed.Full-suite notes
./gradlew cleancompleted successfully../gradlew aggregateViolations --continuewas attempted, but the build is currently blocked by unrelated existing compile errors outside this change:grails-validation/src/main/groovy/grails/validation/Validateable.groovy: unable to resolvegroovy.transform.Virtualgrails-data-graphql/core/.../Arguable.groovyandComplexTyped.groovy: static type checking cannot findwithDelegate(Closure, Object)./gradlew :grails-test-report:check --continuewas attempted and exceeded the 20 minute tool timeout after producing broad test output.