Hey folks,

I just wanted to follow-up on this. I am curious if this is something 
others
are seeing too.

Thanks,
Matt


------ Original Message ------
>From "Matt M" <[email protected]>
To "[email protected]" <[email protected]>
Date 8/29/2026 1:41:09 PM
Subject [Groovy 6] GROOVY-12137: - Indy Cold Reflection Snag/Defaults 
Inconsistency

>
>
>Hey folks,
>
>
>
>I wanted to send this over the mailing list as I am not sure it's a
>
>"bug" per-se and there might be some discussion on it too. Hopefully
>
>this is helpful all the same.
>
>
>
>I have been using Groovy 6's recent betas and believe I have found a
>
>snag with the new experimental invoke dynamic cold reflective
>
>feature/functionality. There's two "threads" for discussion here that
>
>are of note. I have split them out explicitly for the sake of
>
>convenience and clarity.
>
>
>
>—
>
>
>
>First: `groovy.indy.cold.reflection` Default Value Mismatch?
>
>
>
>It looks like the default value of `groovy.indy.cold.reflection` is
>
>set to true/on by default in the code at
>
>https://github.com/apache/groovy/blame/master/src/main/java/org/codehaus/groovy/vmplugin/v8/IndyInterface.java#L64.
>
>However, according to the Git commit message/PR description that
>
>merged in the feature and that line
>
>(https://github.com/apache/groovy/pull/2673), it is supposed to _off_
>
>by default. There's probably good arguments for both.
>
>
>
>My best guess is that the PR description/Git commit message is
>
>erroneous here and it really _is_ supposed to be enabled and on by
>
>default. However, I could very well likely be wrong and mistaken, I am
>
>just speculating.
>
>
>
>The slight mismatch not withstanding, I was a bit surprised to find
>
>this out anyway since the facility is listed as an experimental
>
>feature in the ticket GROOVY-12137 and throughout the code’s
>
>documentation (granted, it's listed as "incubating" in the release
>
>notes as part of AOT support). I would think that experimental
>
>features are generally are opt-in (i.e. I interpret experimental as
>
>not stable/reliable for production usage just yet). Not wrong and I am
>
>sure that the rationale behind it makes sense (i.e. if we don't turn
>
>it on then nobody would know to use it), just surprising that's all.
>
>
>
>BTW, regardless of how it's resolved, the feature flag is quite well
>
>hidden anyways. By sheer dumb luck, I only knew about this facility
>
>even being feature flagged since it was part of some other performance
>
>work I was doing on the compiler and just so happened to be of
>
>relevance that I had it in the back of my mind. It's not listed as
>
>having a toggle'able flag anywhere in the release notes on/at
>
>https://groovy-lang.org/releasenotes/groovy-6.0.html either. I would
>
>then guess that the feature flag is more of a convenience escape-hatch
>
>for rare edge cases as part getting the feature ready to be
>
>finalized/made production-ready, rather than an explicitly, fully
>
>supported switch intended for end-user configuration at their
>
>discretion?
>
>
>
>—
>
>
>
>Second: Cold Reflection & Callstack Snag.
>
>
>
>This is the actual root of the "problem" and where it gets interesting
>
>from a design perspective. Well, I am not sure it's _exactly_ a
>
>"problem" per-se. It _might_ be? So in truth, I only actually noticed
>
>something was wrong due to seeing my logs for my application all of a
>
>sudden start reporting JDK internal methods as the logger's callsite
>
>when using Groovy 6 (e.g. all of my logs were printing
>
>`jdk.internal.reflect.DirectMethodHandleAccessor.invoke` as the method
>
>where `log.info`/etc. was being invoked from instead of their real
>
>method). This was extremely suspicious and didn't make sense as to why
>
>logging all of a sudden just kind of broke.
>
>
>
>After some investigating, I found out why I was seeing
>
>`jdk.internal.reflect.DirectMethodHandleAccessor.invoke` as the
>
>callsite: the changes in IndyDispatch to support Cold Reflective
>
>Invocation. Thankfully Logback had a facility already baked in,
>
>`%caller{N}`, for dumping out the callstack's stack trace for a number
>
>of frames to make finding this out much easier.
>
>
>
>Without just papering over the issue by registering Groovy's internal
>
>compiler packages as framework internals in Logback, I thought about
>
>this a bit more: I wondered if this change might subtly affect other
>
>things that don't expect the callstack to change/have intermediaries
>
>when invoked dynamically? I haven't done a thorough investigation or
>
>spent time digging into this in any great depth, however, I would
>
>imagine that there are some deeper, subtler implications elsewhere
>
>that this might cause.
>
>
>
>I just happened to find this out via logging, which is not necessarily
>
>mission critical (though one could make the argument that having data
>
>silently go missing from logs is far from acceptable). I would be
>
>curious to see if anyone else runs into subtleties with having
>
>reflection based invocations enabled by default.
>
>
>
>I am not saying it's a bad feature or should be removed/changed or
>
>anything. Just food-for-thought.
>
>
>
>—
>
>
>
>Anyhow, I just thought I should surface this to the team and in case
>
>anyone else runs into this issue, they can understand "what" and “why”
>
>a little easier. Maybe this should get some eyeballs on it before
>
>Groovy 6 ships so that if it needs some tweaking or extra
>
>documentation, it can be ready in time?
>
>
>
>Thanks,
>
>Matt

Reply via email to