https://github.com/apache/grails-core/pull/15557#issuecomment-4845438797
All clear on the Grails side, as far as I can tell. Thanks again for the heroic efforts to support some edge case, legacy code in Grails. James On 2026/06/29 20:12:12 Paul King wrote: > I haven't tried to track down the cause but I created this: > > https://issues.apache.org/jira/browse/GROOVY-12117 > https://github.com/apache/groovy/pull/2644 > > AI's read of your comments Eric below: > > Yes — Eric is correct about what that block *does*, but it's > describing the **consumer**, not the site of the order-dependence. Two > clarifications worth making, and he's right about > `@DelegatesTo.Target`. > > ## Where Eric is right > > That block in `TraitTypeCheckingExtension.handleMissingMethod` is > exactly the STC resolver for an inherited super-trait static, and his > read of the `(Object)` cast is the correct historical explanation: the > version he pasted uses exact-match `getDeclaredMethod(name, > signature)`, so an argument whose static type was a *subtype* of the > declared `Object delegate` (e.g. `Field`) didn't match — you cast to > `Object` to hit the declared signature. > > ## Two clarifications > > **1. He's quoting the pre-12106 snippet.** On the `groovy12117` branch > (post-`b7796c3f9b`) that block no longer does exact-match — it builds > the helper's static candidates and runs `chooseBestMethod` for > subtype-aware resolution (`TraitTypeCheckingExtension.java:127-146`). > So the `(Object)` cast is no longer needed *for resolution*; a raw > `Field` arg resolves directly — my regression test passes one with no > cast. > > **2. This block is not where 12117 lives — it's downstream of it.** > The guard at line 123 is `argumentTypes.length > 0 && > ClassHelper.isClassType(argumentTypes[0])`. It only fires once the > call already carries the synthetic `$static$self` Class as arg 0 — > i.e. *after* `TraitReceiverTransformer.findConcreteMethod` (transform > phase) has rewritten `withDelegate(closure, f)` into > `this.withDelegate($static$self, closure, f)`. In the sub-trait-first > ordering that rewrite never happens (the super-trait's helper is still > an empty stub when the sub-trait is lowered, so `findConcreteMethod` > returns null), so the call reaches `handleMissingMethod` as > `withDelegate(Closure, Field)` — arg 0 is `Closure`, the > `isClassType(argumentTypes[0])` guard is **false**, the whole block is > skipped, and you get the plain `Cannot find matching method > Arguable#withDelegate(Closure, Field)`. That's exactly the observed > error. > > So this block can't be the fix point — it's already order-independent > (it runs after every trait is lowered). The order-dependence is one > phase earlier, which is why the fix is the fallback in > `findConcreteMethod` (resolve the static off the not-yet-lowered > super-trait node so the rewrite happens regardless of declaration > order). His block then resolves it identically as it always did. > > ## On `@DelegatesTo.Target` > > Correct — for a *faithful* `withDelegate(Closure, delegate)` the > `delegate` parameter wants `@DelegatesTo.Target` (the existing > `testGrailsHelperShapeWithDelegatesTo` instead uses > `genericTypeIndex=0`, which points `@DelegatesTo` at the closure's > generic type — a different valid form). It doesn't affect the repro > because the test closures (`{ -> }`, `{ -> sb.append('seen') }`) never > reference delegate members, so delegate resolution is never exercised. > But if you want the regression test to mirror the real Grails shape > exactly, I can switch it to `@DelegatesTo.Target Object delegate`. > Want me to make that change? > > On Tue, Jun 30, 2026 at 5:44 AM Milles, Eric (TR Technology) via dev > <[email protected]> wrote: > > > > I think this block of the trait type-checking extension is responsible for > > finding withDelegate in the super trait. That explains the need for the > > Object typecast (see argumentTypes parameter). > > > > > > public class TraitTypeCheckingExtension extends > > AbstractTypeCheckingExtension { > > public List<MethodNode> handleMissingMethod(final ClassNode receiver, > > final String name, final ArgumentListExpression argumentList, final > > ClassNode[] argumentTypes, final MethodCall call) { > > // ... > > if (call instanceof MethodCallExpression mce) { > > ClassNode returnType = > > mce.getNodeMetaData(TraitASTTransformation.DO_DYNAMIC); > > if (returnType != null) return > > Collections.singletonList(makeDynamic(call, returnType)); > > > > // GROOVY-7322, GROOVY-8272, GROOVY-8587, GROOVY-8854, > > GROOVY-10312: trait: this.m($static$self) > > ClassNode targetClass = > > isClassClassNodeWrappingConcreteType(receiver)? > > receiver.getGenericsTypes()[0].getType(): receiver; > > if (Traits.isTrait(targetClass.getOuterClass()) && > > argumentTypes.length > 0 && ClassHelper.isClassType(argumentTypes[0])) { > > Parameter[] signature = > > java.util.Arrays.stream(argumentTypes).map(t -> new > > Parameter(t,"")).toArray(Parameter[]::new); > > List<ClassNode> traits = > > Traits.findTraits(targetClass.getOuterClass()); > > traits.remove(targetClass.getOuterClass()); > > > > for (ClassNode trait : traits) { // check super trait for > > static method > > MethodNode method = > > Traits.findHelper(trait).getDeclaredMethod(name, signature); > > if (method != null && method.isStatic()) { > > return Collections.singletonList(makeDynamic(call, > > method.getReturnType())); > > } > > } > > } > > } > > > > return Collections.emptyList(); > > } > > > > > > Also note that the second parameter in withDelegate needs > > @DelegatesTo.Target in order for the example to fully compile. > > > > ________________________________ > > From: Milles, Eric (TR Technology) <[email protected]> > > Sent: Monday, June 29, 2026 2:09 PM > > To: [email protected] <[email protected]> > > Subject: Re: [VOTE] Release Apache Groovy 5.0.7 > > > > James, > > > > The issue mentioned in > > https://github.com/apache/grails-core/pull/15557#issuecomment-4833554145 > > (code below), is that GROOVY-12106 in a simpler form or is it a new issue? > > The example does indeed work with Groovy 4. But it fails under Groovy > > 5.0.3, so it is possibly related to GROOVY-8854 and GROOVY-11985 but is not > > caused by the changes that went into 5.0.7. > > > > final class A { > > } > > trait Arguable<T> extends ExecutesClosures { // sub-trait declared FIRST > > @groovy.transform.CompileStatic String describe(A a) { withDelegate({ -> > > }, (Object) a); 'ok' } // can the cast be removed? > > } > > trait ExecutesClosures { > > static void withDelegate(@DelegatesTo(strategy = Closure.DELEGATE_ONLY) > > Closure c, Object d) { if (c != null) c.call() } > > } > > class C implements Arguable<String> { > > } > > > > print new C().describe(new A()) > > > > > > ________________________________ > > From: James Fredley <[email protected]> > > Sent: Monday, June 29, 2026 9:21 AM > > To: [email protected] <[email protected]> > > Subject: Re: [VOTE] Release Apache Groovy 5.0.7 > > > > Latest run on Grails 8 with latest Groovy 5 snapshot: https: //urldefense. > > com/v3/__https: //github. > > com/apache/grails-core/pull/15557*issuecomment-4833554145__;Iw!!GFN0sa3rsbfR8OLyAw!aTGIzjECSrwp2O9InZ26flgLuK7b6JB0d3eGoY8mmTbXlgeIn2UDLVlg1GdRYxI-qQi7om_CBMmWFVelntIlxHPH6tI3MA$ > > > > Latest run on Grails 8 with latest Groovy 5 snapshot: > > https://urldefense.com/v3/__https://github.com/apache/grails-core/pull/15557*issuecomment-4833554145__;Iw!!GFN0sa3rsbfR8OLyAw!aTGIzjECSrwp2O9InZ26flgLuK7b6JB0d3eGoY8mmTbXlgeIn2UDLVlg1GdRYxI-qQi7om_CBMmWFVelntIlxHPH6tI3MA$ > > > > On 2026/06/28 10:09:13 Paul King wrote: > > > Both GROOVY_5_0_X and master are now updated with what I believe is a > > > path forward, but I am awaiting to hear from the Grails team on > > > whether the latest version allows them to move forward. > > > > > > GROOVY-11985 which reverted GROOVY-8854 was rolled back. Instead, > > > GROOVY_5_0_X adds @Virtual so we can support the traditional template > > > method style from Groovy 2-4 and fixes the resolution breakages from > > > GROOVY-8854 (as per GROOVY-12106). It leaves the Java-like style > > > (GROOVY-8854) as the default. master also reinforces the Java-like > > > style by adding (non-@Virtual) static methods to the trait interface - > > > fixing some naming previous issues too. As far as I know, the "fuzzy" > > > areas in GEP-22 now all have well-defined semantics. > > > > > > Let me know if you have any feedback. I plan to re-roll the release(s) > > > in a day or two. > > > > > > Cheers, Paul. > > > > > > On Fri, Jun 26, 2026 at 10:50 PM Paul King <[email protected]> wrote: > > > > > > > > Okay, I did another PR here: > > > > > > > > https://urldefense.com/v3/__https://github.com/apache/groovy/pull/2631__;!!GFN0sa3rsbfR8OLyAw!aTGIzjECSrwp2O9InZ26flgLuK7b6JB0d3eGoY8mmTbXlgeIn2UDLVlg1GdRYxI-qQi7om_CBMmWFVelntIlxHMiAqIUWQ$ > > > > > > > > This adds @Virtual as the pair of @Anchored and, as the PR is > > > > currently positioned, flips back to GROOVY-8854 behavior. > > > > > > > > My previous thinking was that given we hadn't advertised the breaking > > > > change, was to remove the break and have a more well-defined migration > > > > path from 6.0.X which is only a month or 2 away I would guess. > > > > > > > > But if the consensus is to keep the breaking change, the implications > > > > for Grails are that they would need to add @Virtual to keep the old > > > > behavior. I don't think the reflection path that is their current > > > > workaround is something we want to suggest frameworks built on Groovy > > > > use. And the other workarounds are quite invasive and would need a > > > > long time for them to percolate through the Grails plugin community. > > > > We don't know anyone using the new behavior, so we don't know if > > > > further folks would be impacted but the static method feature is still > > > > marked as incubating. > > > > > > > > The additional implication for Grails is that plugins using the same > > > > pattern that Grails itself uses will continue to work if compiled > > > > under 4.0.32 but will break as soon as they are compiled under Groovy > > > > 5 unless they also add @Virtual. At least the breakage is limited to > > > > the traits themselves and not Grails applications which weave in the > > > > traits. > > > > > > > > If folks are happy with that path, I can cancel the vote and re-roll > > > > the release, and discuss with Grails about getting @Virtual added. > > > > > > > > Cheers, Paul. > > > > > > > > On Fri, Jun 26, 2026 at 5:48 AM Jochen Theodorou <[email protected]> > > > > wrote: > > > > > > > > > > Hi, > > > > > > > > > > > > > > > I think I have to agree with Eric. -1 > > > > > > > > > > Normally I would suggest to undo the trait changes in 5.0.7 and go > > > > > with > > > > > that, but that would not help Grails either. > > > > > > > > > > Is it a 5.1.0? Well the question is what comes after? If we "fix" the > > > > > reamining bug, does that lead to a reevaluation of who traits work and > > > > > then we get a 5.2 next? Also Anchored is a best effort to solve a > > > > > problem onlly 5.0.x introduced. Do we intend to keep that around? Is > > > > > Grails using that? > > > > > > > > > > I really do not want to block things, but I the situation does > > > > > currently > > > > > not feel exactly right. > > > > > > > > > > I have a wish to Grails here. Could you write a test suite that covers > > > > > the Grails cases in "all" aspects? And I mean the way you expect the > > > > > things to work - in pure Groovy, without Grails of course. I think > > > > > that > > > > > is better than this case-by-case and late discoveries process we > > > > > currently have. > > > > > > > > > > bye Jochen > > > > > > > > > > > > > > > On 6/25/26 20:06, James Daugherty via dev wrote: > > > > > > Hi Eric, > > > > > > > > > > > > Would you be agreeable to a release of 5.1.0 or a milestone of 5.1.0 > > > > > > with these changes? Is your concern for any 5.x version or just the > > > > > > 5.0.x version? > > > > > > > > > > > > Regards, > > > > > > James > > > > > > > > > > > > On Thu, Jun 25, 2026 at 2:02 PM James Fredley > > > > > > <[email protected]> wrote: > > > > > >> > > > > > >> Hi Eric, > > > > > >> > > > > > >> I wanted to share some context on our current work to bring Groovy > > > > > >> 5 support into Apache Grails 8. > > > > > >> > > > > > >> After the Groovy 5 release last year, Grails encountered several > > > > > >> compatibility challenges. The team has invested substantial > > > > > >> effort, more than 75 iterations, on this pull request to resolve > > > > > >> the issues and enable Grails 8 to ship on the stable Groovy 5.0.7 > > > > > >> release alongside Spring Boot 4: > > > > > >> https://urldefense.com/v3/__https://github.com/apache/grails-core/pull/15557__;!!GFN0sa3rsbfR8OLyAw!aTGIzjECSrwp2O9InZ26flgLuK7b6JB0d3eGoY8mmTbXlgeIn2UDLVlg1GdRYxI-qQi7om_CBMmWFVelntIlxHPZVQBq9Q$ > > > > > >> > > > > > >> Without completing this work, we would likely need to release > > > > > >> Apache Grails 8 on Apache Groovy 4 and then target Apache Groovy 6 > > > > > >> for Apache Grails 9. However, Grails 7 is built on Spring Boot > > > > > >> 3.5.x, which reaches end of life on June 30, 2026. This creates > > > > > >> real pressure to deliver Grails 8 in a timely manner. > > > > > >> > > > > > >> For clarity, Apache Grails 9 will almost certainly target Apache > > > > > >> Groovy 6 regardless. > > > > > >> > > > > > >> On a more positive note, we have also improved our release > > > > > >> validation process with Canary builds. The previous joint > > > > > >> validation approach primarily caught issues in patch releases. The > > > > > >> new process lets us test Grails against upcoming Groovy versions > > > > > >> much earlier and more comprehensively: > > > > > >> https://urldefense.com/v3/__https://github.com/apache/grails-core/pull/15558__;!!GFN0sa3rsbfR8OLyAw!aTGIzjECSrwp2O9InZ26flgLuK7b6JB0d3eGoY8mmTbXlgeIn2UDLVlg1GdRYxI-qQi7om_CBMmWFVelntIlxHN-NLC9WQ$ > > > > > >> > > > > > >> Thank you for your ongoing collaboration. I am happy to discuss > > > > > >> timelines, the remaining workarounds in the PR, or anything else > > > > > >> that would help us coordinate effectively. > > > > > >> > > > > > >> Best regards, > > > > > >> James Fredley > > > > > >> VP, Apache Grails PMC > > > > > >> > > > > > >> This version stays professional, collaborative, and timeline > > > > > >> focused while remaining fully compliant with your no em dashes > > > > > >> preference. Ready to copy and send or post to the list. > > > > > >> > > > > > >> On 2026/06/25 15:44:42 "Milles, Eric (TR Technology) via dev" > > > > > >> wrote: > > > > > >>> -1 (binding) > > > > > >>> > > > > > >>> I do not think the trait static method change (GROOVY-11985) or > > > > > >>> the new Anchored transform (GROOVY-12093) should have been done > > > > > >>> in a point-fix release. GROOVY-12106 is evidence that one > > > > > >>> problem has been traded for another. There was quite a bit of > > > > > >>> discussion, but IMO the behavior should have remained as-is and > > > > > >>> Grails could investigate a workaround. Groovy 5 was in > > > > > >>> pre-release state for an extended time. So, there was plenty of > > > > > >>> time to try it out and discuss the trait changes. > > > > > >>> > > > > > >>> Having Groovy 5.0.0 to 5.0.6 have one set of behaviors and then > > > > > >>> 5.0.7 onwards do something else plus have GROOVY-12106 and > > > > > >>> possibly other issues is not a good look. > > > > > >>> > > > > > >>> If 11985 and 12093 were removed, I'm okay with the rest of 5.0.7. > > > > > >>> We could then further weigh the possibilities for Groovy 5 and 6 > > > > > >>> WRT trait static member references. > > > > > >>> > > > > > >>> > > > > > >>> ________________________________ > > > > > >>> From: Paul King <[email protected]> > > > > > >>> Sent: Thursday, June 25, 2026 2:46 AM > > > > > >>> To: Groovy_Developers <[email protected]> > > > > > >>> Subject: [VOTE] Release Apache Groovy 5.0.7 > > > > > >>> > > > > > >>> Dear development community, I am happy to start the VOTE thread > > > > > >>> for a Groovy 5. 0. 7 release! This release includes 14 bug > > > > > >>> fixes/improvements as outlined in the changelog: https: > > > > > >>> //urldefense. com/v3/__https: //issues. apache. > > > > > >>> org/jira/secure/ReleaseNote. > > > > > >>> jspa?projectId=12318123&version=12356953__;!!GFN0sa3rsbfR8OLyAw!aTE-LsRa0qOkuOe9PDf8SxURjg4lPNkURZZDxdnHHE1SarHQqnSUqpw4F1byG6kxErokFTjgNp2kjyRDpx1WUg$ > > > > > >>> > > > > > >>> > > > > > >>> Dear development community, > > > > > >>> > > > > > >>> I am happy to start the VOTE thread for a Groovy 5.0.7 release! > > > > > >>> > > > > > >>> This release includes 14 bug fixes/improvements as outlined in > > > > > >>> the changelog: > > > > > >>> https://urldefense.com/v3/__https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12318123&version=12356953__;!!GFN0sa3rsbfR8OLyAw!aTE-LsRa0qOkuOe9PDf8SxURjg4lPNkURZZDxdnHHE1SarHQqnSUqpw4F1byG6kxErokFTjgNp2kjyRDpx1WUg$ > > >> > >>> > > > > > >>> Tag: > > > > > >>> https://urldefense.com/v3/__https://gitbox.apache.org/repos/asf?p=groovy.git;a=tag;h=refs*tags*GROOVY_5_0_7__;Ly8!!GFN0sa3rsbfR8OLyAw!aTE-LsRa0qOkuOe9PDf8SxURjg4lPNkURZZDxdnHHE1SarHQqnSUqpw4F1byG6kxErokFTjgNp2kjyRmvXQoww$ > > >> > >>> Tag commit id: 061e5462ecd50521e881005a82f2733e31ca976a > > > > > >>> > > > > > >>> The artifacts to be voted on are located as follows (r85451). > > > > > >>> Source release: > > > > > >>> https://urldefense.com/v3/__https://dist.apache.org/repos/dist/dev/groovy/5.0.7/sources__;!!GFN0sa3rsbfR8OLyAw!aTE-LsRa0qOkuOe9PDf8SxURjg4lPNkURZZDxdnHHE1SarHQqnSUqpw4F1byG6kxErokFTjgNp2kjyQSz2JVOg$ > > >> > >>> Convenience binaries: > > > > > >>> https://urldefense.com/v3/__https://dist.apache.org/repos/dist/dev/groovy/5.0.7/distribution__;!!GFN0sa3rsbfR8OLyAw!aTE-LsRa0qOkuOe9PDf8SxURjg4lPNkURZZDxdnHHE1SarHQqnSUqpw4F1byG6kxErokFTjgNp2kjyQpsp9rgw$ > > >> > >>> > > > > > >>> Release artifacts are signed with a key from the following file: > > > > > >>> https://urldefense.com/v3/__https://dist.apache.org/repos/dist/release/groovy/KEYS__;!!GFN0sa3rsbfR8OLyAw!aTE-LsRa0qOkuOe9PDf8SxURjg4lPNkURZZDxdnHHE1SarHQqnSUqpw4F1byG6kxErokFTjgNp2kjySCMw7zpA$ > > >> > >>> > > > > > >>> Please vote on releasing this package as Apache Groovy 5.0.7. > > > > > >>> > > > > > >>> Reminder on ASF release approval requirements for PMC members: > > > > > >>> https://urldefense.com/v3/__http://www.apache.org/legal/release-policy.html*release-approval__;Iw!!GFN0sa3rsbfR8OLyAw!aTE-LsRa0qOkuOe9PDf8SxURjg4lPNkURZZDxdnHHE1SarHQqnSUqpw4F1byG6kxErokFTjgNp2kjyRvf488sA$ > > >> > >>> Hints on validating checksums/signatures (but replace md5sum with > > >> > >>> sha256sum): > > > > > >>> https://urldefense.com/v3/__https://www.apache.org/info/verification.html__;!!GFN0sa3rsbfR8OLyAw!aTE-LsRa0qOkuOe9PDf8SxURjg4lPNkURZZDxdnHHE1SarHQqnSUqpw4F1byG6kxErokFTjgNp2kjyS1WVRpgA$ > > >> > >>> > > > > > >>> The vote is open for the next 72 hours and passes if a majority > > > > > >>> of at > > > > > >>> least three +1 PMC votes are cast. > > > > > >>> > > > > > >>> [ ] +1 Release Apache Groovy 5.0.7 > > > > > >>> [ ] 0 I don't have a strong opinion about this, but I assume > > > > > >>> it's ok > > > > > >>> [ ] -1 Do not release Apache Groovy 5.0.7 because... > > > > > >>> > > > > > >>> Here is my vote: > > > > > >>> > > > > > >>> +1 (binding) > > > > > >>> > > > > > >>> > > > > > > > > >
