Groovy で Vert.x のモジュールを作成

Vert.x のモジュールを Groovy で作成する方法をご紹介します。

サンプルソースは http://github.com/fits/try_samples/tree/master/blog/20120708/

モジュールの配置場所

モジュールは以下のディレクトリに配置できます。

  • Vert.x の mods ディレクトリ
  • 環境変数 VERTX_MODS で指定したディレクトリ

両方の場所に同じモジュールを配置した場合、Vert.x 1.1.0 では mods ディレクトリに配置した方が優先される模様です。

モジュールの作り方

モジュールの基本的な作り方は以下の通りです。

  1. モジュール用のディレクトリ作成 *1
  2. モジュール定義ファイル mod.json 作成
  3. 実行スクリプト作成 *2

実質的には、通常の Vert.x アプリケーションにモジュール定義ファイル mod.json を追加するだけです。

mod.json の設定内容

モジュール定義ファイル mod.json には以下のような設定項目を記載します。(main は必須)

項目名 概要 デフォルト値 設定例
main モジュールの開始時に実行するスクリプト / クラス sample.groovy
worker Worker Verticle として実行するか否か false true
preserve-cwd モジュールのカレントディレクトリを実行ディレクトリとするか否か false true

なお、今回のような Groovy スクリプトのモジュールを mods ディレクトリに配置する場合、preserve-cwd が false だと以下のようなエラーが発生しました。(環境変数 VERTX_MODS の場所に配置した場合は問題なし)

[vert.x-worker-thread-0] ・・・ Exception in Groovy verticle
java.lang.IllegalArgumentException: 'other' has different root
        at sun.nio.fs.WindowsPath.relativize(WindowsPath.java:392)
        at sun.nio.fs.WindowsPath.relativize(WindowsPath.java:44)
        at org.vertx.java.deploy.impl.VerticleManager.setPathAdjustment(VerticleManager.java:198)
        at org.vertx.java.deploy.impl.VerticleManager.access$600(VerticleManager.java:50)
        ・・・

サンプルモジュールの作成1

それでは "hello" と出力して終了するだけの簡単なモジュール hello を作成してみます。

ファイル構成は以下の通りです。

  • hello ディレクトリ
    • mod.json ファイル
    • hello.groovy ファイル

まず、モジュール定義ファイルに実行スクリプト名を定義します。

mod.json
{
    "main": "hello.groovy"
}

次に、hello.groovy を実装します。

"hello" と出力して終了する処理は以下の通りです。処理を明示的に終了させるには container.exit() の実行が必要な点にご注意ください。

hello.groovy
println "hello"
//処理を終了させるには以下が必要
container.exit()

VERTX_MODS 環境変数を設定して hello モジュールを実行した結果は以下の通りです。
"vertx run <モジュール>" でモジュールを実行します。

実行例
> set VERTX_MODS=c:\try_sample\blog\20120708\vertx_module
> vertx run hello
hello
Started

サンプルモジュールの作成2

次は、もう少し高度なサーバーモジュールを実装してみます。

Groovy スクリプトに以下のメソッドを用意すればモジュールの開始/終了時の処理を実装する事ができます。*3

  • run() : モジュール開始時
  • vertxStop() : モジュール終了時

run() の戻り値の型を Object[] にしないと実行時にエラーが発生するようなのでご注意ください。

ここでは RouteMatcher を使って Sinatra 風の Web サーバー処理を実装してみました。

sample_server.groovy
import org.vertx.groovy.core.http.RouteMatcher

//モジュール開始時の処理
Object[] run() {
    def rm = new RouteMatcher()

    rm.get '/sample', { req ->
        req.response.end 'test data'
    }

    rm.get '/sample/:id', { req ->
        req.response.end "data : ${req.params['id']}"
    }

    server = vertx.createHttpServer()
    server.requestHandler(rm.asClosure()).listen 8080
    println "* server start"
}

//モジュール終了時の処理
def vertxStop() {
    server.close()
    println "* server stop"
}

以下のようにモジュールを実行した後、"http://localhost:8080/sample/aaa" 等へのアクセスで Web サーバー処理が動作している事と Ctrl + c でモジュールを終了した際に "* server stop" が出力される事を確認できると思います。

実行例
> set VERTX_MODS=c:\try_sample\blog\20120708\vertx_module
> vertx run web_sample
* server start
Started

*1:ディレクトリ名がモジュール名として扱われます

*2:Java の場合はクラス

*3:org.vertx.java.deploy.impl.groovy.GroovyVerticleFactory に実装されています