vol.6

Magazine

Japan Grails/Groovy User Group

Contents
Series 10

Groovy 臨機応変（第一回）〜動中の静…Groovy 2.1.0 の新機能 その 1 〜… …… 4
Series 11

アプリケーションを Groovy でコントロールする…… 9Series 12

オレオレ・プログラミング GROOVY… ……………… 12
Series 13『Yokohama.groovy』について〜活動報告など〜……………………………………… 16

Series 05

Grails Plugin 探訪〜第 7 回 Remote Methods プラグイン〜… ………… 18
JGGUG ４コマ漫画「ぐるーびーたん」第 6 話… …… 21
Information

リリース情報…………………………………………… 22

G*Magazine vol.6

Groovy臨機応変（第一回）〜動中の静…Groovy 2.1.0の新機能 その1〜

10

上原 潤二（うえはら じゅんじ）

seriesNTT ソフトウェア株式会社 Grails 推進室所属。JGGUG（日本 Grails/Groovy ユーザ会）運営委員。
「Grails 徹底入門」（翔泳社）、「プログラミング GROOVY」（技術評論社）執筆メンバーの 1 人。
Groovy 技術に関するブログ「Gr な日々」を主宰している。

はじめにこんにちは、JGGUG の上原（NTT ソフトウェア株式会社所属）です。G* マガジンに記事を書くのは初めてとなります。このシリーズでは、Groovy の機能について紹介していきます。今回および次回では、この記事が掲載されているころには既にリリース済みの予定である、Groovy 2.1.0 で導入された一連の新機能について紹介していく予定です。なお、今回の記事の内容は記事執筆時点で入手可能な Groovy 2.1.0 RC1 バージョンに基づいており、最終リリース版では仕様や動作が変更されている可能性もあることをあらかじめご了承ください。

Groovy 2.1.0 は、メジャーバージョンアップであった 2.0 に引き続くマイナーバージョンアップです。Groovy 2.0 リリースはインフラレベルの大きな機能拡張をドカンと提供するものでしたが、それを踏まえての 2.1.0 リリースは、2.0 で導入された機能をより使いやすく発展させるための機能が含まれており、実用性を高めるための周辺手段が整って来たような印象です。Groovy 2.0の新機能については参考 [1]、[2] などを参考下さい。

今回は、Groovy 2.1.0 の新機能の中で「静的 Groovy」機能に関能なプロパティです。インスタンスメソッド呼び出し「object.
method()」において、「object」がレシーバです。インスタンス

メソッド中のコードでレシーバを省略したときには通常メソッドが所属するクラスのインスタンス this がレシーバとして扱われますが、それと同様にクロージャでは delegate プロパティが保持するオブジェクトを暗黙のレシーバとして呼び出そうとします。

要は delegate は、クロージャにおける「this」のようなものです。
delegate は 動 的 に 定 ま る プ ロ パ テ ィ で あ る が 故 に 静 的 型

チェックには本来参与できないのですが、@DelegatesTo アノテー
ションで delegate プロパティが保持するオブジェクトの型を明示的に指定してやることで、delegate プロパティが示すオブジェ
クトのメソッド呼び出しやプロパティ参照について静的型チェックができるようになります。

このような言葉での説明だけでは理解しにくいと思うので、以降では例を示しながら解説します。

■@DelegatesTo の使用例

まず、Groovy 標準の with 句と同じような効果を発揮する以下連のある以下について紹介します。

のようなメソッド「myWith」を定義することを考えてみます。

• @DelegatesTo

が、ここでは通常のメソッドとして定義します。

• 型チェックを拡張し、カスタマイズする• コンパイラ設定スクリプト

本来の with 句は、Object クラスに追加された GDK メソッドです

def myWith(Object self, Closure cl) {cl.delegate = self

• コンパイラ設定ビルダ

Groovy 2.0 及び 2.1 の新機能については、参考 [1]（プログラミ

ング GROOVY 別冊：第８章 Groovy 2.0 の新機能）なども参考にしてください。

@DelegatesTo@DelegatesTo は静的型チェックを強化するために導入された

新規の AST 変換アノテーションであり、groovy.transform.* パッ
ケージに所属します。

@DelegatesTo アノテーションを解説する前に、delegate プロ

パティについて補足しておきます。クロージャにおける delegate
プロパティとは、クロージャ中のコードにおいて、レシーバとなるオブジェクトを明示的に指定していないメソッド呼び出しやプ
ロパティ参照における「暗黙のレシーバ」を示す動的に変更可

4cl.call()}
これは以下のように with 句と同じように（少し違いますが）呼び出すことができ、"ABC" が表示されます。
myWith("abc") {println toUpperCase()}// ==> "ABC" が表示される

ここまでは、delegate プロパティの典型的な使用例の 1 つです。
さて、このコードで toUpperCase() の綴り間違いなども検出できるようにするために、以下のように静的型チェックを適用した
いとします。

Groovy 臨機応変（第一回）〜動中の静…Groovy 2.1.0 の新機能 その 1 〜

G*Magazine vol.6

import groovy.transform.*

org.codehaus.groovy.control.MultipleCompilationEr@TypeCheckedrorsException: startup failed:def d() {with.groovy: 6: [Static type checking] - Cannot
find matching method with#tooooooUpperCase().

myWith("abc") {println

Please check if the declared type is right and if

toUpperCase()

the method exists.

}@ line 6, column 13.

}

println tooooooUpperCase()@TypeChecked を適用するために、対象コードをメソッド定義^

で囲みます。しかし、上記は以下のようにエラーになってしまいます。

1 error

wyWithTest.groovy: 10: [Static type

これが可能なのは、Groovy の静的型チェッカが with メソッド

checking] - Cannot find matching method
myWithCheck#toUpperCase(). Please check if thedeclared type is right and if the method exists.
@ line 10, column 14.
printlntoUpperCase()の呼び出しを特別扱いし、delegate プロパティの値が with メソッ
ドの対象メソッドの型であると型推論して処理しているからです。

同種のことを、ユーザ定義メソッドや、サードパーティ提供の^ライブラリやフレームワークなどの API でもできるようにするこ

1 errorとが、@DelegatesTo の存在意義の 1 つです。myWith 定義を例に

静的型チェック配下のクロージャ中では delegate プロパティ

を参照できないし、もし参照できたとしても delegate プロパティ

すると、以下のようにクロージャ引数 cl に @DelegatesTo を指定します。

に String 型のインスタンスが保持されることがコンパイル時には

import groovy.transform.*

決することはできません。なので、delegate に対するメソッド

def myWith(Object self, @DelegatesTo(String)

決定できないので、toUpperCase() メソッド呼び出しを静的に解呼び出しやプロパティ参照を含むクロージャは、通常は静的型チェック・静的コンパイルができません。仮に、Closure cl) {cl.delegate = self
cl.call()def myWith(String self, Closure cl) {}cl.delegate = self
cl.call()@TypeChecked}def b() {myWith("abc") {のように myWith の引数 self を String 型に限定しても同じです。

println

myWith の処理内容「delegate プロパティに String インスタンス
を代入する」という処理内容を、myWith の呼び出し側は知らないからです。現在の Groovy が、メソッド呼び出しをまたがっての大域的な型推論を行わないから、とも言えます。

}}
このように「このメソッド呼び出しに即値の引数として与えちなみに、以下のように通常の with を使う場合、られたクロージャの delegate プロパティには String 型インスタ
ンスが割り当てられる」ということをコンパイラに伝えること

import groovy.transform.*

で、クロージャ中の delegate に対するメソッド呼び出しの静的@TypeChecked

型チェックや静的コンパイルを可能とします。なお、クロージャ

def d() {が即値ではなく例えば変数などに代入されたクロージャを渡すよ"abc".with {うなときには、@DelegatesTo は機能しません。このことは原理

println toUpperCase()

的に明らかでしょう。

}}
これはコンパイルも通り実行可能であり、tooooUpperCase()のように綴り間違いをしていた時には以下のように「そのようなメソッドは無い」という静的型エラーになります。

toUpperCase()■@DelegatesTo の使用例 2delegate プロパティは、ExpandoMetaClass(EMC) を用いてクラスに動的にメソッドを追加する際にも良く使われます。この際にメソッドとして追加するクロージャを静的コンパイル・静的型

Groovy 臨機応変（第一回）〜動中の静…Groovy 2.1.0 の新機能 その 1 〜5

G*Magazine vol.6
チェックするのにも @DelegatesTo を使用することができます。
以下は、String に hello() メソッドを動的に追加する例です。
import groovy.transform.*

型チェックを拡張し、カスタマイズする
Groovy 2.1.0 では、静的型チェックの振舞いを Groovy 利用者

がカスタマイズすることができるようになりました。
具体的には、
以下のように静的型チェックのための @TypeChecked アノテー

def addMethodToString(name,@DelegatesTo(String) Closure cl) {// 引数クロージャ cl の delegate プロパティには// String 型が与えられると宣言

ションに、型チェックを行うためのスクリプトを指定できるようになりました。

@TypeChecked(extensions='MyExtension.groovy')// 型チェックを行うスクリプト

String.metaClass."$name" = cl// 'MyExtension.groovy' を指定}

void exec()@CompileStatic{

def c() {addMethodToString("hello") {println toUpperCase()// toUpperCase() の暗黙のレシーバの型を解決でき、// 静的コンパイルも可能"test".toUpperCase()}
上 記 の MyExtension.groovy は、Type Checking DSL と 呼 ば れる特別な記法で記述された Groovy コードであり、コンパイルし}ておく必要はありません。留意点としては、この Type Chekingc()があるディレクトリから相対的な位置に置き、相対指定のファイ}

DSL スクリプトは @TypeChecked を指定したクラスやスクリプト
ル名で指定する必要があるようです ( 試した限りでは )。

"def".hello()

Type Checking DSL は以下のような記法です ( 参考 [2] より )。

EMC を用いるための metaClass プロパティ自体は静的型チェッ

onMethodSelection { expr, method -> ... }ク配下では使用できませんが、静的型チェックを適用しないメ

afterMethodCall { mc -> ... }ロージャを既存クラスにメソッドとして追加することができま

incompatibleAssignment { receiver, name, argList,

ソッドを介してクロージャを渡すことで静的コンパイルしたク

unresolvedVariable { var -> .. }す。とはいえ、このように動的に追加したメソッドは、静的コー

argTypes, call -> .. }ドからは呼び出せませんので、上記ができることの有用性にはちょっとした疑問が残るかもしれません。

■@DelegatesTo の利用目的@DelegatesTo が使われるシチュエーション、すなわち delegateに指定された固定クラスに対するメソッド呼び出しは、Spock や
Gradle などでも使われているそうです（参考 [3]）。なのでこれらのツールで将来的に @DelegatesTo が使用されるようになること

で、これらのツールの入力となる DSL について静的型チェックがより有効に活用され、論理的なエラーがより早い段階で検出でき、またより的確になるのかもしれません（ただし、静的型チェックに相当することを AST 変換で実装することは原理的に可能なので、同等のことをこれらのツールが既に行なっていないと仮定して、の話です）。また、@DelegatesTo は以下を目的として使えるとのことです（参考 [1]）。

• API のドキュメントとして• IDE での補完など

IDE の DSL の補完のための情報は、従来は IDE 独自の設定ファイル（Eclipse の DSL ディスクリプタや IDEA IntelliJ の GDSL）として提供されてきましたが、これらを一部置きかえ得るものでもあるようです。

6

これらは、Groovy 標準の静的型チェッカから呼び出されるイ

ベントハンドラの定義であり、静的型チェックの各状況下で呼び出されます。これらのハンドラからの返り値を指定することで、デフォルトの静的型チェッカであれば報告するはずであった静的型エラーを握り潰す (= 静的型エラーを静的型エラー扱いしない )こともできます。以下は指定できる静的型チェックイベントハン
ドラの一覧です。

• onMethodSelection• afterMethodCall• beforeMethodCall• unresolvedVariable• unresolvedProperty• unresolvedAttribute• methodNotFound• afterVisitMethod• beforeVisitMethod• afterVisitClass• beforeVisitClass• incompatibleAssignment• setup• finish

Groovy 臨機応変（第一回）〜動中の静…Groovy 2.1.0 の新機能 その 1 〜

G*Magazine vol.6

Type Checking DSL のイベントハンドラで書ける処理の詳細は

ここでは説明しませんが、AST 情報を駆使して自由にロジックを組むことができます。テストコードを見る限り、型チェック拡張

コンパイラ設定スクリプト
次にコンパイラ設定スクリプトについて説明します。コンパイ

ラ設定スクリプトは、groovyc コマンドなどのコマンドラインオ

によって、例えば以下のような機能が実現できそうです。

プションの一つとして「コンパイラ設定」を指定できるというも• 存在しないメソッド呼び出しの静的型チェック時に @Grab 指

control.CompilerConfiguration クラスのことであり、従来から明張モジュールが追加したメソッドによって、実行は成功する。

GroovyShell などを呼び出したりすることはできました。Groovy• メソッド呼び出しを大文字小文字を無視して比較するようにす

マンドラインからコンパイラ設定を指定することができるように定を追加し、拡張モジュールを実行時に導入させる。そして拡• sprintf でのフォーマット指定と、実引数の型チェックる• @DelegatesTo 相当の機能を実行する。つまり DelegatesTo で型チェックさせる。

のです。コンパイラ設定とは、具体的には org.codehaus.groovy.

示的にこのクラスを使うことで、任意のコンパイラ設定のもとで2.1.0 以降では、そのようなプログラムを書かなくとも手軽にコなります。

コンパイラ設定では、任意のクラスを import/static import した扱いにできたりなど様々な設定ができますが、特に「コンパイType Checking DSL の 詳 細 を 調 べ た い 場 合 は、 今 の と こ ろ

ル対象となるスクリプトやクラスに任意の AST 変換を適用する」

codehaus.groovy.transform.stc.GroovyTypeCheckingExtensionSu

イラ設定スクリプトで @CompileStatic や @TypeChecked などのGroovy の ソ ー ス コ ー ド に 含 ま れ る テ ス ト コ ー ド お よ び org.

という設定を行うことができるので有用です。例えば、コンパ

pport クラスのソースコードを読むのが最善です。

AST 変換を適用することで、コンパイル対象全部に対して静的コンパイルや静的チェックを行うことができます。あるいは、全ク

なお、「型チェック拡張がコード生成に介在できるか」が興味深いところです。もしもそれが可能なら、例えば、動的メソッ
ドの呼び出しやプロパティ参照の静的型エラー時に、その呼び出しコードを invokeMethod() や getProperty() の呼び出しに置き

ラスに @ToString を適用し、デフォルトの動作として toString()
メソッドを自動生成させる、といったこともできます。

コンパイラ設定は、コンパイラ設定スクリプト（以下では替えることにより、Groovy++ の mixed mode コンパイルに似たcompConfig.groovy）と呼ばれる Groovy スクリプトによる設定

で Groovy User のメーリングリストで聞いてみたところ、静的-configscript でそのファイル名を指定します。

ことができるなど、応用範囲が広くなるからです。ということ
Groovy 開発者の Cédric Champeau 氏から回答頂き、「型チェック
拡張は「型チェック」なので本来は AST の書き換えをするものじゃないけども、技術的には可能」とのことでした。また、コーディ

ング規約の統一のためのチェッカや CodeNarc のような静的解析など汎用的なチェックに使用することも狙っているとのことでした。

groovyc -configscript compConfig.groovy Test.groovy
コンパイラ設定スクリプトの記述例は以下のとおりです。
import groovy.transform.CompileStatic
import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer■型チェック拡張の意義

configuration.addCompilationCustomizers(

参考 [1] では、

著者の私見では、「静的型チェック」だけではメリットが十分ではないので、次節で紹介する、性能向上をメリットとする「静的コンパイル」を通じて利用することが主となるでしょう。

などと書いてしまいましたが、型チェック拡張によるカスタ

マイズができることを前提とすれば、「静的型チェックを行う

DSL の容易な実現」という目的においては、@CompileStatic による性能向上が無くとも、DSL に対してより的確なコンパイル時のエラーメッセージが出せたり、IDE サポートが得られるようになるなら、静的型チェックの有用性はとても高いと言えます。
しかしその場合でも、Groovy の一般利用者から見ると、直接 @TypeChecked や型チェック拡張を使用するのではなく、Gradleなどのツールやフレームワークがそれを使用し、間接的に利点が享受される、という形になるのかもしれません。

ファイルとして準備し、以下のようにコマンドラインオプション

new ASTTransformationCustomizer(CompileStatic))
なお、Groovy 2.1.0-rc-1 時点ではコンパイラ指定スクリプトで指定できるのは groovyc コマンドのみですが、2.1.0-final までに

groovy コマンドでも対応する予定とのことです（あくまで予定）。

コンパイラ設定ビルダ
さて最後に、コンパイラ設定ビルダについてですが、これは前節でのコンパイラ設定スクリプト（もしくは通常のプログラ

ム中でのコンパイラ設定）を、より簡潔に記述するための DSL記法です。Groovy 2.1.0 では、設定ファイルはなんでもかんでもDSL にする方針のようですね。前項での「全ファイルに対して @CompileStatic を適用する」というコンパイラ設定スクリプトは、
コンパイラ設定ビルダを用いて以下のように記述できます。

Groovy 臨機応変（第一回）〜動中の静…Groovy 2.1.0 の新機能 その 1 〜7

G*Magazine vol.6

import groovy.transform.*まとめ
今 回 紹 介 し た 機 能 群 に よ っ て、Groovy 2.0 で 登 場 し た 静 的

withConfig(configuration) {ast(CompileStatic)

Groovy 機能が、「Java のように書ける」といったある意味後ろ向きな目的だけではなく、「より有用な DSL を書く」ということにも寄与するようになってきました。DSL や動的な Groovy コード}
さらに、コンパイラ設定ビルダでは、例えば拡張子が「.sgroovy」

であるようなファイルのみを静的コンパイルする、といった指定も以下のように簡単にできます。
import groovy.transform.*
withConfig(configuration) {source(extension: 'sgroovy') {ast(CompileStatic)}

においても静的型チェックが ( 実装が容易に ) できることは有用でしょう。このような、「動的言語・動的型言語をあくまでもベースにした上での静的型の有用性の回収」は Groovy のユニークな特長であり、今後の Groovy の進化の方向性の一つでもあると思います。今後の Gradle や Grails などのツールの対応に期待です。

参考• [1] プログラミング GROOVY 別冊：第８章 Groovy 2.0 の新機能

http://beta.mybetabook.com/b/ksky/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E

3%82%B0GROOVY%E5%88%A5%E5%86%8A%EF%BC%9A%}
他にもファイル名のベース名や拡張子などで柔軟かつ一括の設定を行なうことができます。コンパイラ設定ビルダ記法の例については現時点で非常に情報が少ないのですが、

org.codehaus.groovy.control.customizers.builder.

SourceAwareCustomizerFactory クラスの冒頭コメントや

org.codehaus.groovy.control.customizers.builder.

CompilerCustomizationBuilder のソースコードがかろうじて参考になるでしょう。逆に言うとソースコード以外の情報は見付けられませんでした。

コンパイラ設定ビルダ及びコンパイラ設定スクリプトは、特E7%AC%AC%EF%BC%98%E7%AB%A0+Groovy+2.0%E3%81%AE%E6%96%B0%E6%A9%9F%E8%83%BD• [2]Groovy 2.0 and Beyond

http://www.slideshare.net/glaforge/groovy-2-and-beyond• [3] Groovy dev メーリングリストの「Detailed proposal for @DelegatesTo annotation」というスレッド

http://groovy.329449.n5.nabble.com/Detailed-proposal-forDelegatesTo-annotation-td5710777.html• [4] Groovy 2.1 release notesGroovy 2.1 release notes

http://groovy.codehaus.org/Groovy%202.1%20release%20
notesに 静 的 Groovy に 限 定 さ れ た 機 能 で は あ り ま せ ん が、 上 の @CompileStatic やもしくは @TypeChecked を全体に適用することが有用であるため今回紹介しました。

8

Groovy 臨機応変（第一回）〜動中の静…Groovy 2.1.0 の新機能 その 1 〜

G*Magazine vol.6

アプリケーションをGroovyでコントロールする

11

series奥 清隆（おく きよたか）
仕事でもがっつり Groovy と戯れるプログラマ。
日本 Grails/Groovy ユーザーグループ関西支部長。
著書：『Seasar2 による Web アプリケーションスーパーサンプル』

Groovy Remote Control
今回は個人的にお気に入りなライブラリの 1 つである、Groovy

Remote Control をご紹介します。

http://groovy.codehaus.org/modules/remote/

Groovy Remote Control はその名の通り、リモートの JVM 上で起動しているプログラムをコントロールすることができるライブ
ラリです。プログラミング GROOVY を読まれた方はお気づきだと思いますが、Groovy の使いどころ 7 つのパターンの 1 つである
内視鏡手術を導入するのに適したライブラリです。

■内視鏡手術内視鏡手術とは、アプリケーションを再起動することなく実行

中にアプリケーション内部の状態を確認したり変更することを言います。例としては、Jenkins の CLI やスクリプトコンソールなどがあります。Jenkins のスクリプトコンソールでは、Groovy のコードを実行中の Jenkins 内で実行することができ、Jenkins の状態を確認したり設定を変更したりすることができます。

いてみましょう。コードはサーバ側とクライアント側の 2 つに分かれます。クライアント側では Hello World を表示するクロージャを送り、サーバ側では受け取ったクロージャを実行します。
●server.groovy@Grab('org.codehaus.groovy.modules.remote:remotetransport-http:0.3')
import com.sun.net.httpserver.HttpServer
import groovyx.remote.transport.http.RemoteControlHttpHandler
import groovyx.remote.server.Receiver
def receiver = new Receiver()def handler = new RemoteControlHttpHandler(
receiver)def server = HttpServer.create(
new InetSocketAddress(8080), 0)
server.createContext("/groovy-remote-control",handler)server.start()●client.groovy@Grab('org.codehaus.groovy.modules.remote:remotetransport-http:0.3')
import groovyx.remote.client.RemoteControl
import groovyx.remote.transport.http.HttpTransport

このような内視鏡手術は、groovy.lang.GroovyShell を使って簡単に実装できます。

def script = … // 外部から受け取った Groovy スクリプト
def shell = new GroovyShell()shell.evaluate(script)
クラスローダやバインディング変数、また ImportCustomizerなどのコンパイラ設定などを設定することで、より特化した仕組みを提供することが出来ます。GroovyShell だけでも十分な内視鏡手術が可能になりますが、スクリプトは文字列でしか受け取れなかったり、HTTP で結果を返すときも文字列で返すことになります。Groovy Remote Control を使うと、サーバ側には Groovyのクロージャを渡すことができ、戻り値もオブジェクトのまま受け取ることができます。

■Hello World

それでは、Groovy Remote Control を使って Hello World を書

def transport = new HttpTransport("http://localhost:8080/groovy-remote-control")def remote = new RemoteControl(transport)
remote.exec {println "Hello World!"}
サーバを起動した後で、クライアント側のコードを実行するとサーバ側で「Hello World!」と表示されたと思います。もしくは
以下のようなエラーが出たかと思います。

Caught: java.lang.IllegalStateException: Could
not find class file for class class client$_run_
closure1
java.lang.IllegalStateException: Could not findclass file for class class client$_run_closure1
Groovy Remote Control はクライアントからクロージャを送るときに、クロージャをシリアライズしてサーバ側に送ります。

アプリケーションを Groovy でコントロールする

9

G*Magazine vol.6
サーバ側ではクロージャをデシリアライズするためにクロージャのクラスが必要になります。Groovy Remote Control はクラス
をサーバ側に送信するときにクロージャのクラスファイルを読み込んで、そのバイナリを一緒にサーバ側に送っています。このため、クライアント側のコードはコンパイルされてクラス
ファイルが生成されている必要があります。groovy コマンドやGroovyConsole を使ってクライアント側のコードを実行してしまうと、クラスファイルは生成されないので上記のようなエラーが発生してしまいます。

assert 16 == remote({ 1 + 1 }, { it * 2 }, { it * it })内視鏡手術として利用するためにはアプリケーションにサーバ側のコードを組み込む必要があります。Grails や Jenkins にはそれぞれプラグインがあり、簡単に Groovy Remote Control のサーバとしての機能を統合することが出来ます。

■Grails で利用する

Grails で Groovy Remote Control と連携するためには、Remote

Control プラグイン（http://grails.org/plugin/remote-control）を

コ ン パ イ ル し て か ら 実 行 す る の は 少 し 面 倒 な の で、利用します。Remote Control プラグインの主な目的は、Grails

GroovyConsole を用意しました。groovy コマンドで次のようにControl 経由でテストを実行するためのプラグインですが、普通

GroovyConsole か ら で も 実 行 で き る よ う に 手 を 加 え た

ア プ リ ケ ー シ ョ ン を 立 ち 上 げ て お き、 そ こ に 対 し て Remote

して起動します。

に Groovy Remote Control のサーバ側として利用することも可能

groovy https://raw.github.com/kiy0taka/groovyconsoles/master/GroovyRemoteConsole.groovy
見 た 目 は 通 常 の GroovyConsole で す が、Groovy Remoteです。

適当な Grails アプリケーションを用意して、Remote Control プ

ラグインをインストールしましょう。記事執筆時点での最新バー

ジョンは 1.3 です。BuildConfig.groovy に設定を追記しましょう。

Control のクライアントとして使用できるように拡張しています。

compile ":remote-control:1.3"

で起動に時間がかかります。この GroovyConsole には groovyx.

または、コマンドからインストールします。

変数に設定していますので、以下のコードだけで実行できるよう

grails install-plugin remote-control

初回起動時は Groovy Remote Control のライブラリを取得するのremote.client.RemoteControl のインスタンスをバインディングになります。

remote.exec {println "Hello World!"}
もう少し簡単に次のように書くことも出来ます。
remote {println "Hello World!"}
戻り値については、クライアント / サーバの両方にあるクラス

でシリアライズ可能なオブジェクトであれば返すことが出来ます。
assert remote.exec { 1 + 1 } == 2
クロージャの引数を渡すことは出来ませんが、戻り値と同じよ

うにシリアライズ可能なオブジェクトであれば、リモートに渡す
クロージャの中で使用することが出来ます。

def name = 'JGGUG'
remote.exec {def message = 'Hello ' + name + '!'println message}
複数のクロージャをまとめて渡すことで、チェーンして実行することが出来ます。この場合、前のクロージャの結果が次のクロー
ジャの引数となります。

10 アプリケーションを Groovy でコントロールする

デフォルトではテスト環境でのみ Groovy Remote Control が有

効になりますが、今回は普通に run-app したアプリケーションをコントロールするために、設定を変更します。Config.groovy に以下の設定を追記します。

remoteControl.enabled = true

Remote Controlプラグインを入れて上記の設定をした場合、本番環境も外部からコントロールできてしま

うため危険です。必要に応じて環境ごとに設定をしましょう。

それでは run-app コマンドで Grails アプリケーションを起動し、ブラウザで以下の URL にアクセスしてみましょう。

http://localhost:8080/ アプリケーション名 /grailsremote-control
405 エラーが表示されると成功です。Groovy Remote Control

は GET メソッドはサポートしません。

そ れ で は 先 ほ ど の GroovyConsole か ら ア ク セ ス し て み ま

し ょ う。GroovyConsole の メ ニ ュ ー か ら「Remote Control」→「Configuration」 を 選 択 し、 先 ほ ど ブ ラ ウ ザ で ア ク セ ス した URL を 設 定 し ま す。Remote Control プ ラ グ イ ン を 使 う と リ

モートで実行されるクロージャの中で Spring のコンテキストやGrailsApplication のインスタンスを利用することが出来ます。

例えば、リモートから Grails のサービスを利用して処理を実行したい場合は、変数 ctx を使用して以下のように実行します。

G*Magazine vol.6

remote {// Spring コンテキストからサービスを取得
def service = ctx.myService// サービスのメソッドを実行
service.serviceMthod()}
リモートから Grails の設定を動的に変更したい場合は、変数app を使用して以下のように実行します。
remote {// Config を取得
def config = app.config// 設定を変更
config.myconfig = 'foo'}

ドメインを使う場合、クライアント側でドメインクラスをクラスパスに通しておけばそのまま使うことができますが、少し手間なので Spring コンテキストからドメインのインスタンスを取得して利用できます。例えば Book というドメインクラスがあり、新しい Book を登録するには次のように実行します。
remote {// 新しい Book インスタンスを取得
def book = ctx.getBean('myapp.Book')
book.name = 'G*Magazine Vol.6'// 保存する
book.save()}
このように、実行中の Grails アプリケーションに対して Groovy

Remote Control を利用して、設定の変更やデータの登録をすることができます。

■Jenkins で利用する

Groovy Remote Control は Jenkins で も 利 用 す る こ と が で

き ま す。Jenkins で 利 用 す る 場 合 は Jenkins の Groovy Remote

Control プ ラ グ イ ン（https://wiki.jenkins-ci.org/display/JENKINS/

Groovy+Remote+Control+Plugin） を イ ン ス ト ー ル し ま す。
Jenkins の Remote Control につなぐ場合は、以下の URL にアクセスします。

このように Remote Control プラグインを入れることで Jenkins

をリモートから操作することができるようになります。CLI やス

クリプトコンソールとの違いは、クライアント側で処理した結果をそのまま Jenkins に渡してビルドをしたり、Jenkins 側から返ってきた結果を使ってクライアント側で処理をすることがよりシームレスにできるようになることです。

Remote Control プラグインには他にも Jenkins から他のアプリ

ケーションを Remote Control 経由で操作する機能もあります。
これによって、アプリケーションから Jenkins のコントロールと、Jenkins からアプリケーションをコントロールするという双方向のコントロールが可能になります。Jenkins から外部アプリ
ケーションをコントロールする方法についてはプラグインの Wiki
ページを参照してください。

■Grails 以外のアプリケーションで利用する

Grails にはプラグインがあるため簡単に利用できますが、Grails

以外のアプリケーションでも Groovy Remote Control を利用するための仕組みが用意されています。最初のサーバ側のサンプ

ル で 利 用 し た RemoteControlHttpHandler は JDK に バ ン ド ル されている簡易 HTTP サーバ用のハンドラの実装です。他にサーブレットとして機能する仕組みもあります。Web アプリケー

シ ョ ン に Remote Control を 組 み 込 む た め に は groovyx.remote.

transport.http.RemoteControlServlet ク ラ ス を 使 用 し ま す。
Groovy Remote Control のライブラリを war に含めて web.xml にRemoteControlServlet の設定を追記するだけで使えます。

Grails や Jenkins の プ ラ グ イ ン の よ う に、 独 自 の バ イ ン デ ィ

ン グ 変 数 を 設 定 す る 場 合 は、RemoteControlServlet を 継 承 しcreateReceiver()メソッドをオーバーライドし、コンテキストを設定した groovyx.remote.server.Receiver 型のインスタンスを返します。
protected Receiver createReceiver() {def ctx = [date:new Date(),props:System.properties]
new Receiver(ctx)}

Receiver クラスでは他にクラスローダを変更することも可能です。サーバ側の処理のほとんどはこの Receiver が行っているため、フレームワーク固有のコントローラと統合することも可能です。

http://Jenkins の URL/plugin/groovy-remote/■まとめ

ローカルでデフォルトのまま Jenkins を起動している場合はとても強力な仕組みとなります。Groovy Remote Control を使う

リモートクロージャ内では jenkins という変数で Jenkins インスとができます。ぜひ、Groovy Remote Control を使って内視鏡手「http://localhost:8080/plugin/groovy-remote/」になります。
タンスを利用できます。

内視鏡手術は使い方を間違えるととても危険ですが、その反面ことでより強力な内視鏡を簡単にアプリケーションに組み込むこ術を行ってみてください。そして、内視鏡以外の使い方があればブログなどで紹介してもらえればと思います。

remote {// Jenkins のバージョンを表示
def version = jenkins.version.value
pritnln version}

アプリケーションを Groovy でコントロールする

11

G*Magazine vol.6

オレオレ・プログラミング GROOVY
12

series

綿引 琢磨（わたびき たくま）
Groovy/Grails/Griffon/Java 界隈のやさぐれエンジニア。
日本 Grails/Groovy ユーザーグループ運営委員。

G* な皆さん、こんにちは。Groovy を学ぶ際に最初に読むべきGroovy の テ ン プ レ ー ト エ ン ジ ン は groovy.text パ ッ ケ ー ジ

書籍といえば「プログラミング GROOVY」ですよね？しかし、書（groovy-templates-x.x.x.jar）に格納されています。僅か５ファイん。そこで、このコラムでは「プログラミング GROOVY」を読んで、※ Groovy 2.0 からのモジュール化により、物理的には別モ

籍で紹介されているのは、Groovy の魅力のごく一部に過ぎませこれから Groovy を活用していこうと考えている人向けに、即戦

ルだけの小さなパッケージですので、それぞれについて解説します。
ジュールになっています。

力となるであろう API を紹介したいと思います。

■Template

Groovy のテンプレートエンジン

つの make() メソッドが定義されています。このインタフェース

テンプレートのインタフェースで、オーバーロードによる２Java では、Apache の Velocity Engine が代表的なテンプレー※

トエンジンとして知られていますが、Groovy では言語本体 でテンプレートエンジンの API を提供しています。テンプレートエン
ジンとは、ひな形となる定型のテンプレートにデータをバインド
して、文字列を出力したり、ファイルの生成を行うための機能です。身近な例を挙げると、Grails の generate 系コマンドで生成されるコントローラやビューなどは、Groovy のテンプレートエ
ンジンを利用して生成しています。

groovy.text パッケージ概略図

12 オレオレ・プログラミング GROOVYの実装クラスの中でバインドしたものを出力するための Writable
なクラスを生成します。

■TemplateEngine

テンプレートエンジンの抽象クラスで、オーバーロードによ る ４ つ の createTemplate() メ ソ ッ ド が 定 義 さ れ て い ま す。
最 終 的 に は 抽 象 メ ソ ッ ド と な っ て い る Reader を 引 数 と す る

createTemplate() が呼ばれ、具象クラスのテンプレートエンジンが生成されます。

G*Magazine vol.6■SimpleTemplateEngine

SimpleTemplateEngine では、デバッグ確認用の verbose フラ

３つのテンプレートエンジンの中で最も汎用的に使えるテンプ

グがあり、コンストラクタまたは setVerbose() で値を true にす式（${}）のプレースホルダを記述できます。例えば、テンプレーことができます。前述のテンプレートの場合は以下のような出力

レートエンジンです。JSP 形式（<% %>, <%= %>）と GString 形

ることで、実行時にテンプレートを解析した結果を標準出力する

トファイルを読み込んでクラスファイルを生成するコードは以下になります。

のようになります。
●テンプレート

package $packageName
class $className {<% fields.each { type, fieldName -> %>private $type $fieldName<% } %>}-- script source -out.print("""package $packageName
class $className {"""); fields.each { type, fieldName -> ;out.print("""private $type $fieldName"""); } ;out.print("""}● サンプルコード
import groovy.text.SimpleTemplateEngine""");/* Generated by SimpleTemplateEngine */-- script end --def path= '/Users/bikisuke/sandbox/templateEngine'def className = 'SampleBean'def binding = [packageName:'org.jggug.bean',className:className,
fields:['String':'name', 'int':'value']]def file = new File("${path}/simple.template")
def engine = new SimpleTemplateEngine()
def template = engine.createTemplate(file).make(binding)
new File("${path}/${className}.groovy").write(template.toString())●実行結果
package org.jggug.bean
class SampleBean {private String nameprivate int value}

オレオレ・プログラミング GROOVY

13

G*Magazine vol.6■GStringTemplateEngine
GStringTemplateEngine

は SimpleTemplateEngineと■XmlTemplateEngine

３つ目は名前の通り XML を出力するためのテンプレートエ

同 等 の 機 能 を 持 ち な が ら、 ク ロ ー ジ ャ を 用 い る こ と で、ンジンです。テンプレートの解析に XmlParser を使用し、テンンとなっています。クロージャ内では出力を out という変数に委<gsp:scriptlet> と <gsp:expression> の２つのタグを使ってデー

SimpleTemplateEngine よりも拡張性のあるテンプレートエンジ
譲するため、スクリプトレットで out 変数を使いながらロジックを記述することができます。一つのスクリプトレット内で値の判定をさせて out に出力すると、SimpleTemplateEngine よりも柔軟で読みやすいテンプレートを作成することができます。

プレート自体も XML 書式で記述します。このテンプレートでは
タとのバインドを行います。
●テンプレート<?xml version="1.0" encoding="UTF-8"?>●テンプレート$familyName $firstName 様、おめでとうございます。

<WizardRings xmlns:gsp='http://groovy.codehaus.
org/2005/gsp'><gsp:scriptlet>rings.each {</gsp:scriptlet><TransformationRing style="${it.style}">厳正な抽選の結果、<%= familyName %> 様に<% out << (hasLoan? ' ７億 ' : ' ３億 ') %> 円プレゼントが当選しました。

<stone element="${it.stone.element}" ><gsp:expression>it.stone.base</
gsp:expression></stone>

ご連絡いただければ、すぐにお振込いたしますので、
下記 URL へのアクセスお願いいたします。
http://akutoku.com●サンプルコードimport groovy.text.GStringTemplateEngine
def path<chants><gsp:expression>it.chants</
gsp:expression></chants></TransformationRing><gsp:scriptlet>}</gsp:scriptlet></WizardRings>●サンプルコードimport groovy.text.XmlTemplateEngine= '/Users/bikisuke/sandbox/templateEngine'def binding = [familyName:' 御金 ',def path= '/Users/bikisuke/sandbox/templateEngine'

firstName:' 内造 ',def rings = []hasLoan:truerings << [style:'Flame', stone:[element:'Fire',]

base:'Ruby'], chants:'Hi']

def file = new File("${path}/gstring.template")rings << [style:'Water', stone:[element:'Water',def engine = new GStringTemplateEngine()

base:'Sapphire'], chants:'Sui']

def template = engine.createTemplate(file)rings << [style:'Hurricane',.make(binding)println template.toString()● 実行結果
御金 内造 様、おめでとうございます。

stone:[element:'Wind', base:'Emerald'],
chants:'Fu']rings << [style:'Land', stone:[element:'Earth',
base:'Yellow-Topaz'], chants:'Do and Don']def file = new File("${path}/xml.template")
def engine = new XmlTemplateEngine()

厳正な抽選の結果、御金様に７億円プレゼントが当選しました。

def template = engine.createTemplate(file).make([rings:rings])
println template.toString()

ご連絡いただければ、すぐにお振込いたしますので、
下記 URL へのアクセスお願いいたします。
http://akutoku.com

14 オレオレ・プログラミング GROOVYG*Magazine vol.6● 実行結果<WizardRings><TransformationRing style='Flame'><stone element='Fire'>Ruby</stone><chants>
Hi</chants></TransformationRing><TransformationRing style='Water'><stone element='Water'>
Sapphire</stone>テンプレートエンジンの使いどころ
SimpleTemplateEngine は、オールラウンドで使用することができるので、ソースコード生成のような自動生成ツールを作成する際には非常に役に立つクラスです。筆者はこれまで生成ツールをいくつか作成してきましたが、使い勝手の良さから
SimpleTemplateEngine を使うケースが多いです。

GStringTemplateEngine は、データの値に応じて出力時の内容を変更させたいような場合に有効です。ただし、テンプレートでのロジックが実装しやすい反面、肥大したテンプレートになってしまう可能性もあるため、簡単なデータ変換や出力元の切替など効果的に利用すると良いと思います。

XmlTemplateEngine は使いどころは限られますが、XML に特化したテンプレートエンジンですので、XML を出力する際には検討する価値はあると思います。

<chants>Sui</chants></TransformationRing><TransformationRing style='Hurricane'><stone element='Wind'>
Emerald</stone><chants>

まとめ
簡単ではありますが、Groovy のテンプレートエンジンをおさらいしてみました。2.x 系になって、魅力的な新機能が増えていますが、まだまだ Groovy にはたくさんの実用的な機能があります。皆さんも API を眺めてみて、オレオレ GROOVY を探求してはいかがでしょうか。

Fu</chants></TransformationRing><TransformationRing style='Land'><stone element='Earth'>
Yellow-Topaz</stone><chants>
Do and Don</chants></TransformationRing></WizardRings>

オレオレ・プログラミング GROOVY

15

G*Magazine vol.6『 Yokohama.groovy』について〜活動報告など〜

しんや（@shinyaa31）

はじめまして。しんや（@shinyaa31）と申します。横浜在住、

都内勤務のエンジニアです。

2 年程前から社外の勉強会に参加するようになりました。そして今年（2012 年）の夏に『Yokohama.groovy』というコミュニティを作り読書会・写経会という形で勉強会を実施、継続しています。
今回はその『Yokohama.groovy』について、発足の経緯や実施内容等についてご紹介してみたいと思います。

Yokohama.groovy 発足のきっかけ
これまでに、私自身 #jggug が主催するイベント（主に G* ワー

クショップですが）には数回足を運んでいました。そこでの内容は毎回とても参考になる事が多く得るものも多かったのですが、基本的には『聴講』スタイル。Groovy 界隈に限った事では無かったのですが、手を動かして何かしらのアウトプットを出し、より理解を深める機会が欲しいなと思うようになりました。
2012 年に入り、『アジャイルサムライ読書会

横浜道場』（以下、“ 横浜道場 ”）等で横浜界隈での勉強会参加者と交流する機会も多くなり、そこでのやり取りを経て、『横浜をベースに何か勉強（会）をやろう！』という流れに。イベントの名前はシンプルに『Yokohama.groovy』。対象となったメンバー間での興味関心が Groovy に多かった事で比較的すんなり決まりました。

会の概要等
会の名前が示す通り、開催場所は横浜近辺としています。これは構成が横浜道場メンバーである事が多分に影響しています。

開催ペースは現在のところ隔週開催。今後については不明です

が、メンバー間で都合の良い曜日を決め、調整が付けやすいように曜日を固定して続けています。幸いここまで、日程微調整が少しあったものの、割と安定したペースで続けられています。

開催時間帯については 20:00 〜 22:00 という遅目の時間帯にし本棚にはプログラマの必読書？「ジョジョ」全巻が！

2011 年末に横浜駅西口方面にオープンしたコワーキングス

ペースで、寛ぎやすい空間の中、横浜道場譲り（？）のゆる〜い
雰囲気で会を進行しております。

会の進行に関しては、冒頭にも書いたように『読むだけではな

く手や頭を動かして理解を深める』事を主目的としています。なので読書会＆写経会、というスタイルが近いでしょうか。当回に読む範囲を定めておき、当日は気になる所をかいつまみながら時には深掘り、時には横道に逸れつつ…と言った感じで “ 持続可能なペースで ” 続けてきました。

対象図書第 1 弾は『プログラミング Groovy』
対象図書については、G* ワークショップ等でも常々テーマや話題にも挙がり、教材とするには絶好の書籍だろう、という訳でこちらも迷いなく対象書籍を『プログラミング Groovy』とする事に。第 3 章〜第 5 章の深掘り可能なテーマがメインとなりました。

ました。これは前述の横浜道場にも言える事なのですが、横浜・神奈川在住者が都内に勤務する場合どうしても横浜方面に帰宅するのは若干遅目の時間帯になってしまう事から開始時間を遅らせて（その分終了・懇親会の時間もシフトし）より参加し易くしています。どの勉強会に於いても 19:00、19:30 開催等が多く、定時との兼ね合いだと『行きたいけど時間の都合で…』というケースも割と多く聞きますので “ 時間帯を遅らせて開催する ” というのは横浜・神奈川に限らず、都内開催に於いても参加者増に効果があるのではないでしょうか。

開催場所は現在まで、ほぼ大半を『タネマキ』で執り行っています。

タネマキ【コワーキング ＆ シェアオフィススペース】
http://tane-maki.net/

16 『Yokohama.groovy』について 〜活動報告など〜

2012 年度中のテーマは『プログラミング Groovy』

G*Magazine vol.6

これまでの活動記録

もっと G* 関連イベントを！

第 1 回からのイベント参加記録を以下に並べてみます。どのような内容で開催されて来たか、雰囲気だけでも掴んで頂ければ幸いです（※個人ブログで申し訳ありません…）。
第 1 回 2012/08/07

http://d.hatena.ne.jp/absj31/20120807/1344484292

私の観測範囲（ここ 1 〜 2 年、主に関東）内だと、Groovy, G*

関連の実践系勉強会と言えば以下のようなイメージでした（※この他にも開催してるぞ！と思われた方居ましたら申し訳ありません ...m(_ _)m）。

第 2 回 2012/08/20• G* ワークショップ

第 3 回 2012/09/04• JGGUG 主催の合宿系イベント

http://d.hatena.ne.jp/absj31/20120820/1345539843
http://d.hatena.ne.jp/absj31/20120904/1346856008
第 4 回 2012/09/18

http://d.hatena.ne.jp/absj31/20120918/1348888991
第 5 回 2012/10/02

http://d.hatena.ne.jp/absj31/20121002/1349193477
第 6 回 2012/10/16

http://d.hatena.ne.jp/absj31/20121016/1350402234• TDDBC 等でのテスト系イベントの対象言語の 1 つとして• @kyon_mm 氏による Groovy 関連イベント• その他、単発でちらほらと ...

そんな感じでしたので、最近になって『Groovy/G* 関連の実践系勉強会少ないな〜、もう少しあっても良いのに / あると嬉しいのに ...』という思いは確かにありました。

今回この原稿を書くにあたり綿引さん（@bikisuke）にその辺

第 7 回 2012/10/30

りのお話を伺ったところ、『以前は G* ワークショップや関連イベ

第 8 回 2012/11/13

上げておりませんでした ...）。

http://d.hatena.ne.jp/absj31/20121030/1351611802
http://d.hatena.ne.jp/absj31/20121113/1352871838

ントでも、実践系のものをやってたりしていた』そうです（存じ

書籍『プログラミング Groovy』で紹介されている『Groovy エ

第 9 回 2012/11/27

コシステム』の諸技術、またはそれ以外にも Groovy/G* 界隈には第 10 回 2012/12/18

や各種課題等もある事かと思いますが、“ 文字通り ” ワークショッ

http://d.hatena.ne.jp/y_sumida/20121127/1354423092
http://d.hatena.ne.jp/y_sumida/20121218/1356238928

魅力的且つ実用的な技術が数多く存在していると思います。状況
プやハンズオンの機会が増え、Groovy/G* の技術がより多くの人に使われるようになるとまた面白い展開も出来てくるのではないでしょうか。

Yokohama.groovy の今後について2012 年 12 月一杯で『プログラミング Groovy』の読書・写経会についてはひとまず終了。

開催のハードルは極力低く
昨今本当に数が多くなった勉強会の開催数ですが、勉強会を開催する上でも幾つかのハードルがあると思います。開催地の問題、時間の問題、長期化・シリーズ化するような規模の場合は如何に
勉強会自体を継続させて行くかの問題等など…。

Yokohama.groovy では参加メンバーが皆勉強会参加の “ 常連 ”でもあったため、その辺の事情を把握していたのでこの点については『なるべく開催のコストを掛けない方向で』と一致していました。また人数についても小回りの効く規模に留めています（3〜 6 名）。これは主に利用している会場（横浜タネマキ）の都合もありますが、いざという時の予定調整も行いやすいです。場所についても、コワーキングスペースを利用する事で開催場所決定の手間を削減しています。現在の人数規模感であれば、いざとなったら喫茶店等でも開催可能ですし。書籍に関する予習等は行うものの、基本それ以外の手間等は極力掛けないような体制で行こうという部分を崩さないで居るのも、ここまで定期的に続けられて2013 年からは活動曜日を平日から土日に移し、午後イチ～夕方の長めの時間を取って、Groovy 及び G* プロダクトに関する『もくもく作業』メインの中身となりました。時間も内容もより余裕を持たせる事によって、より充実した方向へとシフトして行こうと思っています。
Twitter ハッシュタグ： #yokohamagroovy で適宜情報は発信していく予定ですので、興味のある方はチェックしてみてください。
また、実施しているイ

ベントについて参加してみたいという方がおりましたら、告知サイト等の告知があればそちらを是非ご参照ください。また

そうでない場合も参加メンバーに気軽に声を掛けてみてください。

いる要因なのかなと思います。

活動拠点『タネマキ』の手書き看板。

『Yokohama.groovy』について〜活動報告など〜

17

G*Magazine vol.6

Grails Plugin 探訪
第7回~ Remote Methods プラグイン ~URL: http://grails.org/plugin/grails-remote-methods
プラグインのバージョン : 0.2

対応する Grails のバージョン : 2.0 以上

杉浦孝博
最近は Grails を使用したシステムの保守をしている自称プログラマ。
日本 Grails/Groovy ユーザーグループ事務局長。

共著『Grails 徹底入門』、共訳『Groovy イン・アクション』

はじめに

サンプルのドメインクラスとコントローラ

今回ご紹介する Grails プラグインは、Remote Methods プラグインです。

本記事は、次の環境で動作確認をしております。

今回のサンプルとして、本をあらわす Book ドメインクラスと、

そのコントローラである BookController を使用します。

• OS : Mac OS X 10.8.2

package appgp07• Grails : 2.2.0

class Book {• Java : 1.7.0_10

String title

なお、コマンドの実行結果については、紙面の都合上、出力結

int price

果を省略しており、実際の出力と異なる場合があります。ご了承

String isbn13

願います。

static constraints = {Remote Methods プラグインとはtitle blank: false
price min: 0

Remote Methods プラグインは、コードを書かずに JavaScript

isbn13 blank: false, maxSize: 13

からコントローラのメソッドを呼び出すコードを生成するためのプラグインです。

プラグインのインストール
Remote Methods プ ラ グ イ ン の イ ン ス ト ー ル は、grailsの install-plugin コ マ ン ド で イ ン ス ト ー ル す る か、 あ る い はBuildConfig.groovy に記述することで行います。

install-plugin コマンドでインストールする場合、次のように行}}

package appgp07
class BookController {// ( 省略 )います。

def getTitle() {// ( 省略 )}$ grails create-app appgp07$ cd appgp07

def getPrice() {// ( 省略 )}$ grails install-plugin grails-remote-methods
BuildConfig.groovy に記述する場合、次のように記述します。
plugins {def getIsbn13() {// ( 省略 )}....
compile ":grails-remote-methods:0.2"
}

}

18

Grails Plugin 探訪

第 7 回 ~ Remote Methods プラグイン ~G*Magazine vol.6

メソッドの定義と GSP の記述
メソッドの定義と、それを呼び出すタグを GSP に記述します。
タグの記述方法には大きく二通りの記述方法があります。呼び出すメソッドを明示する方法と、呼び出すメソッドを明示しない<script src="/appgp07/static/js/application.js"
type="text/javascript" ></script><script type="text/javascript">
var book = {getTitle: function (params, success, error) {方法です。

jQuery.ajax({
type: 'POST',■呼び出すメソッドを明示する

data: params,

メソッドのリモート呼び出しのタグ名は「rm:defineRemote」

url: '/appgp07/book/getTitle',となります。呼び出すコントローラは controller 属性で、メソッ

success: function(data, textStatus) {ド名は methods 属性で指定します。methods 属性はリストで、

success(data, textStatus);

複数指定することができます。

},
error: function(XMLHttpRequest, textStatus,<rm:defineRemote controller="book"errorThrown) {methods="['getTitle', 'getPrice', 'getIsbn13']"/>

if (error) {error(XMLHttpRequest,■呼び出すメソッドを明示しない

textStatus, errorThrown)} else {呼び出すコントローラは controller 属性で指定します。

window.errorHandler(XMLHttpRequest,<rm:defineRemote controller="book"/>

textStatus, errorThrown)};

メソッド呼び出しの対象となるメソッドを、コントローラの}

remoteMethods プロパティで指定します。

});},

class BookController {static remoteMethods= ['getTitle', 'getPrice', 'getIsbn13']
なお、GSP で methods 属性を指定し、かつ remoteMethods プ

ロパティも指定した場合は、methods 属性の指定内容が優先されます。

JavaScript コードの生成
rm:defineRemote タグによって、以下のコードが生成されます。
例えば、次の GSP の記述から<rm:defineRemote controller="book"methods="['getTitle']"/>
実行時に次の JavaScript コードが生成されます（紙面の都合上、_: 0}</script>生成されるコードは、jQuery を使用した Ajax のコードとなります。

呼び出すコードの作成
最後に、生成された JavaScript コードを呼び出すコードを GSPに記述します。

<script type="text/javascript">// 省略
function getTitle(params) {book.getTitle(params, function() {},コードは整形しています）。

function() {})}// 省略</script>

Grails Plugin 探訪

第 7 回 ~ Remote Methods プラグイン ~19

G*Magazine vol.6

コードリーディング
プラグインの機能の説明は以上となります。プラグインがしていることは、簡単に言ってしまえば、タグリブ ( のクラス ) を提供することになります。

タグリブのコード自体短いものなので、次に前ソースを載せます。ここからは、簡単ではありますが、タグリブの仕組みを説明したいと思います。

package remote.methodclass UtilsTagLib {// [1]

def static namespace = 'rm'// [2]

def grailsApplication
def defineRemote = { attrs ->// [3]
javascript(null, {// [6]
def controller = getController(attrs.controller)
def methods = getMethods(controller, attrs.methods)
out << "var ${controller.controllerName} = {"// [4]
methods.each {out << "${it}:function (params, success, error) {"out << remoteFunction(// [6]
controller: controller.controllerName,action: it,params: "params",
onSuccess: "success(data, textStatus)",onFailure: """if (error) {error(XMLHttpRequest,textStatus,errorThrown)} else {window.errorHandler(XMLHttpRequest,textStatus,errorThrown)}""")out << "},"}
out << "_:0}"

}

})

null

private getController(name) {// [5]
return grailsApplication.mainContext.getBean(
grailsApplication.getArtefactByLogicalPropertyName("Controller", name ?: controllerName).clazz.name)}private getMethods(controller, methods) {// [5]
if (controller.hasProperty('remoteMethods') == null &&methods == null) {throw new IllegalArgumentException("In tag 'defineRemote' you should specify methods attribute " +"in tag or define list methods in controller")}}}

methods ?: controller.remoteMethods

20 Grails Plugin 探訪 第 7 回 ~ Remote Methods プラグイン ~G*Magazine vol.6■ファイルの置く場所とクラス名

タグリブのファイルを置く場所は、grails-app/taglib ディレク

トリ配下になります。

タグリブのクラス名は「〜 TagLib」で終わるように、ファイ

ル名は「〜 TagLib.groovy」で終わるように命名します ( コード［1］)。

■タグの名前空間とタグの定義

タグの名前空間の接頭辞は、namespace プロパティで指定します ( コード［2］)。

タグの定義は、タグリブのクラスにクロージャで定義します( コード［3］)。クロージャとバインドされた変数名が、タグの名前となります。

タグ定義のクロージャはパラメータを 1 つ受け取り、タグに記述された属性のマップとなります ( コード［3］)。

■out 変数

タグ定義のクロージャで処理した内容は、out 変数に出力することで、GSP の処理結果の一部としてクライアントに返すことができます ( コード［4］)。

■メソッドの定義

タグリブとはいえ、通常のクラスと変わりありませんので、メ

ソッドの定義をすることができます ( コード［5］)。

■他のタグリブの呼び出し

javascript や remoteFunction と い っ た タ グ リ ブ を、 通 常 の メ

ソッド呼び出しと同じ使い方で利用することができます ( コード［6］)。この場合、呼び先のタグリブで out 変数に出力をしていれば、それらの内容も out 変数に出力順に出力されます。

終わりに
今回はタグの記述のみで、Ajax での単純なメソッド呼び出しができるようになるプラグインをご紹介しました。凝った呼び出し方をする場合には物足りないかもしれませんが、お手軽にメソッ
ド呼び出しの記述ができるのは魅力的ではないかと思います。

あと、今回は機能や実装がシンプルだったこともありましたので、コードリーディングをしてみましたがいかがだったでしょうか。今後も、機会があればやってみたいと思います。

▼ぐるーびーたん

第 5 話までのあらすじ

プログラマを目指して熊本から上京したぐるーびー

たん。今度は JGGUG 温泉合宿に参加 !?

※この作品は、たいがいフィクションです。
実在の人物、
団体とは関係ありません。

Grails Plugin 探訪

第 7 回 ~ Remote Methods プラグイン ~ ／ぐるーびーたん

第6話

21

G*Magazine vol.6

リリース情報 2013.02.19
GrailsGrails は、Groovy や Hibernate などをベースとしたフルスタックの Web アプリケーションフレームワークです。
URL: http://grails.org/
バージョン : 1.3.9, 2.1.3, 2.2.0■更新情報• 2.1.3 では、grails ラッパーが使えない問題や findAll クエリが失敗する問題などのバグ対応が行われています。
• 2.1.3 リリースノート : http://grails.org/2.1.3+Release+Notes• 山本さんのブログ :http://d.hatena.ne.jp/mottsnite/20121219/1355931008• 2.2.0 では、Groovy 2.0 対応や、ネームスペース対応、フォー
クモードの他、各種バグ対応が行われています。
• 2.2.0 リリースノート : http://grails.org/2.2.0+Release+Notes• 山本さんのブログ :http://d.hatena.ne.jp/mottsnite/20121220/1356016199

GroovyGroovy は、JavaVM 上で動作する動的言語です。
URL: http://groovy.codehaus.org/
バージョン : 1.8.9, 2.0.7, 2.1.1■更新情報• 1.8.9 では、GString に getBytes() メソッドが追加されたり、@Immutable が Cloneable フィールドと一緒に使えるようになったり、多くのバグ対応が行われています。
• 1.8.9 リリースノート : http://jira.codehaus.org/secure/
ReleaseNote.jspa?projectId=10242&version=18778• 2.0.7 では、File クラスに createTempDir() メソッドが追加されたり、ソースファイルのクラスパスを検索するかどうかを制御するために groovyc ant タスク用フラグが提供されたり、多くのバグ対応が行われています。
• 2.0.7 リリースノート : http://jira.codehaus.org/secure/
ReleaseNote.jspa?projectId=10242&version=19028• 2.1.1 では、@Delegate を @DelegatesTo と一緒に動作できるようになったり、バイトコード周りが幾つか改良されたり、多くのバグ対応が行われています。
• 2.1.1 リリースノート : http://jira.codehaus.org/secure/
ReleaseNote.jspa?projectId=10242&version=18990

Griffon
Griffon は、デスクトップアプリケーションを開発するためのア
プリケーションフレームワークです。
URL: http://griffon.codehaus.org/
バージョン : 1.2.0■更新情報• 1.2.0 では、リリースパッケージをアップロードするコマンドが追加されたり、カスタマイズしたログ用のファクトリサービスが追加されたり、いくつかのバグ対応が行われています。
• 1.2.0 リリースノート : http://docs.codehaus.org/display/
GRIFFON/Griffon+1.2.0#Griffon120-120

Gant
Gant は、XML の代わりに Groovy で Ant タスクを記述し実行する
ビルド管理ツールです。
URL: http://gant.codehaus.org/
バージョン : 1.9.9■更新情報• 1.9.9 では、-D オプションに = が含まれる場合にパースが正しくない問題が対応されています。
• 1.9.9 リリースノート : http://jira.codehaus.org/secure/22 リリース情報

ReleaseNote.jspa?projectId=11660&version=19046

GradleGradle は、Groovy でビルドスクリプトを記述し実行するビルド管理ツールです。
URL: http://www.gradle.org/
バージョン : 1.4■更新情報• 1.4 では、依存解決が改良されたり、GroovyCompile/
Groovydoc タスクを使って Groovy の依存性を自動構成したり、いくつかバグ対応が行われています。
• 1.4 リリースノート : http://www.gradle.org/docs/1.4/releasenotes

GaelykGaelyk は、Groovy で記述する Google App Engine for Java 用のライトウェイトなフレームワークです。
URL: http://gaelyk.appspot.com/
バージョン : 1.2

Google App Engine SDK for Java
Google App Engine SDK for Java は、Java で Google App Engine
用の Web アプリケーションを開発するための SDK です。
URL: http://code.google.com/intl/ja/appengine/バージョン : 1.7.5■更新情報• 1.7.5 では、F4_1G と B4_1G という新しいインスタンスが利用可能になったり、DataNucleus プラグインが 2.1.2 にバージョンアップされたり、いくつかバグ対応が行われています。
• 1.7.5 リリースノート : http://code.google.com/p/
googleappengine/wiki/SdkForJavaReleaseNotes

GPars
GPars は、Groovy に直感的で安全な並行処理を提供するシステム
です。
URL: http://gpars.codehaus.org/
バージョン : 1.0.0GA■更新情報• 1.0.0GA では、dataflow 用に同期チャネルが追加されたり、静的にディスパッチするアクターが追加されたり、いくつかバグ対応が行われています。
• 1.0.0GA リリースノート : http://jira.codehaus.org/secure/
ReleaseNote.jspa?projectId=12030&version=17007

Groovy++Groovy++ は、Groovy 言語に対して静的な機能を拡張します。
URL: http://code.google.com/p/groovypptest/
バージョン : 0.9.0

Spock
Spock は、Java や Groovy 用のテストと仕様のためのフレームワー
クです。
URL: http://code.google.com/p/spock/バージョン : 0.7■更新情報• 0.7 では、リファレンスドキュメントが新しくなったり、ス
タブやモックがいろいろと改良されたり、Groovy 2.x 対応されたりしています。
• 0.7 リリースメール : http://docs.spockframework.org/en/
spock-0.7-groovy-2.0/new_and_noteworthy.html#id1

GroovyServ
GroovyServ は、Groovy 処理系をサーバとして動作させることでgroovy コマンドの起動を見た目上高速化するものです。

G*Magazine vol.6
URL: http://kobo.github.com/groovyserv/
バージョン : 0.11
■更新情報

• 0.11 では、リモートアクセスがサポートされたり、“cookie”
が “authtoken” にリネームされたり、いくつかバグ対応が行
われています。
• 0.11 リリースノート : http://kobo.github.com/groovyserv/
changelog.html#ref-changelog

Geb
Geb は、Groovy を使用した Web ブラウザを自動化する仕組みです。
URL: http://www.gebish.org/
バージョン : 0.7.2■更新情報• 0.7.2 では、Java 7 で実行した場合に GebAssertionError が発生する問題の対応が行われています。
• 0.7.2 リリースノート : http://jira.codehaus.org/secure/
ReleaseNote.jspa?projectId=12101&version=18756

GContracts
GContracts は、Groovy で契約プログラミングを行うためのフレームワークです。
URL: https://github.com/andresteingress/gcontracts
バージョン : 1.2.10■更新情報• 1.2.10では、Groovy 1.8.8や Java 7で使った時のバグ対応など、いくつかバグ対応が行われています。
• 1.2.10 リリースメール : http://blog.andresteingress.
com/2012/10/17/gcontracts-1-2-10-released/

GroovyFX
GroovyFX は、JavaFX を Groovy で書きやすくするためのフレームワークです。
URL: http://groovyfx.org/
バージョン : 0.3.1■更新情報• 0.3.1 での変更箇所は不明です。

Easyb

GBenchEasyb は、 ビ ヘ イ ビ ア 駆 動 開 発 (Behavior Driven
Development:BDD) 用のフレームワークです。
URL: http://www.easyb.org/
バージョン : 0.9.8

■更新情報

Gmock
Gmock は、Groovy 用のモック・フレームワークです。
URL: http://code.google.com/p/gmock/バージョン : 0.8.2

HTTPBuilder
HTTPBuilder は、HTTP ベースのリソースに簡単にアクセスするための方法です。
URL: http://groovy.codehaus.org/modules/http-builder/バージョン : 0.6.0■更新情報• 0.6.0 では、HttpClient が 4.2.1 に、Nekohtml が 1.9.16 に対応し、JSON の扱いが jsonlib から JsonSlurper に変更となりました。
• 0.6.0 チェンジログ : http://groovy.codehaus.org/modules/
http-builder/changes.html

CodeNarc
CodeNarc は、Groovy 向けの静的コード解析ツールです。
URL: http://codenarc.sourceforge.net/
バージョン : 0.18.1■更新情報• 0.18.1 では、SpaceAroundOperatorRule や BracesForClassRuleなど、いくつかバグ対応が行われています。
• 0.18.1 リリースノート : http://sourceforge.net/projects/
codenarc/files/codenarc/CodeNarc%20Version%200.18.1/

GMetrics
GMetrics は、Groovy ソースコードのサイズや複雑さを計算したり報告するためのツールです。
URL: http://gmetrics.sourceforge.net/
バージョン : 0.6■更新情報• 0.6 では、メトリクスやフューチャーが追加されたり、メト
リクスのインタフェースが変更されたり、いくつかバグ対応が行われています。
• 0.6 リリースノート : http://sourceforge.net/projects/
gmetrics/files/gmetrics-0.6/

GBench は、Groovy のためのベンチマーク・フレームワークです。
URL: http://code.google.com/p/gbench/
バージョン : 0.4.0• 0.4.0 では、パッケージ名が "groovyx.gbench" となったり、
BenchmarkBuilder を実行する拡張モジュールが追加された
り、@Benchmark アノテーションと BenchmarkBuilder の両方のパフォーマンスが改良されたりしています。
• 0.4.0 リリースノート :http://code.google.com/p/gbench/wiki/ReleaseNotes040

Betamax
Betamax は、HTTP 通信の内容を保存し再生するテストツールです。
URL: http://freeside.co/betamax/
バージョン : 1.1.2■更新情報• 1.1.2 での変更箇所は不明です。

Caelyf
Caelyf は、Groovy で記述する Cloud Foundry 用のライトウェイト
なツールキットです。
URL: http://caelyf.cloudfoundry.com/
バージョン : 0.1

Vert.xVert.x は、非同期アプリケーション開発のためのフレームワーク
です。
URL: http://vertx.io/
バージョン : 1.3.1■更新情報• 1.3.1 では、coffee-script.js を事前にコンパイルしたり、
sockjs から切断する前に unregister フックを呼び出すようにしたり、各種バグ対応が行われています。
• 1.3.1 リリース issue: https://github.com/vert-x/vert.x/issues?
milestone=25&state=closed

GVM (Groovy enVironment Manager)
様々な Groovy 関連のツールをインストールし、複数のバージョンを切り替えて使用するためのツールです。
URL: http://gvmtool.net/
バージョン : リリース情報

23

■企業スポンサー■個人サポーター
須江 信洋 様関谷 和愛 様
田中

明様

個人サポータ制度のお知らせ
JGGUG では , 昨年に引き続き 2013 年度も個人サポータを募集いたします。.
個人サポータとなっていただいた方には、一年間にわたって JGGUG が発行する G* Magazine（年数回刊。基本的に電子版として配布予定）に個人サポータとしてお名前を掲載します（掲載を希望しない旨お申し出いただけば掲載しません）。
個人サポータとなるには、まず supporters@jggug.org にメイルで• お名前• 予定金額G* Magazine へのご芳名掲載の可否をお知らせください。追って、運営委員より振込先の情報などを返信します。
皆様のサポートをお待ちしております。

日本 Grails/Groovy ユーザーグループ
代表

山田 正樹

G* Magazine vol.6 2013.02
http://www.jggug.org

発行人：日本 Grails/Groovy ユーザーグループ
編集長：川原正隆
編集：G* Magazine 編集委員（杉浦孝博、奥清隆）
デザイン：㈱ニューキャスト
表紙：川原正隆
編集協力：JGGUG 運営委員会
Mail：info@jggug.org© 2013 JGGUG 掲載記事の再利用についてはCreative Commons ライセンスによります。

Publisher：Japan Grails/Groovy User Group
Editor in Chief：Masataka Kawahara
Editors：G* Magazine Editors Team
(Takahiro Sugiura, Kiyotaka Oku)
Design：NEWCAST inc.
CoverDesign：Masataka Kawahara
Cooperation：JGGUG Steering Committee
Mail：info@jggug.org