首页 文章

从Java调用Groovy函数

提问于
浏览
24

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

示例groovy脚本:

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

我查看了GroovyShell,GroovyClassLoader和GroovyScriptEngine .

6 回答

  • 2

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

    • 编译为ataylor建议

    • 使用JSR-223,如here所述

    • 如果您使用Spring,请使用实现Java接口的groovy类,并使用以下内容注入代码:


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

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

  • 35

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

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

    =)

  • 0

    一个简单的例子:

    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 !
    
  • 9

    更优雅的方式:

    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()
    

相关问题