Вызов Groovy-функции из Java - PullRequest
       17

Вызов Groovy-функции из Java

25 голосов
/ 21 октября 2010

Как вызвать функцию, определенную в файле скрипта Groovy из Java?

Пример скрипта groovy:

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

Я посмотрел на GroovyShell, GroovyClassLoader и GroovyScriptEngine.

Ответы [ 6 ]

38 голосов
/ 22 октября 2010

Предполагается, что у вас есть файл с именем 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 голосов
/ 21 октября 2010

Самый простой способ - скомпилировать скрипт в файл класса 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!
9 голосов
/ 21 октября 2010

Либо

  1. Компилировать, как предполагает ataylor
  2. Использовать JSR-223, как описано здесь
  3. Если вы используете Spring, имейте класс groovy, который реализует интерфейс Java, и вставьте в ваш код:

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

Одним из преимуществ весеннего подхода является концепция 'освежающие бобы.То есть Spring можно настроить для отслеживания изменений в файле сценария и замены во время выполнения.

2 голосов
/ 23 ноября 2013

Вы также можете использовать Bean Scripting Framework для встраивания любого языка сценариев в код Java.BSF дает вам возможность интегрировать другие языки, но не является встроенной интеграцией.

Если вы четко ориентированы на использование Groovy, GroovyScriptEngine является наиболее полным решением.

=)

1 голос
/ 25 мая 2017

Один простой пример:

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 !
0 голосов
/ 12 января 2018

Просто более элегантные способы:

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...