5
votes

I have a problem with inheritance in Groovy script. I want my Groovy script to inherit methods from Java class that I invoke this script.

For example, I have something like this:

public class SimpleTest extends TestCase {

public void test(){
    CompilerConfiguration configuration = new CompilerConfiguration();
    configuration.setScriptBaseClass(this.getClass().getName());
    GroovyShell shell = new GroovyShell(this.getClass().getClassLoader(), new Binding(), configuration);
    shell.evaluate("println sayHello()");
}

public String sayHello(){
    return "Hello";
}
}

And the error is:

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: Script1.groovy: 1: Declared type com.test.SimpleTest does not extend groovy.lang.Script class! @ line 1, column 1. println sayHello() ^ 1 error

How can I do this if I cannot inherit any other class? I want to invoke method just only like from superclass.

Edit

I changed my class to something like this:

public class CmTest extends TestCase {

public void test(){
    GroovyHandler handler = new GroovyHandler();
    handler.run();
}

public String sayHello(){
    return "Hello";
}

public class GroovyHandler extends Script {

    public GroovyHandler(){
    }

    @Override
    public Object run() {
        CompilerConfiguration configuration = new CompilerConfiguration();
        configuration.setScriptBaseClass(this.getClass().getName());
        GroovyShell shell = new GroovyShell(CmTest.class.getClassLoader(), new Binding(), configuration);
        return shell.evaluate("println sayHello()");
    }
}
}

Now the error is:

java.lang.NoSuchMethodError: com.test.SimpleTest$GroovyHandler: method < init >()V not found at Script1.(Script1.groovy) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) at java.lang.Class.newInstance0(Class.java:355) at java.lang.Class.newInstance(Class.java:308) at org.codehaus.groovy.runtime.InvokerHelper.createScript(InvokerHelper.java:429) at groovy.lang.GroovyShell.parse(GroovyShell.java:704) at groovy.lang.GroovyShell.evaluate(GroovyShell.java:588) at groovy.lang.GroovyShell.evaluate(GroovyShell.java:627) at groovy.lang.GroovyShell.evaluate(GroovyShell.java:598) ...

2

2 Answers

0
votes

The class that is going to be used in the script must extend Script

Example:

class ScriptTest extends Script {
    def SayHello() {
        return "Hello"
    }
}

Then you setScriptBaseClass to this particular class

0
votes

I have solved my problem. The solution is class DelegatingScript. Link to doc: http://docs.groovy-lang.org/latest/html/gapi/groovy/util/DelegatingScript.html