I just discover Groovy call from Java and have problem with this case :
I have a groovy file : "test.groovy"
a = 1.0
def mul2( x ) { 2.0 * x }
And I want to use it from Java code like this
GroovyShell gs = new GroovyShell();
gs.parse( new File( ".../test.groovy" ) ).run();
System.out.printf( "a = %s%n", gs.evaluate("a") ); // ok
System.out.printf( "mul2(a) = %s%n", gs.evaluate( "mul2(a)" ) ); // error
The error is :
groovy.lang.MissingMethodException: No signature of method: Script1.mul2() is applicable for argument types: (BigDecimal) values: [1.0]
What I have to do to have access to function defined in groovy script, using evaluate() method ?
I need to use "evaluate" method because I want finally to evaluate something like Math.sin( a * mul2(Math.Pi) ).
Now I have 4 solutions (the forth is what I searched for) :
- use closure as in answer of 'Szymon Stepniak'
- use import static as in answer of 'daggett'
- extends the script that contains Java functions with the script that evaluate the expression :
...the class (in Java, not Groovy)...
public static abstract class ScriptClass extends Script
{
double mul2( double x )
{
return x * 2;
}
}
...the code...
CompilerConfiguration config = new CompilerConfiguration();
config.setScriptBaseClass(ScriptClass.class.getName());
GroovyShell gs = new GroovyShell(config);
System.out.printf( "result = %s%n", gs.evaluate("mul2(5.05)") );
That works but the code is in Java, not what I want, but I note it here for ones need to do that
- And finally extends groovy script :
the groovy file :
double mul2( x ) { x * 2 }
a=mul2(3.33)
the java code that use it
GroovyClassLoader gcl = new GroovyClassLoader();
Class<?> r = gcl.parseClass( resourceToFile("/testx.groovy") );
CompilerConfiguration config = new CompilerConfiguration();
config.setScriptBaseClass(r.getName());
GroovyShell gs = new GroovyShell(gcl, config);
System.out.printf( "mul2(5.05) = %s%n", gs.evaluate("mul2(5.05)") );
// WARNING : call super.run() in evaluate expression to have access to variables defined in script
System.out.printf( "result = %s%n", gs.evaluate("super.run(); mul2(a) / 123.0") );
It's exactly what I wanted :-)
gs.evaluateyou are parsing a new groovy script and absolutely not connected with previously parsed scripts.