web-dev-qa-db-ja.com

JavaからGroovy関数を呼び出す

JavaからGroovyスクリプトファイルで定義された関数をどのように呼び出しますか?

Groovyスクリプトの例:

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

GroovyShell、GroovyClassLoader、GroovyScriptEngineを見てきました。

27
joemoe

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!
39
tim_yates

最も簡単な方法は、スクリプトを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!
20
ataylor

どちらか

  1. テイラーの提案に従ってコンパイル
  2. 説明されているようにJSR-223を使用してください ここ
  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>

春のアプローチの1つの利点は、「さわやかな豆」の概念です。つまり、Springはスクリプトファイルの変更を監視し、実行時に置き換えるように構成できます。

9
toolkit

Bean Scripting Framework を使用して、任意のスクリプト言語をJavaコードに埋め込むことができます。BSFは他の言語を統合する機会を提供しますが、ネイティブ統合ではありません。

Groovyの使用に明確に集中している場合は、GroovyScriptEngineが最も完全なソリューションです。

=)

2
raulsaeztapia

簡単な例:

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 !
1
Alfredo Diaz

よりエレガントな方法:

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()
0
Eugene Lopatkin