Skip to content

GROOVY-12040: restore @Builder retention to RUNTIME in 5.0.x#2565

Merged
paulk-asert merged 1 commit into
apache:masterfrom
paulk-asert:groovy12040
May 27, 2026
Merged

GROOVY-12040: restore @Builder retention to RUNTIME in 5.0.x#2565
paulk-asert merged 1 commit into
apache:masterfrom
paulk-asert:groovy12040

Conversation

@paulk-asert
Copy link
Copy Markdown
Contributor

No description provided.

@codecov-commenter
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 68.1928%. Comparing base (42ce7e0) to head (782863a).

Additional details and impacted files

Impacted file tree graph

@@                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                

see 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@testlens-app
Copy link
Copy Markdown

testlens-app Bot commented May 26, 2026

✅ All tests passed ✅

🏷️ Commit: 782863a
▶️ Tests: 32001 executed
⚪️ Checks: 28/28 completed


Learn more about TestLens at testlens.app.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 @Builder retention from SOURCE to RUNTIME.
  • 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.

@paulk-asert paulk-asert merged commit f1a4483 into apache:master May 27, 2026
29 checks passed
@paulk-asert paulk-asert deleted the groovy12040 branch May 27, 2026 02:56
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants