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
