从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!
或
- 编译为ataylor建议
- 使用JSR-223,如此处所述
- 如果您使用的是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()