G::blog

主にVert.xやYokeについての覚書

Vert.x 2 のGradleテンプレートを用いた auto-redeploy 可能な Eclipse プロジェクトの作成方法

先日は、「Yoke の Gradle テンプレートを用いた auto-redeploy 可能な Eclipse プロジェクトの作成」としてYokeを使ったアプリケーションを開発するための Eclipseプロジェクトの作り方を不十分ながら記事にしました。

今回も現時点でわかっている範囲での覚書という位置づけですが、 Vert.x の Gradle テンプレートを用いた純粋な Vert.x アプリケーション(実行可能なモジュール)を開発するための Eclipseプロジェクトの作り方について書きます。

今回は、簡単なサービスを書く言語として、Groovy を使いました。しかし、Javaでも大きくは変わらないはずです。

1. Vert.x の Gradle テンプレートを取得し、展開したフォルダに適当な名前を付ける。

Vert.x Gradle Template を訪ねて、【ZIP】ボタンを押して Gradle テンプレートの ZIP アーカイブをダウンロードします。vertx-gradle-template-master.zip という名前のファイルが、ダウンロードされるでしょう。

それを展開し、名前を適当に変えます。

% unzip vertx-gradle-template-master.zip
% mv vertx-gradle-template-master vertx-hello-world
% 

2. 必要により gradle.properties ファイルを修正する。

この記事を書いている時点では、Vert.x 2 の最新は、beta5 でした。Gradelテンプレートに含まれている gradle.properties ファイルにおいてもそのように記述されていたので、何もしないで閉じました。
きっちりした方は、モジュール名など変えるなどされてもよいでしょう。

3. Verticle の内容を変えて、ブラウザでアクセスしてみる。

src/main/groovy/example にある GroovyVerticle.groovy ファイルをHTTPサービスをするように修正します。

package example

import org.vertx.groovy.platform.Verticle

class GroovyVerticle extends Verticle {
    def start() {
	vertx.createHttpServer().requestHandler{ request ->
   		request.response.end("<html><body><h1>Hello from vert.x!</h1></body></html>")
	}.listen(8080)    
    }

}


次に、ターミナルから

% gradlew runMod

と実行します。これにより必要なモジュールなどがダウンロードされてサービスが起動します。

% gradlew runMod
(省略)
:compileJava UP-TO-DATE
:compileGroovy
:processResources
:classes
:copyMod
:pullInDeps
Pulling in dependencies for module com.mycompany~my-module~1.0.0-SNAPSHOT. Please wait
Dependencies pulled in successfully
:modZip
:jar SKIPPED
:signArchives SKIPPED
:assemble
:compileJava UP-TO-DATE
:compileGroovy
:processResources UP-TO-DATE
:classes
:copyMod
:runMod
CTRL-C to stop server
> Building > :runMod

といった状態になれば OK です。

※注意: Vert.x の要求によりJDK 1.7.0かそれ以降が必要です。


ここで、ブラウザら http://localhost:8080/ にアクセスしてみると、"Hello from vert.x!" と表示されるはずです。

表示されたなら CTRL-Cを入力して一旦終了します。

4. Eclipseにインポートする

% gradlew eclipse

と入力してみます。


すると、

% gradlew eclipse
:eclipseClasspath
Download http://repo1.maven.org/maven2/io/vertx/testtools/2.0.0-beta2/testtools-2.0.0-beta2.pom
Download http://repo1.maven.org/maven2/io/vertx/lang-groovy/2.0.0-beta4/lang-groovy-2.0.0-beta4-sources.jar
Download http://repo1.maven.org/maven2/io/vertx/testtools/2.0.0-beta2/testtools-2.0.0-beta2-sources.jar
Download http://repo1.maven.org/maven2/io/vertx/testtools/2.0.0-beta2/testtools-2.0.0-beta2.jar
:eclipseJdt
:eclipseProject
:eclipse

BUILD SUCCESSFUL

Total time: 11.735 secs

というふうに出力されます。

ディレクトリを眺めてみると、.settings や .classpath などの Eclipse で開発しているとき遭遇するおなじみのファイルが作られています。

というわけで、このディレクトリを Eclipse の Import メニュー項目から表示される Import ダイアログの中にある "Existing Projects int Workspace" を使ってインポートします。

無事インポートできるのですが、src/test/java/com/mycompany/myproject/test/unit/ExampleUnitTest.java がエラーになってしまうので、適当に対応します。わたしは、エラーが起きているimport文などをコメントアウトしました。

※ 依存関係を変更した場合は、再度 gradlew eclipse を実行する必要があるようです。

5. 編集して、再度実行して、そのまま編集してみる。

src/main/groovy/example/GroovyVerticle.groovy の中のブラウザに返している文字列を "Hello from vert.x!" から "Hello from vert.x with Eclipse!" にして、

% gradlew runMod

を実行してみます。


無事起動したら、ブラウザで http://localhost:8080/ にアクセスしてみます。すると当然ですが、"Hello from vert.x with Eclipse!" と表示されます。

では、そのままの状態で、Eclipse から再度編集してみます。"Hello from vert.x with Eclipse!" から "Hello from vert.x with Eclipse!!" と "!" を一つ加えてみることにします。で、ブラウザをリロードします。まっとうな人生であるなら、何も変化がないはずです。

CNTRL-C を入力して一旦終了します。

6. auto-redeploy が効くようにする。

では、編集内容が反映するように、auto-redeploy のための設定をしていきます。

まずは、先日の記事と同様に、gradle/vertx.gradle の適当な位置に、次のタスクを追加します。

task runModEclipse(dependsOn: copyMod, description: 'Run the module using all the build dependencies (not using installed vertx') << {
  setSysProps()
  def classpath = [new URL("file:./bin/")] as URL[]
  def pm = PlatformLocator.factory.createPlatformManager()
  def latch = new CountDownLatch(1)
  pm.deployModuleFromClasspath(moduleName, null, 1, classpath, new AsyncResultHandler<String>() {
      public void handle(AsyncResult<String> asyncResult) {
          if (asyncResult.succeeded()) {
              println "CTRL-C to stop server"
          } else {
              println "Failed to deploy module"
              asyncResult.cause().printStackTrace()
              latch.countDown()
          }
      }
  });
  latch.await(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
}

※ このタスクでは、org.vertx.java.core.file.impl.PathAdjuster 正常に機能せずしないことが分かりました。リソースの取得が正常に動作しません。詳しくは、この記事を参照してください。


※ これは、ビギナーが作ったなんちゃってタスクですので、もっと良い方法があるかもしれません。

次に、Eclipse から src/main/resources/mod.json に、 "auto-redeploy": true を加えます。

{
  "main":"groovy:example.GroovyVerticle",

  // If your module is going to be registered in the Vert.x module registry you will also need the following
  // mandatory fields
  "description":"Put description of your module here",
  "licenses": ["The Apache Software License Version 2.0"],
  "author": "Joe Bloggs",

  // Optional fields
  "developers": ["Other Dev 1", "Other Dev 2"],
  "keywords": ["gerbils", "cars", "cheese", "chocolate", "underpants", "herring"],
  "homepage": "url to your project page",
  "auto-redeploy": true
}

設定はこれだけです。
これらの設定により、Eclipse が生成するクラスファイルや移動するリソースファイルの変更を Vert.x がキャッチして自動的にデプロイしなおしてくれます(現状、トップレベルのモジュールのみ)。

7. 再度実行して、編集してみる。

では、再度実行してみましょう。その際に、先ほど追加した runModEclipse タスクを使います。

% gradlew runModEclipse

起動してブラウザから http://localhost:8080/ にアクセスすると先ほどの修正が反映されて、"Hello from vert.x with Eclipse!!" と表示されるはずです。

では、Eclise から編集してみます。 "Hello from vert.x with Eclipse!!" を "Hello from vert.x with Eclipse!!!" というふうに "!" を一つ加えてブラウザの画面をリロードしてみます。
すると、その修正が反映された画面に変わるはずです。
もし変わらない場合は、 bin/mod.json の内容を確認してみてください。修正の反映された内容になっていないかもしれません。もし反映されていないならば、それに直接編集加えるか、反映されるまで根気よく Eclipse から src/main/resources/mod.json を修正してみてください。

ここまで来たら、gradlew を起動する前に、環境変数 JAVA_OPTS にデバッグのための引数を設定すれば、Eclipse からリモートデバッグも可能です。

例:
 -Xdebug -Xrunjdwp:transport=dt_socket,address=8002,server=y,suspend=n

8. あとがき

7. で、修正が反映されると書きましたが、わたしの環境では、GroovyVerticle#start() を

package example

import org.vertx.groovy.platform.Verticle

class GroovyVerticle extends Verticle {
    def start() {
	vertx.createHttpServer().requestHandler{ request ->
   		request.response.end("<html><body><h1>Hello from vert.x!</h1></body></html>")
	}.listen(8080, "localhost")    
    }
}

のようにホスト名を指定するようにして書いた場合、編集してリロードするとそのリロードが終わらないという現象が起きています。

この現象が起きても、ブラウザの停止ボタンを押してリロードすると無事反映されます。Java で Verticle を書いた場合も同様です。

現時点(Vert.x 2.0.0-CR1)で、このようになる原因は、私は把握できていません。
分かり次第、その都度、追記していきたいとおもいます。
何か気づかれた方がいらっしゃいましたら教えてください。