GROOVY-12040: restore @Builder retention to RUNTIME in 5.0.x#2565
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #2565 +/- ##
==================================================
+ Coverage 68.1904% 68.1928% +0.0024%
- Complexity 33103 33106 +3
==================================================
Files 1508 1508
Lines 126157 126157
Branches 22891 22891
==================================================
+ Hits 86027 86030 +3
+ Misses 32490 32487 -3
Partials 7640 7640 🚀 New features to boost your workflow:
|
✅ All tests passed ✅🏷️ Commit: 782863a Learn more about TestLens at testlens.app. |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR restores @groovy.transform.builder.Builder annotation retention to RUNTIME (per GROOVY-12040), ensuring the annotation remains visible via Java reflection after compilation.
Changes:
- Change
@Builderretention fromSOURCEtoRUNTIME. - Add a regression test verifying
ConnectionSettings.getAnnotation(Builder)returns a non-null annotation and that key attributes are readable at runtime.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/main/java/groovy/transform/builder/Builder.java |
Restores @Builder retention to RetentionPolicy.RUNTIME so it is available via reflection. |
src/test/groovy/org/codehaus/groovy/transform/BuilderTransformTest.groovy |
Adds a regression test to confirm @Builder is visible and its attributes are accessible at runtime. |
jamesfredley
added a commit
to apache/grails-core
that referenced
this pull request
May 29, 2026
…12040 fixed in Groovy 6) GROOVY-12040 (apache/groovy#2565, merged to master 2026-05-27, present in 6.0.0-SNAPSHOT build #716) restores @builder to @retention(RUNTIME). The isLikelyBuilderType() heuristic was introduced on the Groovy 5 line because Class.getAnnotation(Builder) returned null under the SOURCE-retention regression. With the upstream fix, runtime annotation detection works again, so the heuristic and its three call-site disjuncts are removed and builder detection reverts to the pre-Groovy-5 getAnnotation(Builder) form. The Spring 7 Map-to-typed-config conversion fallbacks (handleConverterNotFoundException, handleConversionException) are retained - they are independent of the Groovy version and required regardless of @builder annotation retention. GROOVY-12040 is not yet backported to GROOVY_5_0_X, so this workaround remains required on the grails8-groovy5-sb4 base branch (5.0.7-SNAPSHOT); it is removed here only on the Groovy 6 canary. Verified on Groovy 6.0.0-SNAPSHOT build #716 / Gradle 9.5.1 / Spring Boot 4.0.6: :grails-datastore-core:test --tests ConfigurationBuilderSpec (4/4 passed) and :grails-datastore-core:codeStyle green. Assisted-by: claude-code:claude-4.8-opus
jamesfredley
added a commit
to apache/grails-core
that referenced
this pull request
May 29, 2026
…12040 backported to GROOVY_5_0_X) GROOVY-12040 (apache/groovy#2565) restores @builder to @retention(RUNTIME) and is now backported to GROOVY_5_0_X. Confirmed against the published 5.0.7-SNAPSHOT build 5.0.7-20260529.064309-2, whose groovy.transform.builder.Builder again carries RUNTIME retention (the prior cached build dated 2026-05-22 still had SOURCE). The isLikelyBuilderType() heuristic was introduced only because Class.getAnnotation(Builder) returned null under the SOURCE-retention regression. With runtime annotation detection working again, the heuristic and its three call-site disjuncts are removed and builder detection reverts to the pre-Groovy-5 getAnnotation(Builder) form. The Spring 7 Map-to-typed-config conversion fallbacks (handleConverterNotFoundException, handleConversionException) are retained; they are independent of the Groovy version. While auditing the remainder of the former combined row, the AbstractConstraint.getDefaultMessage fallback was confirmed to be a genuinely required, SEPARATE Groovy 5 bug (not GROOVY-12040): on Groovy 5 the ConstrainedProperty interface constant DEFAULT_MESSAGES is initialised with null values (its map initialiser runs before the DEFAULT_*_MESSAGE constants it references are assigned), so a direct DEFAULT_MESSAGES.get(code) returns null while MESSAGE_BUNDLE resolves the same code correctly. The MESSAGE_BUNDLE fallback is kept, its comment corrected to describe the real root cause, and a new reproducer/regression test (DefaultMessageResolutionSpec) is added to guard it. Verified on 5.0.7-SNAPSHOT (5.0.7-20260529.064309-2) / JDK 21: :grails-datastore-core:test --tests *ConfigurationBuilder* -> 9/9 passed :grails-datamapping-validation:test -> all passed, incl new DefaultMessageResolutionSpec :grails-datastore-core:codeStyle and :grails-datamapping-validation:codeStyle -> green Assisted-by: claude-code:claude-4.8-opus
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.
No description provided.