On 2/11/25 23:13, Jonathan Carter wrote:
My team and I are trying to instrument JFR to monitor some of the deeper
activity of Groovy compilation in an app which runs Groovy Scripts.
We're trying to get a picture of what's going on when users have certain
hard-to-reproduce performance problems.

JFR = Java Flight Recorder

We setup a subclass of GroovyClassLoader that overrode
createCompilationUnit and parseClass, firing off some JFR events when
those methods get called.

We're hitting a wall with the
groovy.util.GroovyScriptEngine.ScriptClassLoader private class. While
that provides a bunch of useful cacheing, it doesn't delegate to the
parent classloader for createCompilationUnit  or parseClass. Instead, it
calls to super. I expect (though I don't know) that this is expected
behaviour for a Java classloader, and that a parent should only get
called when the child needs it.

In the JVM a class identity is determined by name and class loader. A
Classloader is supposed to return the same class each time. And a
Classloader is suppose to ask the parent first for a class.

But this is not normal class loading. This is on-demand compilation with
optional recompilation. And I think we violate in that about all of
those principles. Better not expect it to behave like a regular class
loader.

While I could create my own copy of groovy.util.GroovyScriptEngine and
manipulate the behavior there, my hunch is that there should be some
more maintainable way to monitor Groovy compilation. Some of them would
want to push some patches upstream to Groovy, perhaps there are some
that wouldn't require that.

If you want to monitor the compilation, then maybe you should go a step
deeper. GroovyScriptEngine is only a frontend to the compiler.

So, fellow Groovy devs, which of the following seems like the most
sensible path to meet the felt need of monitoring Groovy compilation?

 1. Adding some native JFR events to Groovy. This would necessarily
    target the Groovy 5+ line, since JFR is only freely available on
    OpenJDK 11+.
 2. Modifying how groovy.util.GroovyScriptEngine.ScriptClassLoader is
    declared or used so that it could be overridden, in part or in whole?
 3. Some third option born from a better mind than mine? :)

Please feel free to tell me if I'm missing something obvious, by the
way. It is probable!

maybe first we should define what activities you want to monitor. Is it
when a compilation is started/finished, is it class loading activity, is
it lookups on the file system, .... all of that?

bye Jochen

Reply via email to