皆さん、Vert.x 使っていますか?
前回の「Vert.x がいいね!(第1回:入門する) - Taste of Tech Topics」に続き、第2回目となる今回は開発環境の構築について書きます。
目次は以下の通りです。
- environment
- install
- setting
- gradle project template
- auto redeoploy
- 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を開発するために、Mavenのarchetypeを使った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、JavaScript、Ruby、Pythonの全てのサンプルソースとそのテストコードが含まれており、非常に勉強になります。ですが、その分いろいろと含んでおり、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
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つの問題があります。
- ログ出力がされない
- 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開発をするための開発環境の構築について説明してきました。ぜひ一度お試し下さい。
私もまだまだ試行錯誤している状態ですので、こんなやり方しているよ!という情報がありましたら、お寄せ頂けるとありがたいです。
次回は?
Vert.xで気になるのはEvent LoopスレッドとVerticle Instanceの設定の関係です。次回はその辺りを書きたいと思います。
それでは!
See also
- Vert.x がいいね!(第1回:入門する) - Taste of Tech Topics
- Vert.x がいいね!(第3回:Event LoopsとVerticle Instances) - Taste of Tech Topics
- Vert.x がいいね!(第4回:テストする) - Taste of Tech Topics
- RxJavaを使ってCallback Hellから脱出する( Vert.x がいいね!第5回 ) - Taste of Tech Topics
- RxJavaを使ってCallback Hellから脱出する( Java8 ラムダ編 ) - Taste of Tech Topics