Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GroovyShell: embedded execution

I'm trying to embed groovy into a large Java application.

The Java application should load some utility Groovy scripts at startup.

The application should then run other scripts multiple times. There is also a need to enter some code at a GUI and execute it at user request.

The problem I'm facing is this:

I am loading the startup script like this:

GroovyShell gShell = new GroovyShell();
gShell.evaluate(new FileReader("scripts/autoload.groovy"));

Suppose my autoload.groovy contains:

def prnt(m) {
    println("From Groovy: " + m);
}

This works fine. But when I want to run a user command using:

gShell.evaluate("prnt 66");

I get the error: groovy.lang.MissingMethodException: No signature of method: Script2.prnt() is applicable for argument types: (java.lang.Integer) values: [66]

How can my user script access the methods already loaded?

Note: I have also tried "autoload.prnt 88", and still get the error.

like image 632
Ayman Avatar asked Oct 08 '22 03:10

Ayman


1 Answers

Each evaluate call is compiled and run as a separate Script, and

def prnt(m) {
    println("From Groovy: " + m);
}

defines a method in the Script class generated from autoload.groovy, which is not accessible from the subsequent "calling" script. However, the scripts run by the same GroovyShell share the same binding, so you can store values in the binding from one script and access them in another. Storing a value in the binding is simply a case of assigning the value to an otherwise undeclared variable:

prnt = { m ->
    println("From Groovy: " + m);
}

This stores a closure in the binding variable prnt, and you can call the closure from other scripts in the same shell. Note that

def prnt = { m ->

or

Closure prnt = { m ->

would not work, because the def or type makes it a local variable declaration (private to this particular script) rather than an assignment to the binding.

like image 72
Ian Roberts Avatar answered Oct 12 '22 23:10

Ian Roberts