ちょっと思い立った小ネタとして。
JSR-223でGroovyが使えますが、このスクリプト中でGrapeを使うには?と。
準備
とりあえず、JSR-223でGroovyを動かすには、Maven依存関係に「groovy-jsr223」または「groovy-all」があればOKです。
<dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-jsr223</artifactId> <version>2.4.7</version> </dependency> <!-- groovy-allでも可 --> <!-- <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> <version>2.4.7</version> </dependency> -->
動作確認にはテストコードで。
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> <version>3.5.2</version> </dependency>
コードを書く
動作確認用のコードは、側はこんな感じに。
src/test/java/org/littlewings/scripting/groovygrape/GroovyScriptingTest.java
package org.littlewings.scripting.groovygrape; import java.util.Arrays; import java.util.stream.Collectors; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; public class GroovyScriptingTest { // ここにテストを書く }
とりあえず、ふつうにJSR-223越しにGroovyを使ってみましょう。
@Test public void simpleExecuteGroovy() throws ScriptException { ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("groovy"); assertThat(scriptEngine.eval("'Hello Groovy'.replace('Groovy', 'World')")) .isEqualTo("Hello World"); }
まあ、ふつうに動きます。
では、スクリプト内にGrapeを使ったコードを仕込んでみます。
@Test public void usingGrapes() throws ScriptException { ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("groovy"); String script = Arrays .asList( "@Grab('org.apache.commons:commons-lang3:3.4')", "import org.apache.commons.lang3.StringUtils", "", "def target = 'Hello World!!!'", "StringUtils.replace(target, 'World', 'Groovy')" ) .stream() .collect(Collectors.joining(System.lineSeparator())); assertThat(scriptEngine.eval(script)) .isEqualTo("Hello Groovy!!!"); }
対象には、Commons Lang 3になってもらいました。
で、動かすとエラーになります。
java.lang.NoClassDefFoundError: org/apache/ivy/core/report/ResolveReport
これを回避するには、依存関係にApache Ivyを加えます。
<dependency> <groupId>org.apache.ivy</groupId> <artifactId>ivy</artifactId> <version>2.4.0</version> </dependency>
Grapeは、Apache Ivyで動いているんでした、と。
こうすると、先ほどのCommons Lang 3を使ったコードはちゃんと動作するようになります。