"Introduction to Vert.x"をGradleで試す


Vert.x 3系のドキュメントに"[Introduction to Vert.x](http://vertx.io/blog/posts/introduction-to-vertx.html)"があります。ソースコードを０から組み上げて簡単な CRUD画面を作るまでが書かれていて、初めに行うチュートリアルとして優れています。しかし残念ながらMavenベースで書かれているので、Gradleではどのようにすれば良いのかが書かれていません。なので、このチュートリアルをGradleで試してみました。ソースは以下のリポジトリにあります。

https://github.com/nakaken0629/my-first-app

とりあえず、Gradle 3系が動くようになるまでは、自力で頑張ってください。あとはMacで試しています。Linuxでも大体同じようにできると思いますが、Windowsはさらに修正がいると思います。こんな感じでGradleの実行ができれば、Gradleの導入完了です。

```
$ gradle --version

------------------------------------------------------------
Gradle 3.4.1
------------------------------------------------------------

Build time:   2017-03-03 19:45:41 UTC
Revision:     9eb76efdd3d034dc506c719dac2955efb5ff9a93

Groovy:       2.4.7
Ant:          Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM:          1.8.0_101 (Oracle Corporation 25.101-b13)
OS:           Mac OS X 10.11.6 x86_64
```

# My first Vert.x 3 Application

## Let’s start !

まずはプロジェクトの新規作成を行います。

```
$ mkdir my-first-app
$ cd my-first-app
$ gradle init --type java-application
```

プロジェクト情報と、vertx-coreを参照する設定を、build.gradleに行います。

```diff
diff --git a/build.gradle b/build.gradle
index c63225d..2576243 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,6 +6,12 @@
  * user guide available at https://docs.gradle.org/3.4.1/userguide/tutorial_java_projects.html
  */

+group 'io.vertx.blog'
+version '1.0-SNAPSHOT'
+project.ext {
+      artifactId = 'my-first-app'
+}
+
 // Apply the java plugin to add support for Java
 apply plugin: 'java'

@@ -21,7 +27,7 @@ repositories {

 dependencies {
     // This dependency is found on compile classpath of this component and consumers.
-    compile 'com.google.guava:guava:20.0'
+    compile 'io.vertx:vertx-core:3.0.0'

     // Use JUnit test framework
     testCompile 'junit:junit:4.12'
```

## Let’s code !

MyFirstVerticleクラスは、 "src/main/java/io/vertx/blog/first/MyFirstVerticle.java" に作成します。

これでコンパイルが通るようになります。

```
$ ./gradlew compileJava
:compileJava UP-TO-DATE

BUILD SUCCESSFUL

Total time: 2.633 secs
```

## Let’s test

vertx-unitを参照する設定を、build.gradleに行います。

```diff
diff --git a/build.gradle b/build.gradle
index 2576243..404ca01 100644
--- a/build.gradle
+++ b/build.gradle
@@ -31,6 +31,7 @@ dependencies {

     // Use JUnit test framework
     testCompile 'junit:junit:4.12'
+    testCompile 'io.vertx:vertx-unit:3.0.0'
 }
```

MyFirstVerticleTestクラスは、"src/test/java/io/vertx/blog/first/MyFirstVerticleTest.java" に作成します。

これでテストが通るようになります。

```
$ ./gradlew test
:compileJava UP-TO-DATE
:processResources NO-SOURCE
:classes UP-TO-DATE
:compileTestJava UP-TO-DATE
:processTestResources NO-SOURCE
:testClasses UP-TO-DATE
:test UP-TO-DATE

BUILD SUCCESSFUL

Total time: 1.665 secs
```

## Packaging

shadeはMaven用のプラグインなので、Gradleで同じような機能を持つshadowを導入します。設定はbuild.gradleに行うだけです。以下の内容を追加しています。

* shadowプラグインを追加する
* mainクラスをデフォルトの"App"クラスから"io.vertx.core.Starter"クラスに変更する
* "shadowJar"タスクを追加する

```diff
$ git diff
diff --git a/build.gradle b/build.gradle
index 404ca01..c7198bb 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,6 +6,10 @@
  * user guide available at https://docs.gradle.org/3.4.1/userguide/tutorial_java_projects.html
  */

+plugins {
+    id 'com.github.johnrengelman.shadow' version '1.2.3'
+}
+
 group 'io.vertx.blog'
 version '1.0-SNAPSHOT'
 project.ext {
@@ -35,5 +39,14 @@ dependencies {
 }

 // Define the main class for the application
-mainClassName = 'App'
-
+mainClassName = 'io.vertx.core.Starter'
+
+shadowJar {
+    classifier = 'fat'
+    manifest {
+        attributes 'Main-Verticle': 'io.vertx.blog.first.MyFirstVerticle'
+    }
+    mergeServiceFiles {
+        include 'META-INF/services/io.vertx.core.spi.VerticleFactory'
+    }
+}
```

shadowJarタスクを実行して、fat jarファイルを作成します。ファイルは"build/libs/"ディレクトリ以下に作成されます。

```
$ ./gradlew shadowJar
:compileJava
:processResources NO-SOURCE
:classes
:shadowJar

BUILD SUCCESSFUL

Total time: 2.74 secs
```

## Executing our application

以下のコマンドで起動できます。止める時は"CTRL + C"を押します。

```
$ java -jar build/libs/my-first-app-1.0-SNAPSHOT-fat.jar
3 26, 2017 9:59:36 午前 io.vertx.core.Starter
情報: Succeeded in deploying verticle
```

# Vert.x Application Configuration

この章は、特筆するべきGradleだけのカスタマイズはありません。

# Some Rest with Vert.x

## Vert.x Web

vertx-webをclasspathに追加します。

```diff
$ git diff head^ head
diff --git a/build.gradle b/build.gradle
index c7198bb..31f115e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -32,6 +32,7 @@ repositories {
 dependencies {
     // This dependency is found on compile classpath of this component and consumers.
     compile 'io.vertx:vertx-core:3.0.0'
+    compile 'io.vertx:vertx-web:3.0.0'

     // Use JUnit test framework
     testCompile 'junit:junit:4.12'
```

# Some Rest with Vert.x

この章は、特筆するべきGradleだけのカスタマイズはありません。

# Unit and Integration Tests

## Implement the plan

TODO:テスト用に空いているポートを探して、src/test/resources/my-it-config.jsonをビルド時に書き換える

既存のtestタスクについて、shadowJarに依存するようにするとの、テスト実行前にvertxプロセスを起動して、テスト終了後にvertxプロセスを終了する設定を追加する。

```diff
diff --git a/build.gradle b/build.gradle
index 31f115e..fc8c656 100644
--- a/build.gradle
+++ b/build.gradle
@@ -51,3 +51,13 @@ shadowJar {
         include 'META-INF/services/io.vertx.core.spi.VerticleFactory'
     }
 }
+
+test.dependsOn.add(shadowJar)
+test.doFirst {
+    ant.java(jar: "build/libs/${project.name}-${version}-fat.jar",
+            fork: true,
+            spawn: true)
+}
+test.doLast {
+    ['sh', '-c', "ps -ax | grep ${project.name}-${version}-fat.jar | grep -v grep | awk 'NR==1{print \$1}' | xargs kill -SIGTERM"].execute()
+}
```
## Hey, we don’t have integration tests !

"AssertJ"と"Rest-Assured"をclasspathに追加する設定を、build.gradleに行う。

```diff
diff --git a/build.gradle b/build.gradle
index fc8c656..a5ea94a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -37,6 +37,8 @@ dependencies {
     // Use JUnit test framework
     testCompile 'junit:junit:4.12'
     testCompile 'io.vertx:vertx-unit:3.0.0'
+    testCompile "com.jayway.restassured:rest-assured:2.4.0"
+    testCompile "org.assertj:assertj-core:2.0.0"
 }
```

これで、Integration Testも通るようになります。

```
$ ./gradlew test
:compileJava
:processResources
:classes
:shadowJar
:compileTestJava
:processTestResources NO-SOURCE
:testClasses
:test

BUILD SUCCESSFUL

Total time: 9.685 secs
```

# Using the asynchronous SQL client

この章は、特筆するべきGradleだけのカスタマイズはありません。

# Combine vert.x and mongo to build a giant

TODO: 試してみる（今の所mongoに興味がないので、パスしてます :-p)