-1 (binding)

I was hoping that my earlier on the indy cold reflection issue _might_
have been caught early enough to get the issue addressed before the
next release window; however, given that we are escalating from Groovy
6 being in beta to a first release candidate, I feel that I should
call this out as a blocking issue and be a voice of dissent.

TL;DR: Given this is an RC, the issue surfaced with
`groovy.indy.cold.reflection` being enabled/on by default and how it
affects the callstack
(https://issues.apache.org/jira/browse/GROOVY-12354) has enough
possible friction points, gotchas, and potential pitfalls for an
unsuspecting end user, that the RC release should be re-rolled to
address it.

—

Essentially, I am suggesting re-rolling the RC release to either fix
this issue or change the default for `groovy.indy.cold.reflection` to
be off by default.

I emailed several days ago regarding the indy dispatch's cold
reflection invocation change now "polluting" (for lack of a better
phrase) the callstack with Groovy and JDK internals and the feature
flag for it being enabled/on by default (and hidden very well). This
change causes some subtle "breakages" (again, for lack of a better
phrase) that are invisible to end users who know nothing about
Groovy's compilation internals. Beyond that, this feature is geared,
applicably, for highly performance sensitive scenarios/AOT compilation
focused JVM's (i.e. GraalVM) so it's maybe not broadly practical to
enable it by default (i.e. there's an argument to be said for paying
the performance cost of method handles upfront at first-invocation
versus at unknown points later on in the application lifecycle), as
well as it's very new and still incubating/experimental.

>From an end user perspective, the new default for how Groovy handles
dynamic invocations is a very obscure compiler implementation detail,
and yet has not necessarily insignificant implications and
unsuspecting effects on end user code. An end user won't know, and
shouldn't _really_ need to care, and will not suspect/expect that the
language's compiler is changing how the callstack is being constructed
for dynamic invocations. They won't know that the callstack _could_ be
getting polluted with compiler/language internals from the change and
having unexpected shifts in _exactly_ how Groovy works by using
Reflection for invoking methods up until another very obscure
implementation detail threshold is reached (again, from their
perspective).

Furthermore, an end user will see erroneous compiler internals exposed
in places where they shouldn't be and are misleading (e.g. logging
statements that say JDK compiler internals are where code is
executing). This leads to a number of false lines of thought and false
conclusions for investigating:

- They may suspect that an external library is broken when it's not
   (they may even send misleading upstream bug reports causing those
   folks to be just as confused)
- They may be suspecting their own usages of reflection to be causing
   issues when they aren’t
- They may suspect that other libraries are conflicting and causing
   breakages when they aren’t
- They may suspect the Groovy language is incompatible with external
   libraries when it's not
- They may be completely confounded as to what is happening and why
   stuff is reflecting all of a sudden (especially when they are not
   using reflection API's themselves)

There's an even nastier, subtler effect: they will experience a pseudo
Schrodinger's Cat bug depending on how long their JVM has been running
and whether or not various methods/code paths have or have not hit the
indy dispatch's threshold limit where it shifts back from reflective
calls to full, proper, complete method handles for dynamic invocation.
It will seem that it's as if the code starts off incorrect and then
eventually, could, become correct (which could change when you check
it and maybe only because you checked it).

They may suspect some kind of threading, race-condition, or state
pollution bug in their code, external library code, or the language
based on when/if the affected code seems to work/not work (i.e. the
threshold was hit or wasn’t).

Again, if they are not intimately familiar with the compiler (and why
would they be), they will be confused and frustrated (i.e. imagine
production works (since it's long-running and highly likely to hit
threshold) but a local dev environment isn't (since it's _not_
long-running and unlikely to hit the threshold)).

Couple that all with the fact that it's all highly relativistic to
whether or not certain code paths get hit often or not, so imagine the
inverse whereby maybe production _doesn't_ hit a certain code path but
local dev _does_ since it may have extra debugging code causing hot
spots for optimization then.

I know that if I wasn't familiar with the language's compiler and
didn't just happen to know about this obscure change, that I would
suspect several of the aforementioned items. It's as if some affected
code sometimes works and sometimes doesn't work _exactly_ as expected.

All in all, not fun.

Anyhow, that's my vote and rationale.

Thanks
Matt


------ Original Message ------
>From "Paul King" <[email protected]>
To "Groovy_Developers" <[email protected]>
Date 9/4/2026 5:19:53 AM
Subject [VOTE] Release Apache Groovy 6.0.0-RC-1

>
>
>Dear development community,
>
>
>
>I am happy to start the VOTE thread for a Groovy 6.0.0-RC-1 release!
>
>
>
>This release includes 51 bug fixes/improvements as outlined in the changelog:
>
>https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12318123&version=12357479
>
>
>
>Tag: 
>https://gitbox.apache.org/repos/asf?p=groovy.git;a=tag;h=refs/tags/GROOVY_6_0_0_RC_1
>
>Tag commit id: 7f4b9cd30b05c5a076967e926c76719fd099f61e
>
>
>
>The artifacts to be voted on are located as follows (r87177).
>
>Source release: 
>https://dist.apache.org/repos/dist/dev/groovy/6.0.0-RC-1/sources
>
>Convenience binaries:
>
>https://dist.apache.org/repos/dist/dev/groovy/6.0.0-RC-1/distribution
>
>Temporary artifacts:
>
>https://repository.apache.org/content/repositories/orgapachegroovy-1121
>
>
>
>Release artifacts are signed with a key from the following file:
>
>https://dist.apache.org/repos/dist/release/groovy/KEYS
>
>
>
>Please vote on releasing this package as Apache Groovy 6.0.0-RC-1.
>
>
>
>Reminder on ASF release approval requirements for PMC members:
>
>http://www.apache.org/legal/release-policy.html#release-approval
>
>Hints on validating checksums/signatures (but replace md5sum with sha256sum):
>
>https://www.apache.org/info/verification.html
>
>
>
>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 6.0.0-RC-1
>
>[ ]  0 I don't have a strong opinion about this, but I assume it's ok
>
>[ ] -1 Do not release Apache Groovy 6.0.0-RC-1 because...
>
>
>
>Here is my vote:
>
>
>
>+1 (binding)

Reply via email to