Running ginq from a "clean" classloader

Per Nyfelt <[email protected]> Mon, 28 Apr 2025 20:23:03 +0200
Newsgroups gmane.comp.lang.groovy.user
Organization Alipsa HB
Message-ID <[email protected]>
Hi,

I am experimenting with running groovy scripts in a "clean" environment 
i.e. in a GroovyClassloader that does not have a parent.

Background: One of my OSS projects is an analytics IDE where i want to 
enable users to run scripts that only has the dependencies of a gradle 
build script and hence i need to separate the IDE classloader from the 
one running the script.

However, i have run into an issue with ginq expressions that baffles me.

A complete but minimal example is here: 
https://github.com/perNyfelt/groovy-issues/tree/main/NoParentCL but the 
issue is basically:

The groovy script is

def numbers = [0, 1, 2] println "Numbers are $numbers" var result = GQ { 
from n in numbers where n > 0 select n } println "Ginq result is $result"

After creating the GroovyClassloader i add the following files to the 
classpath: groovy-4.0.26.jar, groovy-ginq-4.0.26.jar, 
groovy-macro-4.0.26.jar

When is do

new GroovyShell(new GroovyClassloader()).evaluate(script)

everything works fine but if i do

new GroovyShell(new GroovyClassloader((Classloader)null).evaluate(script)

I get

Exception in thread "main" groovy.lang.MissingMethodException: No 
signature of method: Script1.GQ() is applicable for argument types: 
(Script1$_run_closure1) values: [Script1$_run_closure1@5cb5bb88]
Possible solutions: is(java.lang.Object), run(), run(), any(), grep(), 
any(groovy.lang.Closure)
         at 
org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:72)
         at 
org.codehaus.groovy.vmplugin.v8.IndyGuardsFiltersAndSignatures.unwrap(IndyGuardsFiltersAndSignatures.java:163)
         at 
org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
         at Script1.run(Script1.groovy:3)
         at 
java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
         at java.base/java.lang.reflect.Method.invoke(Method.java:580)
         at 
org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
         at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
         at 
groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1333)
         at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1088)
         at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1007)
         at 
org.codehaus.groovy.runtime.InvokerHelper.invokePojoMethod(InvokerHelper.java:633)
         at 
org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:624)
         at 
org.codehaus.groovy.runtime.InvokerHelper$1.run(InvokerHelper.java:461)
         at groovy.lang.GroovyShell.evaluate(GroovyShell.java:460)
         at groovy.lang.GroovyShell.evaluate(GroovyShell.java:495)
         at groovy.lang.GroovyShell.evaluate(GroovyShell.java:469)
         at RunScript.runScript(RunScript.java:37)
         at RunScript.main(RunScript.java:18)

Does anyone know why that would be the case and/or a possible workaround?

Regards,
Per