Groovyの基礎
GroovyはJava VMで動作するスクリプト言語です。


インストール
以下はバージョン4.0.24の例です。

  1. 総本山からダウンロードし、 任意のディレクトリに展開します。
  2. 環境変数 JAVA_HOME、 GROOVY_HOME、 PATH (${GROOVY_HOME}/binを含める) を設定します。
  3. ${GROOVY_HOME}/binのgroovyやgroovyshで実行します。
または、groovyコマンドを使用せず、javaコマンドで

set GROOVY_HOME=C:\Wintools\groovy-4.0.24
set CLASSPATH=%GROOVY_HOME%\lib\groovy-4.0.24.jar
java groovy.ui.GroovyMain myscript.gv

のようにGroovy処理系を呼び出して実行することもできます。


Groovyを実行する簡単なバッチファイル

@echo off
set JAVA_HOME=C:\Wintools\jdk-17.0.5
set GROOVY_HOME=C:\Wintools\groovy-4.0.24
set CLASSPATH=%GROOVY_HOME%\lib\groovy-4.0.24.jar
set CLASSPATH=%CLASSPATH%;C:\usr\java\lib\commons-logging-1.1.jar
set CLASSPATH=%CLASSPATH%;C:\usr\java\lib\poi4\*
java groovy.ui.GroovyMain --encoding=sjis %1 %2 %3 %4 %5 %6 %7 %8 %9

JAVA_HOMEを環境変数で設定していない場合、このようにバッチファイルの中で設定しても良いでしょう。


スクリプト内で動的にCLASSPATHを追加する
同じJava言語のスクリプト実行ツールBeanShellには、addClassPathという、 スクリプトの中から動的にCLASSPATHを追加できる機能があります。 Groovyでも以下の方法で可能です。 注意が必要なのはGroovyの言語処理系というよりはgroovysh(GroovyShell)に含まれる機能なので、 スクリプトでGroovyShellを生成して、その中でスクリプトを実行するという若干奇矯な書き方になることです。

def classLoader = this.class.classLoader
classLoader.addURL(new File('/my/tools/mytool.jar').toURL())
def shell = new GroovyShell(classLoader)

script = """
import my.tool.MyTool
println "こんにちは。"

def s1 = "こんにちは。"
s2 = MyTool.encode(s1)
println s2
s3 = MyTool.decode(s2)
println s3
"""
shell.evaluate(script)

この方法であれば、スクリプトの実行に必要になるCLASSPATH定義が、 .bashrcやシェルスクリプトなど複数の場所に分散せずに済むため、 特にバッチ処理などで複数ユーザーで利用する汎用ツールを配布する目的に適していそうです。
もちろん、.bashrcやシェルスクリプトで定義したCLASSPATHに、 スクリプト内でこの方法でCLASSPATHを追加することもできます。柔軟に対応できますね。


(古) Groovyを実行するためのantファイルのテンプレート
以下は上記の方法を知らなかったときに頑張っていた古い方法です。
もっと色々なCLASSPATHを設定したいなどの場合、カレントディレクトリに以下のbuild.xmlを置いておけば、 コマンドラインプロンプトから「ant -Dscript=mysample.gv」のようにしても実行できます。

<project name="default" default="run.groovy" basedir=".">
  <property name="GROOVY_HOME" value="C:/Wintools2/groovy-1.5.4" />
  <property name="JAVALIBDIR" value="C:/usr/java/lib" />
  <property name="TOMCATLIBDIR" value="C:/Wintools2/Tomcat-5.5.20/shared/lib" />
  <property name="HSQLDBLIBDIR" value="C:/Wintools2/hsqldb/lib" />
  <property name="classpath" value="." />

  <!-- specify using -Dscript={script_file_name} option -->
  <property name="script" value="" />

  <target name="run.groovy">
  <java classname="groovy.ui.GroovyMain" fork="yes">
  <classpath>
    <pathelement path="${classpath}" />
    <pathelement location="${GROOVY_HOME}/embeddable/groovy-all-1.5.4.jar" />
    <pathelement location="${HSQLDBLIBDIR}/hsqldb.jar" />
    <pathelement location="${JAVALIBDIR}/xalan/xalan.jar" />
    <pathelement location="${JAVALIBDIR}/xalan/xercesImpl.jar" />
    <pathelement location="${JAVALIBDIR}/xalan/xml-apis.jar" />
  </classpath>
  <arg value="${script}" />
  </java>
  </target>
</project>


Javaとの違い
Groovyの文法は、ぱっと見「Java?」というくらいよく似ているので、違いだけを列挙してみましょう。

  • 文をクラスにまとめる必要はない。PerlやPythonなどと同様、スクリプト冒頭からいきなり文を書き始めてよい。
    ※クラスやメソッドは、それが使われるよりも後ろに定義されていてもよい。
  • 文末セミコロンは省略可能。
  • forループ構文はJavaとはまったく違う「in」を使った構文がある。例えばJavaの
    for(int i=0; i<nodes.getLength(); i++)
    は
    for(i in 0 .. nodes.length)
    のように書く。
    ※Groovy 1.5以降、一応Java形式の構文と両方使えるようになりました。
    GroovyからすればJava形式のfor構文ははっきり言って冗長なんですけど、 ユーザの熱望もあってサポートされたそうです。
  • return文のreturnキーワードは省略可能。Perlのように、最後に評価された値が返る。
  • 型宣言は省略でき、後から違う型の値を代入することも可。またauto-boxing機能もあり。
  • print, println, dumpという組み込みメソッドがある。
  • invokeMethod()で動的にメソッドを呼び出せる。
  • 文字列はPerlやPythonのように、一重引用符でも二重引用符でも囲める。
  • 二重引用符で囲んだ文字列の中に、「${式}」と書くと、 PerlやBシェルのように式の値が置き換わって埋め込まれる。
  • 二重引用符での文字列表現は、途中で改行されても閉じるまで有効。 またPHP風のヒアドキュメント(<<<EOS)や、 Python風の3つ並んだ二重引用符で囲んで複数行の文字列を表現することもできる。
  • Stringに、contains, count, tokenize, minus, multiply の各メソッドが追加されている。
  • 正規表現のために、Java SE regexのPatternやMatcherに対応する演算子が幾つかある。
  • 演算子はオーバーロードされている。例えば文字列は==で比較できる。 Javaの==、つまり完全に同一メモリにあるオブジェクトかどうかの比較はGroovyでは===。 Javaのa.compareTo(b)はPerlのように a <=> bと書ける。 またnullは比較演算においては限りなく小さい値として扱われる。
  • Mapに対する演算子 a[key] は a.get(key) の意味。 またa[key] = value は a.set(key, value)の意味。
  • java.io.*、java.util.* は最初からインポートされているので、明示的にimport文を書く必要はない。
  • クロージャのサポート
  • クラスのインスタンス変数は、privateを明示的につけない限り、setter/getterが自動生成される。
  • メソッド引数を囲む括弧は省略可能なことがある(コンストラクタの引数の括弧は省略不可)


コマンドライン引数
Groovyスクリプトに渡されたコマンドライン引数は、変数argsに配列として入っています。 args[0]から順番に取り出されます。Javaと同じく、 渡されたより多くの引数を取り出そうとすると、ArrayIndexOutOfBoundsExceptionが発生します。

println "[0]=[" + args[0] + "]"
for(arg in args){
    println "arg:" + arg
}


リストと配列
Groovyでは配列状のモノを簡単に

widths = [10,20,40,30]

と角括弧を使って定義できますが、これは配列ではなくJavaでいうjava.util.ArrayListを定義しています。 配列とリストを相互に変換するにはtoArray()、toList()メソッドを使う手もありますが、 ArrayList.toArray()を使っても、プリミティブデータ型の配列には変換できません。 最初からプリミティブデータ型の配列を定義したい場合は、データ型を添えて以下のように書きます。

float[] widths = [10,20,40,30]

これはJavaの配列定義によく似ていますが、中括弧ではなく角括弧を使う点に注意してください。
また同様に、

func(["John", "Bob", "Fred"])

とすると、Groovyの場合はString[]ではなくArrayListが渡ってしまいます。 String[]を渡したい場合は簡単には、

func((String[])["John", "Bob", "Fred"])

とキャスト(強制型変換)と同じ書き方でOKです。

Java kowaza Top

(first uploaded 2007/03/17 last updated 2025/01/12, URANO398)