Search code examples
groovyclassloadergroovyshellgroovyclassloader

How to use GroovyClassLoader to load GroovyCompiled classes or how to set delegate in case of loadClass


I am trying to loadClass which are compiled during build and placed in classpath as .class files. For this I tried

GroovyClassLoader gos = new GroovyClassLoader();

gos.loadClass("className");

This will successfully load the class file in java code but it uses AppClassLoader to load this not GroovyClassLoader.

I understand that GroovyClassLoader internally finds it using AppClassLoader. But there is a difference :

As gos.parseClass(string) will give us a class parsed from GroovyClassLoader.

While instantiating class file in second case(parseClass) give us delegate to set Delegate but in the first case(loadClass), we don't have any.

How to set delegate after doing loadClass or any way to load class file through GroovyClassLoader.

Load Class


Solution

  • Groovy Compiler compiles the groovy files(HelloWorld.dsl) and put them in class path creating .class file(HelloWorld.class) with same name. By default compiled class file(open the byte code) have class(HelloWorld) with same name as of class file.

    This class will get extended from Script. Now if you try to load this class file using gos.loadClass("HelloWorld").newInstance() , it will give us a Script object and we won't be able to set a delegate to a Script object. Also it won't get converted into DelegatingScript.

    To make your compile class extended from DelegatingScript add this at top of your dsl file @groovy.transform.BaseScript DelegatingScript delegatingScript . Groovy compiler will understand that and make the class files to get extended from DelegatingScript instead of Script as it was earlier.

    Now when you try to load class using gos.loadClass("HelloWorld").newInstance(), it will give a DelegatingScript object not a Script object. To this object, we can set the delegate and run the script.

    To use a delegate if you are using parseClass, we need to setScriptBaseClass as DelegatingScript to compilerConfiguration. Now if you try gos.parseClass(dslText).newInstance() , it will give directly give a DelegatingScript object and we can set a delegate and run the script.