覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

Groovy - Java上で定義した文字列をGroovyのScriptとして実行する

Java上で定義した文字列をGroovyのScriptとして実行するサンプルです

以下サンプルでは、Scriptで受け取った文字列をコンソールに出力して、"end"という文字列をreturnします。


■pom.xml

Mavenで取り合うことを前提として、pom.xmlには以下を追記します

<dependency>
    <groupId>org.codehaus.groovy</groupId>
    <artifactId>groovy-all</artifactId>
    <version>2.4.7</version>
</dependency>


■サンプルコード(.java)

BindingクラスでScriptに渡すパラメータをセットし、GroovyShell#evaluateでScriptを実行します。

import groovy.lang.Binding;
import groovy.lang.GroovyShell;

public class GroobyLauncher1 {

    public static void main(String[] args) {

        // Groovy の Scriptの内容
        String script = "println 'Hello World ' + name; 'end';";

        // 引数の設定
        Binding bind = new Binding();
        bind.setVariable("name", "SampleMan");  // このサンプルではパラメータ名はname

        GroovyShell gs = new GroovyShell(bind);
        String result = (String) gs.evaluate(script);

        System.out.printf("Result: " + result);
    }
}


■実行結果

Hello World SampleMan
Result: end


パラメータを受け渡す場合、Script内のパラメータ名とBinding#setVariableに指定するパラメータ名(第1引数)を一致させる必要があります(上記サンプルでは"name")。
仮にScript上のパラメータ名と一致しない場合、以下のような例外がスローされます

Exception in thread "main" groovy.lang.MissingPropertyException: No such property: name for class: Script1
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:53)
    at org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:52)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:307)
    at Script1.run(Script1.groovy:1)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:585)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:623)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:594)
    at sample.groovy.app.GroobyLauncher1.main(GroobyLauncher1.java:18)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)