0

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

Ashish
  • 1
  • 2
  • 1
    place compiled files into classpath that is accessible for groovyClassLoader only – daggett Jul 02 '21 at 11:50
  • @daggett How can we do that as RootClassLoader/AppClassLoader will have access to build/classes/main and as per loadClass method, it will check in cache first and then it will check in parent class loader. – Ashish Jul 02 '21 at 12:50
  • "How to set delegate after doing loadClass..." - What delegate are you wanting to set? – Jeff Scott Brown Jul 02 '21 at 13:12
  • It will be a different class(kind of parser) which will be used by script. Below code is from DelegatingScript. So similar way but after using loadClass instead of parsing. class MyDSL { public void foo(int x, int y, Closure z) { ... } public void setBar(String a) { ... } } CompilerConfiguration cc = new CompilerConfiguration(); cc.setScriptBaseClass(DelegatingScript.class.getName()); GroovyShell sh = new GroovyShell(cl,new Binding(),cc); DelegatingScript script = (DelegatingScript)sh.parse(new File("my.dsl")) script.setDelegate(new MyDSL()); script.run(); – Ashish Jul 02 '21 at 13:17
  • `gos.addClasspath('path/to/compiled/classes')` - after this classes from specific folder will be loaded by gos. – daggett Jul 02 '21 at 13:26
  • @daggett I tried this too but still it use AppClassLoader . loadClass method defined in the Groovy mentioned this : loads a class from a file or a parent classloader. – Ashish Jul 02 '21 at 14:14
  • probably you have to clarify your question. addClasspath working for me. – daggett Jul 02 '21 at 18:38
  • oh is it. You can checkout the screenshot attached to question. May be I am doing something wrong. – Ashish Jul 03 '21 at 05:34

1 Answers1

0

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.

Ashish
  • 1
  • 2