Scripting Java is Groovy
I wanted to see if I could create a simple program that would evaluate a Groovy script and return its result. I've found the documentation and examples about embedding Groovy somewhat lacking. There are plenty of examples and tutorials on how to use it like you would perl or python but very few about using it within an application framework. So I started with:
package com.fortunemegastore.groovy.tests;
import groovy.lang.GroovyShell;
import groovy.lang.Binding;
import groovy.lang.Closure;
import org.codehaus.groovy.control.CompilationFailedException;
import java.io.File;
import java.io.IOException;
public class GroovyTest {
public static void main(String[] args){
GroovyShell shell = new GroovyShell(new Binding());
try {
shell.setVariable("g", new Double(9.8));
shell.setVariable("m1", new Double(10));
shell.setVariable("m2", new Double(20));
shell.setVariable("d", new Double(2));
shell.evaluate(new File("equation.groovy"));
Closure solve = (Closure) shell.getVariable("foo");
System.err.println(solve.call());
} catch(IOException ioe){
ioe.printStackTrace();
} catch(CompilationFailedException cfe){
cfe.printStackTrace();
}
}
}
This class intiliazes a GroovyShell to interpret scripts, sets up some variables for the script, then evaluates the script. Within the script, the result is stored in the variable "foo". The evaluated script is:
foo = { f = (g*m1*m2)/(d*d); return f; }
Simple huh? The beauty of this is that any string can be evaluated by the parser. If you had a number of different equations to solve a problem, you could plug any one of them into this script and get a result. This is great but the example above has to set variables and depends on a specific variable being present to process the result. I'd rather do this in an object oriented way. For that, I created a second experiment:
package com.fortunemegastore.groovy.tests;
import java.io.File;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
public class GroovyTest2 {
public static void main(String[] args){
GroovyShell shell = new GroovyShell(new Binding());
try {
NameInterface ni = (NameInterface) shell.evaluate(new File("class.groovy"));
System.err.println("Name: " + ni.getName());
System.err.println("Foo Result: " + ((FooInterface) ni).foo(5,6));
} catch(Exception e){
e.printStackTrace();
}
}
}
Which processes the script:
import com.fortunemegastore.groovy.tests.NameInterface;
import com.fortunemegastore.groovy.tests.FooInterface;
class Thing implements NameInterface, FooInterface {
String name
int foo(int a, int b){
return a + b;
}
}
return new Thing(name:"The Thing");
Here I have defined a new class in Groovy that implements interfaces defined in Java.
The two interfaces are extremely simplistic:
package com.fortunemegastore.groovy.tests;
public interface NameInterface {
public void setName(String name);
public String getName();
}
package com.fortunemegastore.groovy.tests;
public interface FooInterface {
public int foo(int a, int b);
}
The Thing class is evaluated in Groovy with the resulting object returned to GroovyTest2's control. I have implemented foo(int a, int b) to return the sum of its parameters. Another class implemented through Groovy scripting could return some other value. Neither affects the source of the java program! The output of the program is:
Name: The Thing
Foo Result: 11


0 Comments:
Post a Comment
<< Home