代码之家  ›  专栏  ›  技术社区  ›  joemoe

从Java调用Groovy函数

  •  24
  • joemoe  · 技术社区  · 15 年前

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

    groovy脚本示例:

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

    我已经看过GroovyShell、GroovyClassLoader和groovyscript引擎。

    6 回复  |  直到 15 年前
        1
  •  39
  •   tim_yates    15 年前

    假设你有一个名为 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!
    
        2
  •  20
  •   ataylor    15 年前

    最简单的方法是将脚本编译成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!
    
        3
  •  9
  •   Jmini Peter Kriens    10 年前

    或者

    1. 按照ataylor的建议编译
    2. 按照说明使用JSR-223 here
    3. 如果你正在使用 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方法的一个优点是“可刷新bean”的概念。也就是说,Spring可以配置为监视脚本文件的修改,并在运行时替换。

        4
  •  2
  •   raulsaeztapia    12 年前

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

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

    =)

        5
  •  1
  •   Alfredo Diaz    8 年前

    一个简单的例子:

    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 !
    
        6
  •  0
  •   Eugene Lopatkin    8 年前

    更优雅的方式:

    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 groovy类的方法:

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