从Java调用Groovy函数

如何从Java调用Groovy脚本文件中定义的函数?

示例groovy脚本:

def hello_world() { println "Hello, world!" } 

我查看了GroovyShell,GroovyClassLoader和GroovyScriptEngine。

假设您有一个名为test.groovy的文件,其中包含(如您的示例所示):

 def hello_world() { println "Hello, world!" } 

然后你可以像这样创建一个Runner.java文件:

 import groovy.lang.GroovyShell ; import groovy.lang.GroovyClassLoader ; import groovy.util.GroovyScriptEngine ; import java.io.File ; class Runner { static void runWithGroovyShell() throws Exception { new GroovyShell().parse( new File( "test.groovy" ) ).invokeMethod( "hello_world", null ) ; } static void runWithGroovyClassLoader() throws Exception { // Declaring a class to conform to a java interface class would get rid of // a lot of the reflection here Class scriptClass = new GroovyClassLoader().parseClass( new File( "test.groovy" ) ) ; Object scriptInstance = scriptClass.newInstance() ; scriptClass.getDeclaredMethod( "hello_world", new Class[] {} ).invoke( scriptInstance, new Object[] {} ) ; } static void runWithGroovyScriptEngine() throws Exception { // Declaring a class to conform to a java interface class would get rid of // a lot of the reflection here Class scriptClass = new GroovyScriptEngine( "." ).loadScriptByName( "test.groovy" ) ; Object scriptInstance = scriptClass.newInstance() ; scriptClass.getDeclaredMethod( "hello_world", new Class[] {} ).invoke( scriptInstance, new Object[] {} ) ; } public static void main( String[] args ) throws Exception { runWithGroovyShell() ; runWithGroovyClassLoader() ; runWithGroovyScriptEngine() ; } } 

编译它:

 $ javac -cp groovy-all-1.7.5.jar Runner.java Note: Runner.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 

(注意:警告留给读者练习);-)

然后,您可以运行此Runner.class:

 $ java -cp .:groovy-all-1.7.5.jar Runner Hello, world! Hello, world! Hello, world! 

最简单的方法是将脚本编译成java类文件,然后直接调用它。 例:

 // Script.groovy def hello_world() { println "Hello, World!" } // Main.java public class Main { public static void main(String[] args) { Script script = new Script(); script.hello_world(); } } $ groovyc Script.groovy $ javac -classpath .:$GROOVY_HOME/embeddable/groovy-all-1.7.5.jar Main.java $ java -classpath .:$GROOVY_HOME/embeddable/groovy-all-1.7.5.jar Main Hello, World! 

  1. 编译为ataylor建议
  2. 使用JSR-223,如此处所述
  3. 如果您使用的是Spring ,请使用实现Java接口的groovy类,并使用以下代码注入代码:

    

弹簧方法的一个优点是’可刷新的豆’的概念。 也就是说,可以将Spring配置为监视脚本文件以进行修改,并在运行时替换。

您也可以使用Bean Scripting Framework将任何脚本语言嵌入到Java代码中。 BSF为您提供了集成其他语言的机会,但不是本机集成。

如果你明确专注于使用Groovy,GroovyScriptEngine是最完整的解决方案。

=)

一个简单的例子:

 import groovy.lang.GroovyClassLoader; import groovy.lang.Script; public class GroovyEmbedder { static public final String GROOVY_SCRIPT= "println ('Hello World !')"; static public void main(String[] args) throws Exception { ((Script) new GroovyClassLoader().parseClass(GROOVY_SCRIPT).newInstance()).run(); } } 

测试

 > javac -cp groovy-all-2.4.10.jar GroovyEmbedder.java > java -cp groovy-all-2.4.10.jar:. GroovyEmbedder Hello World ! 

更优雅的方式:

 GroovyScriptEngine engine = new GroovyScriptEngine( "." ) Object instance = engine .loadScriptByName(scriptName) .newInstance() Object result = InvokerHelper.invokeMethod(instance, methodName, args) 

如果脚本类扩展了groovy.lang.Script

 Object result = engine .createScript(scriptName, new Binding()) .invokeMethod(methodName, args) 

如果你只想调用你的groovy类的main方法,就不需要扩展groovy.lang.Script

 Object result = engine .createScript(scriptName, new Binding()) .run()