从Java调用Groovy函数

时间:2010-10-21 16:16:29

标签: java groovy

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

示例groovy脚本:

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

我查看了GroovyShell,GroovyClassLoader和GroovyScriptEngine。

6 个答案:

答案 0 :(得分:36)

假设您有一个名为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!

答案 1 :(得分:19)

最简单的方法是将脚本编译成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!

答案 2 :(得分:9)

无论

  1. 编译ataylor建议
  2. 按照here
  3. 的说明使用JSR-223
  4. 如果您正在使用Spring,请使用实现Java接口的groovy类,并使用以下代码注入代码:

  5. <lang:groovy id="messenger" script-source="classpath:Messenger.groovy">
        <lang:property name="message" value="I Can Do The Frug" />
    </lang:groovy>
    

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

答案 3 :(得分:2)

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

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

=)

答案 4 :(得分:1)

一个简单的例子:

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 !

答案 5 :(得分:0)

更优雅的方式:

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.lang.Script方法,则无需延长main

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