初めてのgradle build(Java)

## この記事について
シンプルなJavaアプリをGradleでビルドする極簡単なチュートリアルです。Gradleの雰囲気をつかむのが目的です。またGradle Wrapperの導入、利用方法も説明します。

ビルドスクリプトはGroovyで書くとか、この文法はこういう意味でとか、そういうことはあまり詳しく説明しません[^1]。でも、雰囲気はつかめると思いますよ。
[^1]: そもそも説明できるほど詳しくなかったり

## 想定読者
* JDKを自分で導入して簡単なプログラムが書ける程度のJavaプログラマ
* 「パスを通す」の意味がわかる人



## 前提条件
JDK6以上がダウンロードされていることが条件です。IDEは不要で、テキストエディタがあればよいです。



## プロジェクト作成
はじめに、GradleでビルドするためのJavaプロジェクトを作成します。Gradleの説明に主眼を置くために、できるだけシンプルなプロジェクトにします。


### ディレクトリ構成
お好きなディレクトリ配下に、次のディレクトリ構成を作成してください。

```
└── src
    └── main
        └── java
            └── hello
```


### ソースコード
`src/main/java/hello`ディレクトリ配下に'HelloWorld.java' と 'Greeter.java'の2クラスを作成してください。

```java:src/main/java/hello/HelloWorld.java
package hello;

public class HelloWorld {
  public static void main(String[] args) {
    Greeter greeter = new Greeter();
    System.out.println(greeter.sayHello());
  }
}
```

```java:src/main/java/hello/Greeter.java
package hello;

public class Greeter {
  public String sayHello() {
    return "Hello world!";
  }
}
```



## Gradleのインストール
Gradleをインストールしましょう。

[http://www.gradle.org/downloads](http://www.gradle.org/downloads)からバイナリをダウンロードできます。`gradle-バージョン-bin.zip`をDL・展開して、`bin`フォルダにパスを通してください。

以下のようなインストーラを使うのもありです。

* http://sdkman.io/
* Home brew(brew install gradle)

インストールできたか確認するために次のコマンドを実行してください

```
gradle
```

正しくインストールできていれば、ウェルカムメッセージが表示されます。

```
>gradle
Starting a Gradle Daemon (subsequent builds will be faster)
:help

Welcome to Gradle 3.2.1.

To run a build, run gradle <task> ...

To see a list of available tasks, run gradle tasks

To see a list of command-line options, run gradle --help

To see more detail about a task, run gradle help --task <task>

BUILD SUCCESSFUL

Total time: 8.667 secs
```

これでGradleのインストールは完了です。



## gradle tasks
プロジェクトディレクトリ配下で以下のコマンドを実行してください。

```
gradle tasks
```

`gradle tasks`コマンドはgradleで実行できるタスクを表示します。この時点では次の基本的なタスクが表示されたでしょう。

```
:tasks

------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------

Build Setup tasks
-----------------
init - Initializes a new Gradle build. [incubating]
wrapper - Generates Gradle wrapper files. [incubating]

Help tasks
----------
buildEnvironment - Displays all buildscript dependencies declared in root project 'hello'.
components - Displays the components produced by root project 'hello'. [incubating]
dependencies - Displays all dependencies declared in root project 'hello'.
dependencyInsight - Displays the insight into a specific dependency in root project 'hello'.
dependentComponents - Displays the dependent components of components in root project 'hello'. [incubating]
help - Displays a help message.
model - Displays the configuration model of root project 'hello'. [incubating]
projects - Displays the sub-projects of root project 'hello'.
properties - Displays the properties of root project 'hello'.
tasks - Displays the tasks runnable from root project 'hello'.

To see all tasks and more detail, run gradle tasks --all

To see more detail about a task, run gradle help --task <task>

BUILD SUCCESSFUL

Total time: 1.244 secs
```

まぁ、初期状態ではあまり意味ありませんが、どのようなタスクが実行可能か知りたい場合はこのコマンドを利用するということを頭の片隅に入れておくと良いでしょう。



## Javaコードのビルド
プロジェクトフォルダ直下に`build.gradle`ファイルを作成してください。

```gradle:build.gradle
apply plugin: 'java'
```

この一行はJavaプラグインを使ってこのプロジェクトをビルドすることを示しています。

再び`gradle tasks`を実行してください。プロジェクトのビルド、JavaDocの作成、テストの実行などの新しいタスクが追加されているのがわかると思います。

早速ビルドしてみましょう。

```
gradle build
```

`gradle build`はこれから頻繁に利用することになるでしょう。名前通り、ビルドを実施するコマンドです。数秒後、ビルド完了を示す"BUILD SUCCESSFUL"が表示されます。

ビルド結果を知るために`build`フォルダーを見てみましょう。幾つかのフォルダがあります。

### classes
Javaコードをコンパイルしたときの.classファイルを格納されています。今回はHelloWorld.class'と'Greeter.class'が作成されているはずです

### dependency-cache
依存モジュールの.jarが格納されます。現時点では空です。

### libs
作成されたライブラリ(大抵はjarもしくはwar)が格納されます。



## プロジェクトの実行
ビルドができたので実行してみましょう。`java`コマンドを利用して実行することも可能ですが、せっかくなのでgradle上から実行してみましょう。`build.gradle`を以下のように変更してください。

```gradle:build.gradle
apply plugin: 'java'
apply plugin: 'application'

mainClassName = 'hello.HelloWorld'
```

applicationプラグインを利用すると`gradle run`コマンドでアプリケーションを起動できるようになります。

```
>gradle run
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:run
Hello world!

BUILD SUCCESSFUL

Total time: 1.786 secs
```



## 依存性の解決
ここまでのサンプルは外部ライブラリに一切依存していませんのでgradleを利用する旨味はあまりありません。

そこで、"Hello World!"だけでなく現在日時も表示させるように変更してみましょう。Java標準ライブラリのJava日付時刻APIを使ってもよいのですが、説明のためにJoda Time librariesを使ってみます。

まず、HelloWorld.javaを次のように変更します。

```java:HelloWorld.java
package hello;

import org.joda.time.LocalTime;

public class HelloWorld {
  public static void main(String[] args) {
    LocalTime currentTime = new LocalTime();
    System.out.println("The current local time is: " + currentTime);

    Greeter greeter = new Greeter();
    System.out.println(greeter.sayHello());
  }
}
```

HelloWorldは現在時刻を取得して表示するのにJoda TimeのLocalTimeを利用しています。

ここで`gradle build`を実行してください。Joda Timeが解決できないので失敗します。

ではgradleに依存関係を解決してもらいましょう。`build.gradle`を変更してください。

```:build.gradle
apply plugin: 'java'
apply plugin: 'application'

mainClassName = 'hello.HelloWorld'

repositories {
    mavenCentral()
}

jar {
    baseName = 'gs-gradle'
    version =  '0.1.0'
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    compile "joda-time:joda-time:2.2"
    testCompile "junit:junit:4.12"
}
```
※sourceCompatibility のところはお使いのJDKのバージョンによしなに合わせてください

`repositories`ブロックで、リポジトリにMavenセントラルリポジトリを利用することを指定しています。

jarブロックではjarの名前を指定しています。このケースでは`gs-gradle-0.1.0.jar`となります。

`dependencies`ブロックで、Joda Timeへの依存性を宣言しています。具体的にはjoda-timeグループのjoda-timeライブラリ、バージョン2.2です。

`compile`はコンパイル時のみ有効な依存性であることを示しています。Mavenで言うところの`compile`スコープですね。その他の依存性タイプは

* `providedCompile` コンパイル時に必要だが、実行時はコンテナによって提供される依存性Servlet APIとかがそう。Mavenで言うところのprovided。
* `testCompile` コンパイルと時とテスト時に必要な依存性。ビルド成果物には含まれない。jUnitとか。Mavenで言うところのtest。


さて、再び`gradle build`を実行してください。gradleがJoda Timeへの依存をMaveセントラルリポジトリから解決してビルドが成功します。

プロジェクトも問題なく実行できるはずです。

```
>gradle run
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:run
The current local time is: 01:56:47.665
Hello world!

BUILD SUCCESSFUL

Total time: 1.308 secs
```



## Gradle Wapper
複数人からなるプロジェクトでこの手のツールを利用するとなると、他のメンバーのためにインストール手順書を整備したり、利用しているバージョンがまちまちだったりと色々面倒です。

そこで登場するのがGradle Wapperです。プロジェクトにGradle Wapperを導入するとWindows、Mac、Linuxなど環境を問わず誰でも同じバージョンのgradleでプロジェクトをビルドできます。

Gradle Wapperの導入方法は簡単で、プロジェクト直下で以下のコマンドを実行するだけです。

```
$ gradle wrapper --gradle-version 2.13
```

タスクが完了すると、いくつかのフォルダ、ディレクトリが作成されます。

```
└── <project folder>
    └── gradlew
    └── gradlew.bat
    └── gradle
        └── wrapper
            └── gradle-wrapper.jar
            └── gradle-wrapper.properties
```

これでGradle Wrapperの導入は完了です。利用方法も簡単で、gradleコマンドの代わりにプロジェクト直下の「gradlew(.bat)」を実行するだけです。

```
./gradlew build
```
※初回実行時は指定されたバージョンのgradleをダウンロードしてくるため若干時間がかかります

当然、別のコマンドも実行できます。

```
./gradlew run
```

`gradle init`で作成されたファイルをgitやsvnにコミットしておくだけで(そしてこのコマンドを叩いてねとreadmeに1行書いておくだけで)、だれもが難しいインストール作業なしにgradlew経由でgradleを利用できるというわけです。よく考えられていますね。



## 終わりに
これでGradleの雰囲気は大体つかめたと思います。この記事の内容だけで本格的なプロジェクトのビルドをすることはできません。しかし他のGradle関連の記事を読むハードルが低くなったはずです。必要に応じて情報を仕入れて、Gradleを使いこなしてください。

この記事がgradleを使い始めるきっかけになれば幸いです。