読者です 読者をやめる 読者になる 読者になる

Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

Vert.x がいいね!(第2回:開発環境を構築する)

vert.x Java

id:KenichiroMurataです。

f:id:acro-engineer:20131221154226j:plain:w200

皆さん、Vert.x 使っていますか?

前回の「Vert.x がいいね!(第1回:入門する) - Taste of Tech Topics」に続き、第2回目となる今回は開発環境の構築について書きます。

目次は以下の通りです。

  1. environment
  2. install
  3. setting
  4. gradle project template
  5. auto redeoploy
  6. remote debugging

1. environment

Vert.xをインストールをして開発を行う前に、必要な環境を揃えましょう。私の環境はOS X Mountain Lionですので、Windowsの方は環境に合わせて読み替えてください。

JDK 1.7

Vert.xはJDK 1.7.0以上が必要になります。JDK 1.7は「Java SE - Downloads | Oracle Technology Network | Oracle」からダウンロードしてインストールしてください。

私の環境では以下になります。

ken@~ $ java -version
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)

Eclipse

開発にはEclipse Kepler (4.3) IDE for Java EE Developers を使います。Java EE Developersを使うのは、HTML/CSS/JavaScript(JSON)を開発で使うので、関連ツールが最初から入っていると楽だからです。

Eclipse Downloads」からダウンロードしてインストールしてください。

2. install

それでは次はVert.xのインストールです。インストール手順は公式サイトに説明があります。「ダウンロードページ」からサイトに行って、vert.x-2.0.0-final.tar.gz をダウンロードしてください。適当なディレクトリで解凍しましょう。

パスを通す

Vert.xのアーカイブを解凍したら、vertxコマンドが使えるようにパスを通します。私の場合は、ホーム直下に配置したので、以下のように.bashrcにPATHを定義しました。

ken@~ $ cat .bashrc 
PS1="\u@\W \$ "
PATH="$PATH":/Users/ken/vert.x-2.0.0-final/bin

ken@~ $ source .bashrc 

パスを通して、有効化したらvertxコマンドを実行してください。usageが表示されれば完了です。

ken@~ $ vertx

Hello World!

前回も紹介しましたが、Hello World的なプログラムを作成し、動作確認をしてみましょう。
以下の内容をHelloWorldVerticle.javaというファイル名で保存してください。

import org.vertx.java.core.Handler;
import org.vertx.java.core.http.HttpServerRequest;
import org.vertx.java.platform.Verticle;

public class HelloWorldVerticle extends Verticle {

  public void start() {
    container.logger().info("Verticle start.");
    vertx.createHttpServer().requestHandler(new Handler<HttpServerRequest>() {
      public void handle(HttpServerRequest req) {
        req.response().headers().set("Content-Type", "text/plain");
        req.response().end("Hello World!");
      }
    }).listen(8080);
  }
}

ファイルを作成したら、次のようにコマンドを実行し、ブラウザからlocalhost:8080にアクセスしてください。

ken@work $ vertx run HelloWorldVerticle.java 
Verticle start. 

.classではなく、.javaなファイルを指定しても動作するところがVert.xの面白い所ですね。

3. setting

開発をする上ではVert.xのログファイルを確認します。デフォルト設定はOSのtmpディレクトリにvertx.logが出力されるのですが、私の環境では権限の問題などあり、そのままだと出力されません。そこで、vert.xのディレクトリにlogディレクトリを作成し、そこにvertx.logが出力されるように設定変更しましょう。

設定ファイルは「vert.x-2.0.0-final/conf/logging.properties」になります。このファイルの以下の部分を変更します。

# Put the log in the system temporary directory
#java.util.logging.FileHandler.pattern=%t/vertx.log
java.util.logging.FileHandler.pattern=/Users/ken/vert.x-2.0.0-final/log/vertx.log

この設定をした後に、再度HelloWorldVerticleを実行してみましょう。先ほど指定したvertx.logにログが出力されているはずです。

ken@~ $ cat vert.x-2.0.0-final/log/vertx.log
[vert.x-eventloop-thread-2] 03:06:37,789 INFO [null-HelloWorldVerticle.java-704507910]  Verticle start.

最初からスレッド名とか出てくれるのはありがたいですね。

4. gradle project template

Vert.xではVerticleか、1つ以上のVerticleを含んだModuleという形式で開発を行います。簡単なプロトタイプでは直接Verticleを作成する形式でよいと思いますが、ちゃんとしたアプリケーションや再利用可能なモジュールを開発するのであればVerticleが1つであってもModuleとして開発した方がよいと思います。

Vert.xではこのModuleを開発するために、Mavenarchetypeを使ったproject templateによる開発と、Gradleによる project templateを使った開発の2つの方法を用意しています。ここではGradleによるproject templateを使った開発方法について説明します。Developing Vert.x Modules with Gradleを参考にします。

ちなみに、GradleはGroovyによるビルドツールですが、このproject templateに内包されているため、別途インストールは不要です。この辺りも便利ですね。

git cloneして、Eclipseにインポートする

まずは、vertx-gradle-templateからgit cloneします。このgradle project templateはJava、Groovy、JavaScriptRubyPythonの全てのサンプルソースとそのテストコードが含まれており、非常に勉強になります。ですが、その分いろいろと含んでおり、testの実行にも時間が掛かります。そこで、とりあえずJavaでだけの場合を必要最小限に知りたいという人(私のことです)向けに、ミニマムなJava用のgradle project templateとして、vert.x-module-template-for-javaを作成しましたので、こちらの方が好みの方はぜひご利用ください。

ken@work $ git clone https://github.com/vert-x/vertx-gradle-template.git my-vertx-module
ken@work $ cd my-vertx-module/
ken@my-vertx-module $ git remote rm origin

git cloneしたら、早速テストを動かして確認してみましょう。

ken@my-vertx-module $ ./gradlew test

次にEclipseからプロジェクトとしてインポートできるように、eclipseタスクを実行します。

ken@my-vertx-module $ ./gradlew eclipse

これでEclipseプロジェクトとしてのセットアップが完了するので、Eclipseからインポートできるようになります。

mod.json

Moduleを開発する際にはmod.jsonという設定ファイルを作成する必要があります。gradle project templateでは「src/main/resources/mod.json」にあります。このmod.jsonでは以下のようにmainとしてModuleのエントリポイントとなるVerticleを定義する必要があります。

    "main":"com.mycompany.myproject.PingVerticle",

また、このmod.jsonには、main以外にもModuleをリポジトリに公開する際に必要となるdescription、licenses、authorなどを定義します。詳細はファイルを確認してください(開発だけの場合にはmainだけでOKです)。

HelloWolrdVerticleをModuleとして動かす

先ほど作成したHelloWorldVerticle.javaをModuleとして動かしてみましょう。HelloWorldVerticle.javaを「src/main/java」以下に配置して、mod.jsonを以下のように変更します。

  // "main":"com.mycompany.myproject.PingVerticle",
  "main":"HelloWorldVerticle",

ここまでできたら、runModEclipseタスクを利用して動作させてみましょう。

ken@my-vertx-module $ ./gradlew runModEclipse

ブラウザでlocalhost:8080にアクセスすると動作が確認できます。

ただし、この方法は2つの問題があります。

  1. ログ出力がされない
  2. gradleによる起動は時間がかかる

1つ目のログ出力されないという問題はgradleがvertxのログ設定を上書きしてしまうため、vertxのログ出力が有効になりません。また、2つ目の起動に時間がかかるというのは、やってみると分かりますが、gradleの依存関係のあるタスクが全て動くためでしょう、私の環境では約10秒はかかります。よって、繰り返し実行するにはちょっとつらい状況です。

そこで、TIPS的な内容になりますが、次の方法で行うことをオススメします。

vertx runmodでModuleを動かす

./gradlew runModEclipseではなく、vertx runmod コマンドを使ってModuleを動かすと、ログ出力も正しく行われ、起動にも時間がかかりません。実際には以下のようにモジュール名とclass pathを指定して実行します。

ken@my-vertx-module $ vertx runmod com.mycompany~my-module~0.0.1 -cp bin

cpオプションで指定しているbinディレクトリはEclipseプロジェクトでのoutputディレクトリです。

ただし、vertx runmodでModuleを実行するには、カレントディレクトリの直下のmodsディレクトリ配下にModuleをインストール(配置)しておく必要があります。そうなるとこの実行方法をとる場合に、毎回作成したModuleをmods以下に配置する必要があります。ただ、実際の所は、mods以下にモジュール名のディレクトリとその配下にmod.jsonのみが存在すれば、後は-cpで指定したbinディレクトリにあるclassファイルを利用することで動作させることができます。

mod.jsonは一度定義すればほとんど変更はしないので、最初にこの作業を行えば、後はvertx runmodで開発のフローを回すことができます。

とは言っても手作業でこれをやるのは手間なので、私はgradleのタスクに以下のようなcopyModJsonというタスクを作って、実行するようにしています。

task copyModJson( type:Copy, dependsOn: 'copyMod', description: 'Copy the mod.json into the local mods directory for runmod auto-redeploy' ) {
  file("mods/$moduleName").mkdirs()
  from "build/mods/$moduleName/mod.json"
  into "mods/$moduleName"
}

このタスクを「gradle/vertx.gradle」に追加しています。vert.x-module-template-for-javaにはこのタスクを追加したvertx.gradleが含まれているので、こちらを使うか、ソースを確認してください。

上記のタスクが使えるようになっていれば、以下のように実行することで、準備が整います。

ken@my-vertx-module $ ./gradlew copyModJson

後は、先ほど紹介した通り、vertx runmodコマンドでModuleを実行してください。

ken@my-vertx-module $ vertx runmod com.mycompany~my-module~0.0.1 -cp bin

ちなみに、モジュール名はdomain~modulename~versionという形式と決まっており、これらの定義は「gradle.properties」に以下のように定義されていますので、必要に応じて変更してください。

# E.g. your domain name
modowner=com.mycompany

# Your module name
modname=my-module

# Your module version
version=0.0.1

5. auto redeoploy

Vert.xのModuleにはauto-redeployという機能があります。これはソースやclassファイルが変更されたらvertxを再起動せずにauto-redeployしてくれるという機能です。これも非常に便利です。デフォルトでは設定はOFFになっているので、mod.jsonに以下のように定義して有効にしましょう。

  //"main":"com.mycompany.myproject.PingVerticle",
  "main":"HelloWorldVerticle",
  "auto-redeploy": true,

これで準備は整いましたので、実際に試してみましょう。まずは先ほどと同様にvertx runmodコマンドでModuleを実行します。

ken@my-vertx-module $ vertx runmod com.mycompany~my-module~0.0.1 -cp bin
Verticle start. 

ブラウザでアクセスすると「Hello World!」が返ってきます。次は試しにEclipse上でHelloWorldVerticle.javaを以下のように変更し、保存します。

    vertx.createHttpServer().requestHandler(new Handler<HttpServerRequest>() {
      public void handle(HttpServerRequest req) {
        req.response().headers().set("Content-Type", "text/plain");
        //req.response().end("Hello World!");
        req.response().end("Hello World!!!");
      }
    }).listen(8080);

保存すればEclipseが自動的にコンパイルをするので、binディレクトリ以下のclassファイルが更新されます。
そうするとvertxのログに以下のように出力され、変更を検知したvertxがauto-deployしたことが分かります。

ken@my-vertx-module $ vertx runmod com.mycompany~my-module~0.0.1 -cp bin
Verticle start. 
Module com.mycompany~my-module~0.0.1 has changed, reloading it. 
Verticle start. 

ブラウザを実際に再読込させてみると「Hello World!!!」が返ってきます。う〜む、便利ですね。

6. remote debugging

Moduleを実際にデバッグするには、通常のjavaプログラムと同じようにremote debuggingができます。設定方法は簡単です。「vert.x-2.0.0-final/bin/vertx」の冒頭部分にJVM_OPTSを定義する箇所がありますので、以下のように定義します。

#JVM_OPTS="-XX:+CMSClassUnloadingEnabled -XX:-UseGCOverheadLimit"
#JVM_OPTS=""
JVM_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n"

これで後は、vertx runmodコマンドを実行し、Eclipseからremote debuggingで8000ポートにアタッチすれば、あとはブレークポイントを設定するなり、なんなりお好きにどうぞ!、という感じです。

長くなりましたが、Vert.xによるModule開発をするための開発環境の構築について説明してきました。ぜひ一度お試し下さい。
私もまだまだ試行錯誤している状態ですので、こんなやり方しているよ!という情報がありましたら、お寄せ頂けるとありがたいです。