Gradle使い方メモ

Gradle を実際に触ってみたときのメモ。

基本的な話は vvakame さんの [Gradle入門](http://qiita.com/vvakame/items/83366fbfa47562fafbf4) を読んでいる前提。

より踏み込んだ話は [Gradle のタスク定義のあれこれ - Qiita](https://qiita.com/opengl-8080/items/0a192b62ee87d8ac7578) を参照。

#環境
##OS
Windows 7 64bit

##Java
1.7.0_40

##Gradle
1.9

#インストール
##Java
割愛

##Gradle
[ここ](http://www.gradle.org/downloads) を開いて `gradle-1.9-bin.zip` をクリックして zip をダウンロード。

zip を解凍したら、 `gradle-1.9\bin` にパスを通す。

コマンドプロンプトを開いて、 `gradle --version` を入力。

バージョンの情報が出力されたら OK。

###プロキシの設定
```properties:HTTPプロキシ
systemProp.http.proxyHost=<プロキシホスト名>
systemProp.http.proxyPort=<プロキシポート番号>
systemProp.http.proxyUser=<認証ユーザ名>
systemProp.http.proxyPassword=<パスワード>
```

```properties:HTTPSプロキシ
systemProp.https.proxyHost=<プロキシホスト名>
systemProp.https.proxyPort=<プロキシポート番号>
systemProp.https.proxyUser=<認証ユーザ名>
systemProp.https.proxyPassword=<パスワード>
```

上記設定を、以下のいずれかに記述する。

- プロジェクトのルートに配置した `gradle.properties`
- Gradle ホームフォルダ（`<ユーザのホームフォルダ>\.gradle`）に配置した `gradle.properties`

#簡単な Java プロジェクトを作る
コマンドラインから実行して `Hello Gradle!!` と出力するだけの簡単なプロジェクトを作る。

##build.gradle を作成する
プロジェクトのルートフォルダに、 `build.gradle` という名前のテキストファイルを作成する。

内容は以下。

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

##Java ソースコードを作成する
次に、 Java のソースコードを作成する。 `src\main\java` がデフォルトのソースフォルダの場所なので、その下に `sample\gradle` とフォルダを作って、 `GradleMain.java` を配置する。
`GradleMain.java` の内容は以下。

```java:GradleMain.java
package sample.gradle;

public class GradleMain {
    public static void main(String[] args) {
        System.out.println("Hello Gradle!!");
    }
}
```

フォルダ構成は以下のようになる。

```text:フォルダ構成
│  build.gradle
└─src
    └─main
        └─java
            └─sample
                └─gradle
                        GradleMain.java
```

###デフォルトのフォルダ構成
```text:
src
├─main
│  ├─java          : 製品の Java ソースコード
│  └─resources     : 製品のリソース
└─test
    ├─java          : テスト Java ソースコード
    └─resources     : テストのリソース
```

基本のフォルダ構成は Maven と同じ感じ。

##コンパイルする
コマンドプロンプトを開いて、 `build.gradle` のあるフォルダまで移動し、以下のコマンドを実行。

```text:Javaソースコードをコンパイルする
>gradle compileJava
```

すると、以下のように `build` フォルダの下に class ファイルが生成される。

```text:
│  build.gradle
│
├─build
│  └─classes
│      └─main
│          └─sample
│              └─gradle
│                      GradleMain.class
│  
└─src
    └─main
        └─java
            └─sample
                └─gradle
                        GradleMain.java
```

##実行する
```bat:コンパイルで生成されたclassファイルを普通に実行する
>java -cp build\classes\main sample.gradle.GradleMain
Hello Gradle!!
```

##生成したファイルを消す
```text:生成したファイルを消す
>gradle clean
```

`build` フォルダが削除される。

##タスクを複数指定する
```text:タスクを複数指定して実行する
>gradle clean compileJava
```

`clean` してから `compileJava` が実行される。

#コンパイルのオプションを色々設定する
##javac のオプション
`javac` コマンドで指定できるオプションは、 gradle では `build.gradle` で以下のように指定する。

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

compileJava {
    options.encoding = 'Shift_JIS'
}
```

`compileJava` の中で `options.<オプション名> = <値>` とすれば指定できる。上記例は、ソースコードのエンコーディングを指定している。

指定できるオプション名については [CompileOptions - Gradle DSL Version 1.11](http://gradle.monochromeroad.com/docs/dsl/org.gradle.api.tasks.compile.CompileOptions.html) を参照。

##ソース・class ファイルの JDK バージョンを指定する
`javac` の `-source`, `-target` に対応するオプションは以下のように指定する。

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

sourceCompatibility = '1.6' // -source
targetCompatibility = '1.6' // -target
```

#Gradle からアプリケーションを実行する
__アプリケーションプラグイン__ を使えば、 java コマンドを叩く代わりに Gradle 経由でアプリケーションを実行できる。

まず、 `build.gradle` を以下のように記述する。

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

mainClassName = 'sample.gradle.GradleMain'
```

`apply plugin: 'application'` でアプリケーションプラグインの使用を宣言し、 `mainClassName` に Main クラスの FQCN を指定する。
※アプリケーションプラグインを使えば java プラグインも利用できるようになるので、 java プラグインの宣言は不要。

あとは、以下のように `run` タスクを実行すれば OK。

```text:runタスクでアプリケーションを実行する
>gradle run
```

##run タスクで実行する Main クラスにコマンドライン引数を渡す

コマンドライン引数を渡したい場合、単純に `gradle run` の後に引数を書き連ねてもうまくいかない。

```text:runタスクの後ろに引数を書いてもダメ
>gradle run hoge fuga
```

`hoge` と `fuga` は、実行する Main クラスの main メソッドには渡されない。


**2020/10/24 修正 (@YujiSoftware さんから編集リクエストを頂きました)**

Gradle 4.9 から `--args` で引数を渡せるようになった。
[gradle run で実行する Java の引数は --args で指定できる (Gradle 4.9 から) - Qiita](https://qiita.com/niwasawa/items/533385a7c718a1dc39a3)

```text:runタスクにコマンドライン引数を渡す
>gradle run --args="hoge fuga"
```

<details><summary>4.9 より前で引数を渡す方法はこちら</summary><div>

[gradle-user - Command line arguments to application?](http://gradle.1045684.n5.nabble.com/Command-line-arguments-to-application-td3999977.html) ←同じ疑問を持った人がいて、どうも書き込みを見る限り普通にコマンドライン引数のノリで引数を渡すことはできず、以下のように `build.gradle` の記述を工夫する必要があるみたい。

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

mainClassName = 'sample.gradle.GradleMain'

run {
    if (project.hasProperty('args')) {    // "args" というプロパティが渡されていたら
        args project.args.split('\\s+')   // 空白文字で split して、 run タスクの args オプションにセットする
    }
}
```

実行するときは、以下のようにコマンドライン引数を渡す。

```text:runタスクにコマンドライン引数を渡す
>gradle run -Pargs="hoge fuga piyo"
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:run
{hoge,fuga,piyo}
```
</div></details>

#起動用スクリプトを自動生成する
同じくアプリケーションプラグインを使えば、作成したプログラムの起動用スクリプト（Windows と Unix 用）を自動生成できる。

起動スクリプトの生成は、 `startScripts` タスクを使用する。

```text:起動スクリプトを生成する
>gradle startScripts
```

タスクが完了すると、 `build\scripts` の下に起動用スクリプトファイルが出力されている。
デフォルトでは、 `build.gradle` のあるフォルダの名前でスクリプトファイルが出力される。 

スクリプトファイルの名前は `build.gradle` で以下のように指定できる。

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

mainClassName = 'sample.gradle.GradleMain'

startScripts {
    applicationName = 'hoge'
}
```

`applicationName` で指定できる。

他に指定できる値については [CreateStartScripts - Gradle DSL](http://gradle.monochromeroad.com/docs/dsl/org.gradle.api.tasks.application.CreateStartScripts.html) を参照。

#作成したアプリケーションを全部 zip にまとめて出力する
同じくアプリケーションプラグインを使えば、次のファイル類をまとめた zip ファイルを、タスク一発で生成できる。

- ソースをコンパイルして固めた jar
- 依存 jar ファイル一式
- 起動スクリプト

タスクの名前は `distZip`。

```text:全部入りのzipを生成する
>gradle distZip
```

タスクが完了すると `build\distributions` に zip ファイルが出力される。
解凍すると、以下のようなフォルダ構成になっている。

```text:
├─bin  : 起動スクリプトが配置されている
└─lib  : ソースをコンパイルして固めた jar 及び依存 jar ファイル
```

こちらも `build.gradle` で zip ファイルの名前を任意の値に変更できる。

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

mainClassName = 'sample.gradle.GradleMain'

distZip {
    baseName = 'HelloGradle'
}
```

`baseName` で指定する。

他に指定できる値については [Zip - Gradle DSL Version 1.8](http://gradle.monochromeroad.com/docs/dsl/org.gradle.api.tasks.bundling.Zip.html) を参照。

Maven より圧倒的に楽だ……。

ちなみに、 tar にしたい場合は `distTar` というタスクがある。

#ソース以外の任意のファイルをアプリケーションに含める
`src/main/java` および `src/main/resources` の下にあるファイルは、全て jar に固められてしまう。

そうではなく、 jar の外に出しておいて、かつアプリに含まれるようにしたいファイルが存在する場合は、 `src/dist` フォルダの下に配置する。

```text:フォルダ構成
project/
  `-src
    |-main/java/
    `-dist/
      |-hoge.txt
      `-fuga/
        `-piyo.txt
```

```text:
> gradle installApp
```

※`installApp` は ver 3.0 から削除され `installDist` に置き換わる予定なので注意。

```text:タスク実行後
project/
   `-build/install/
     |-hoge.txt
     |-fuga/
     |  `-piyo.txt
     |-bin/
     `-lib/
```

- `src/dist` の下に配置したファイルやフォルダが、そのままアプリケーションのルートに配置される。


#サードパーティのライブラリ（jar）を使用する
Apache Commons Lang を使った例。

##ローカルに jar ファイルがある場合
jar ファイルが `lib\commons-lang3-3.1.jar` にある場合、 `build.gradle` に以下のように記述する。

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

dependencies {
    compile files('lib/commons-lang3-3.1.jar')
}
```

`dependencies` 内の `files` で jar を指定している。

jar ファイルの指定は、次のようにもできる。

```groovy:ローカルのjarの指定方法
dependencies {
    // 個別ファイル複数指定
    compile files('lib/hoge.jar', 'lib/fuga.jar')
    // lib フォルダ直下の jar を全て指定
    compile fileTree(dir: 'lib', include: '*.jar')
    // lib フォルダ以下、サブフォルダも含めて全 jar ファイルを指定
    compile fileTree(dir: 'lib', include: '**/*.jar')
}
```

##Maven2 のセントラルリポジトリに存在する jar を指定する場合
Maven2 のセントラルリポジトリに存在する jar を指定する場合は、 `build.gradle` を以下のように記述する。

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

repositories {
    mavenCentral()
}

dependencies {
    compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.1'
}
```

`group` は `GroupId`、 `name` は `ArtifactId` を指定する。

リポジトリからダウンロードした jar ファイルは、 `%ユーザのホームフォルダ%\.gradle\caches` 以下に保存される。
ライブラリをキャッシュする場所を変更したい場合は、環境変数 `GRADLE_USER_HOME` に任意のフォルダのパスを設定すれば良い。

`dependencies` の部分は、以下のようにも書ける。

```groovy:
dependencies {
    compile 'org.apache.commons:commons-lang3:3.1'
}
```

##セントラルリポジトリ以外の Maven リポジトリを指定する
JSONIC 1.2.0 を Seasar が提供している Maven リポジトリから落としてみる。

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

mainClassName = 'sample.gradle.GradleMain'

repositories {
    maven {
        url "http://maven.seasar.org/maven2"
    }
}

dependencies {
    compile 'net.arnx.jsonic:jsonic:1.2.0'
}
```

`repositories` の中の `maven` の中の `url` に使用するリポジトリの URL を設定すれば、セントラルリポジトリ以外の Maven リポジトリも使用できるようになる。

```java:GradleMain.java
package sample.gradle;

import java.util.Map;
import java.util.HashMap;

import net.arnx.jsonic.JSON;

public class GradleMain {
    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<>();
        
        map.put("hoge", "HOGE");
        map.put("fuga", "FUGA");
        map.put("piyo", "PIYO");
        
        System.out.println(JSON.encode(map));
    }
}
```

```text:実行
>gradle clean run
:clean
:compileJava
:processResources UP-TO-DATE
:classes
:run
{"fuga":"FUGA","hoge":"HOGE","piyo":"PIYO"}

BUILD SUCCESSFUL
```

#Javadoc を生成する
```text:Javadocを生成するタスク
>gradle javadoc
```

`build\docs\javadoc` の下に Javadoc が生成される。

```java:GradleMain.java
package sample.gradle;

/**
 * メインクラスです。
 */
public class GradleMain {
    
    /**
     * メインメソッドです。
     * @param args コマンドライン引数
     */
    public static void main(String[] args) {
        System.out.println("Hello Gradle!!");
    }
}
```

__生成された Javadoc__

![gradleで生成したjavadoc.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/b58df33a-dc00-c6da-00ff-1bb62d5e5dca.jpeg)

#JUnit を実行する
JUnit4 + jMockit でテストコードを作成して実行してみる。

```java:src/main/java/sample/gradle/GradleMain.java
package sample.gradle;

public class GradleMain {
    public String method() {
        return "original";
    }
}
```

```java:src/test/java/sample/gradle/GradleMainTest.java
package sample.gradle;

import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;

import org.junit.Test;
import mockit.Mocked;
import mockit.Expectations;

public class GradleMainTest {
    
    @Mocked private GradleMain gradleMain;
    
    @Test
    public void test() {
        // setup
        new Expectations() {{
            gradleMain.method(); result = "stub";
        }};
        
        // exercise
        String actual = gradleMain.method();
        
        // verfiy
        assertThat(actual, is("stub"));
    }
}
```

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

repositories {
    mavenCentral()
}

dependencies {
    testCompile 'com.googlecode.jmockit:jmockit:1.4'
    testCompile 'junit:junit:4.11'
    testCompile 'org.hamcrest:hamcrest-library:1.3'
}
```

JUnit とかはテストでだけ使うので `testCompile` を指定している。

```text:テストを実行する
>gradle test
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:compileTestJava
:processTestResources UP-TO-DATE
:testClasses
:test

BUILD SUCCESSFUL
```

デフォルトは、全ての class ファイルがチェックされて、テストクラスを見つけたら全部実行される。

##テスト結果を HTML で確認する
`test` タスクが完了すると `build\reports\tests` の下にテスト結果が HTML で出力される。

![gradleが生成したテスト結果HTML.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/d47ab21f-e945-3757-b08d-53b7042777eb.jpeg)

__2013/12/22 修正__

デフォルトでは HTML は出力されず、 `reports.html.enabled = true` にする必要があると記述していたが、よく見たらデフォルトは出力されるようになっていたので、特に設定なしで HTML 出力は可能でした。すみません。

#War を作成する
__WAR プラグイン__ を使って war ファイルをビルドし、 Tomcat にデプロイしてみる。

サーブレットの実装は以下。

```java:src/main/java/sample/gradle/GradleServlet.java
package sample.gradle;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.annotation.WebServlet;

import java.io.IOException;

@WebServlet("/servlet")
public class GradleServlet extends HttpServlet {
    
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.getWriter().println("Hello Gradle War Plugin!!");
    }
}
```

デフォルトでは、 `src/main/webapp` 以下が、ウェブアプリケーションのソースフォルダになるので、その直下に `index.html` を配置する。
内容は以下。

```html:src/main/webapp/index.html
<html>
  <head>
    <title>index</title>
  </head>
  <body>
    <h1>Index</h1>
    <a href="servlet">GradleServlet</a>
  </body>
</html>
```

最後に、 `build.gradle` を以下のように記述する。

```groovy:build.gradle
apply plugin: 'war'

repositories {
    mavenCentral()
}

dependencies {
    providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
}

war {
    archiveName = 'hello.war'
}
```

先頭で WAR プラグインの利用を宣言。

servlet の実装は実行環境が提供してくれるので、war ファイル内に servlet の jar を含めないように `providedCompile` を指定している。
※`providedCompile` は WAR プラグインを使用している時にだけ利用可能。

`war` の `archiveName` は、生成する war ファイルの名前を指定している。これを指定しない場合は、デフォルトでは `build.gradle` の存在するフォルダの名前が war ファイルのベースに利用される。

war の生成は、 `war` タスクで実行できる。

```text:warタスクを実行してwarファイルを生成する
>gradle war
```

タスクが完了すると、 `build\libs` の下に war ファイルが生成される。
これを Tomcat に配備してブラウザからアクセスする。

![gradleで生成したサーブレットアプリケーション１.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/32fef8f1-a255-effa-afac-4ba35259901e.jpeg)

![gradleで生成したサーブレットアプリケーション２.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/9207e4f2-bddc-f969-25bd-ef85dcb98625.jpeg)

#マルチプロジェクトを作成する
##基本
```text:フォルダ構成
│  build.gradle
│  settings.gradle
│
├─hoge
│  └─src
│      └─main
│          └─java
│              └─sample
│                  └─gradle
│                          Hoge.java
│
├─fuga
│  └─src
│      └─main
│          └─java
│              └─sample
│                  └─gradle
│                          Fuga.java
│
└─src
    └─main
        └─java
            └─sample
                └─gradle
                        Main.java
```

ルートフォルダと `hoge` フォルダ、 `fuga` フォルダがそれぞれプロジェクトとなっている。

`hoge` と `fuga` がサブプロジェクトフォルダであることを明示するためには、ルートフォルダに `settings.gradle` を配置し、以下のように記述する。

```groovy:settings.gradle
include 'hoge', 'fuga'
```

`hoge` や `fuga` がもっと深い階層に存在する場合は、次のように `:` （コロン）繋ぎで記述する。

```groovy:settings.gradle
include 'subprojects:gui:hoge', 'subprojects:web:fuga'
```

区切り文字が `/` ではなく `:` なのには以下の理由がある。

> 以前Gradleでは、プロジェクトのパスセパレータとして「/」を使用していました。しかし、このセパレータ文字はdirectoryタスク(「ディレクトリの作成 」参照)が導入されたときに廃止されています。directoryタスクのタスク名に、「/」が含まれるためです。

[第56章 マルチプロジェクトのビルド - 56.5. プロジェクトとタスクのパス](http://gradle.monochromeroad.com/docs/userguide/multi_project_builds.html#sec:project_and_task_paths)

各プロジェクトの設定は、以下のようにルートフォルダの `build.gradle` にまとめて書くことができる。

```groovy:build.gradle
allprojects {
    apply plugin: 'java'
}
```

`allprojects` の中には、ルートのプロジェクトも含めた、全プロジェクトに共通の設定を記述することができる。

ルートフォルダでタスクを実行すれば、各プロジェクトごとにタスクがそれぞれ実行される。

```text:ルートフォルダでcompileJavaタスクを実行
>gradle compileJava

>tree
│  build.gradle
│  settings.gradle
│
├─hoge
│  ├─build
│  │  └─classes
│  │      └─main
│  │          └─sample
│  │              └─gradle
│  │                      Hoge.class
│  │  
│  └─src
│      └─main
│          └─java
│              └─sample
│                  └─gradle
│                          Hoge.java
│
├─fuga
│  ├─build
│  │  └─classes
│  │      └─main
│  │          └─sample
│  │              └─gradle
│  │                      Fuga.class
│  │  
│  └─src
│      └─main
│          └─java
│              └─sample
│                  └─gradle
│                          Fuga.java
│
├─build
│  └─classes
│      └─main
│          └─sample
│              └─gradle
│                      Main.class
│
└─src
    └─main
        └─java
            └─sample
                └─gradle
                        Main.java
```

##サブプロジェクトだけにまとめて設定をする
ルートプロジェクト以外の全サブプロジェクトに設定を適用させたい場合は、 `subprojects` に設定を記述する。

```groovy:build.gradle
allprojects {
    apply plugin: 'java'
}

subprojects {
    apply plugin: 'war'
}
```

上記設定で `war` タスクを実行すると、 `hoge` と `fuga` プロジェクトだけが war にアーカイブされる。

```text:subprojectsにだけWarプラグインを適用させた場合
>gradle war

>tree /f
│  build.gradle
│  settings.gradle
│
├─hoge
│  ├─build
│  │  └─libs
│  │          hoge.war
│  │
│  └─src
│      └─main
│          └─java
│              └─sample
│                  └─gradle
│                          Hoge.java
│
├─fuga
│  ├─build
│  │  └─libs
│  │          fuga.war
│  │
│  └─src
│      └─main
│          └─java
│              └─sample
│                  └─gradle
│                          Fuga.java
│
└─src
   └─main
       └─java
           └─sample
               └─gradle
                       Main.java
```

##サブプロジェクト毎に個別の設定をする
さらにプロジェクト毎に個別の設定をしたい場合は、以下のいずれかの方法が利用できる。

- `project(String)` メソッドを使用する
- サブプロジェクトのフォルダごとに `build.gradle` を配置する

###project(String) メソッドを使用する
```groovy:build.gradle
allprojects {
    apply plugin: 'application'
    mainClassName = 'sample.gradle.Main'
}

project(':hoge') {
    mainClassName = 'sample.gradle.Hoge'
}

project(':fuga') {
    mainClassName = 'sample.gradle.Fuga'
}
```

全プロジェクトにアプリケーションプラグインを適用し、 Main クラスとして `sample.gradle.Main` を設定している。
ただし、 Main クラスについては、 `project(String)` でプロジェクトごとに Main クラスを再定義している。

```text:runタスクの実行結果
>gradle run
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:run
Main
:fuga:compileJava UP-TO-DATE
:fuga:processResources UP-TO-DATE
:fuga:classes UP-TO-DATE
:fuga:run
Fuga
:hoge:compileJava UP-TO-DATE
:hoge:processResources UP-TO-DATE
:hoge:classes UP-TO-DATE
:hoge:run
Hoge

BUILD SUCCESSFUL
```

※各クラスは、自分のクラス名を出力する実装になっている（Hoge クラスは Hoge と出力する）。

###サブプロジェクトのフォルダごとに build.gradle を配置する
```text:フォルダ構成
│  build.gradle
│  settings.gradle
│
├─hoge
│  │  build.gradle
│  │
│  └─src
│      └─main
│          └─java
│              └─sample
│                  └─gradle
│                          Hoge.java
│
├─fuga
│  │  build.gradle
│  │
│  └─src
│      └─main
│          └─java
│              └─sample
│                  └─gradle
│                          Fuga.java
│
└─src
   └─main
       └─jaga
           └─sample
               └─gradle
                       Main.java
```

ルートの `build.gradle` の内容は以下。

```groovy:ルートのbuild.gradle
allprojects {
    apply plugin: 'application'
    mainClassName = 'sample.gradle.Main'
}
```

各サブプロジェクトに配置している `build.gradle` の内容は以下。

```groovy:hogeプロジェクトのbuild.gradle
mainClassName = 'sample.gradle.Hoge'
```

```groovy:fugaプロジェクトのbuild.gradle
mainClassName = 'sample.gradle.Fuga'
```

```text:runタスクの実行
>gradle run
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:run
Main
:fuga:compileJava UP-TO-DATE
:fuga:processResources UP-TO-DATE
:fuga:classes UP-TO-DATE
:fuga:run
Fuga
:hoge:compileJava UP-TO-DATE
:hoge:processResources UP-TO-DATE
:hoge:classes UP-TO-DATE
:hoge:run
Hoge

BUILD SUCCESSFUL
```

##特定のサブフォルダ以下のサブプロジェクトにだけ設定を適用する
```text:フォルダ構成
├─core
└─web
    ├─hoge
    └─fuga
```

ルートフォルダに `core` プロジェクトがあり、 `web` フォルダの下に `hoge` と `fuga` プロジェクトが存在する。

`web` フォルダ以下に存在するサブプロジェクトにだけ設定を適用したい場合は、次のように `build.gradle` を記述する。

```groovy:build.gradle
subprojects {
    apply plugin: 'java'
    
    repositories {
        mavenCentral()
    }
}

project(':web') {
    subprojects {
        apply plugin: 'war'
        
        dependencies {
            providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
        }
    }
}
```

`web` フォルダも実は __プロジェクトの１つ__ なので、その中でまた `subprojects` を使って設定を記述すれば、 `web` プロジェクトのサブプロジェクト全体に設定を適用させることができる。

##特定のプロジェクトだけでタスクを実行する
前述したとおり、ルートフォルダでタスクを実行すると全プロジェクトで指定したタスクが実行される。

特定のプロジェクトでだけタスクを実行したい場合は、以下のようにタスクを指定する。

```text:特定のプロジェクトだけでタスクを実行する
>gradle :hoge:compileJava
```

`:<プロジェクトへのパス>:<実行するタスク>`　と指定する。

複数指定する場合は以下のようにする。

```text:プロジェクト指定のタスクを複数実行する
>gradle :hoge:clean :hoge:compileJava
```

##プロジェクト間の依存関係を設定する

```text:フォルダ構成
│  build.gradle
│  settings.gradle
│
├─hoge
│  └─src
│      └─main
│          └─java
│              └─sample
│                  └─gradle
│                          Hoge.java
│
├─fuga
│  └─src
│      └─main
│          └─java
│              └─sample
│                  └─gradle
│                          Fuga.java
│
└─piyo
    └─src
        └─main
            └─java
                └─sample
                    └─gradle
                            Piyo.java
```

```java:Hoge.java
package sample.gradle;

public class Hoge {
    public static void main(String[] args) {
        Fuga.fuga("Hoge");
        Piyo.piyo("Hoge");
    }
}
```

```java:Fuga.java
package sample.gradle;

public class Fuga {
    public static void fuga(String caller) {
        System.out.println(caller + " calls Fuga#fuga() method.");
        Piyo.piyo("Fuga");
    }
}
```

```java:Piyo.java
package sample.gradle;

public class Piyo {
    public static void piyo(String caller) {
        System.out.println(caller + " calls Piyo#piyo() method.");
    }
}
```

```groovy:settings.gradle
include 'hoge', 'piyo', 'fuga'
```

- `hoge` プロジェクトは、 `fuga` と `piyo` の２つのプロジェクトに依存している
- `fuga` プロジェクトは、 `piyo` プロジェクトに依存している

上記のようにプロジェクト間に依存関係がある場合は、以下のように `build.gradle` を記述する。

```groovy:build.gradle
subprojects {
    apply plugin: 'application'
}

project(':hoge') {
    dependencies {
        compile project(':fuga'), project(':piyo')
    }
    mainClassName = 'sample.gradle.Hoge'
}

project(':fuga') {
    dependencies {
        compile project(':piyo')
    }
}
```

依存関係は各プロジェクト毎に `dependencies` 内で定義する。

※`settings.gradle` は、プロジェクトの依存関係に関係なく、好きな順番で記述して問題ない。

```text:Hoge#main(String[])を実行
>gradle :hoge:run
:piyo:compileJava
:piyo:processResources UP-TO-DATE
:piyo:classes
:piyo:jar
:fuga:compileJava
:fuga:processResources UP-TO-DATE
:fuga:classes
:fuga:jar
:hoge:compileJava
:hoge:processResources UP-TO-DATE
:hoge:classes
:hoge:run
Hoge calls Fuga#fuga() method.
Fuga calls Piyo#piyo() method.
Hoge calls Piyo#piyo() method.

BUILD SUCCESSFUL
```

#Eclipse で Gradle を利用する
Eclipse のバージョンは Juno を前提とする。

##プラグインのインストール
###Groovy-Eclipse for Juno
`build.gradle` とかの編集は groovy エディタがあった方がいいので、 `Groovy-Eclipse for Juno` を入れておく。

マーケットプレイスからプラグインをインストールする。

###Gradle Integration for Eclipse
マーケットプレイスから、 `Gradle Integration for Eclipse` をインストールする。

デフォルトだと `Spring Dashboard` とかをインストールしようとするけど、自分の環境？では必要なファイルが見つからない的なエラーが出てインストールできなかった。
`(optional)` って書いてるので、 `Spring Dashboard` と `Spring UAA Integration` はチェックを外してインストールした。

インストールが完了したら Eclipse を再起動。

このプラグインには 2013/12/07 現在 Gradle 1.5 がバンドルされているみたいで、デフォルトではその Gradle を使おうとするっぽい。

それは困るので、 Gradle の切り換えを行う。

[ウィンドウ]　→　[設定] と選択し、 [Gradle] を開く。
次に [Gradle Distribution] で [フォルダー]を選択し、既にインストールしている Gradle 1.9 のフォルダのパスを設定する。

![Gradleプラグインの設定.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/2a679edd-eea3-22e8-fd9e-5d40780c8d29.jpeg)

##Gradle プロジェクトを作る
[ファイル]　→　[新規]　→　[その他]　→　[Gradle]　→　[Gradle Project]　を選択。

[プロジェクト名] を入力して、 [Sample project] でプロジェクトのひな形を選択する。
とりあえず、 [Java Quickstart] を選択。

作成されたプロジェクトは以下。

![Gradleプラグインで生成されたプロジェクトの様子.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/316c6032-eb7e-917d-f3a0-a29a1d07de3c.jpeg)

なんか色々生成されてる。

##既存の Gradle プロジェクトを Eclipse にインポートする
```text:フォルダ構成
│  build.gradle
│
└─src
    └─main
        └─java
            └─sample
                └─gradle
                        GradleMain.java
```

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

mainClassName = 'sample.gradle.GradleMain'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.apache.commons:commons-lang3:3.1'
}
```

上記プロジェクトを Eclipse にインポートする。

Eclipse 上で [ファイル]　→　[インポート] を選択。
[Gradle]　→　[Gradle Project] を選択して次へ。

[ルート・フォルダー] に上記プロジェクトのフォルダパスを入力し、 [Build Model] をクリックする。
するとプロジェクトが読み込まれるので、 [完了] をクリックする。

![eclipseにインポート.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/be2f0c09-9228-abf8-8365-97957c744a1d.jpeg)

![既存のGradleプロジェクトをインポート.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/879921ef-4fd3-30c4-8296-9047acb62026.jpeg)

依存ライブラリは Eclipse の Gradle プラグインが管理してくれているようで、 `.classpath` ファイルは以下のようになっている。

```xml:.classpath
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
	<classpathentry kind="src" path="src/main/java"/>
	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
	<classpathentry exported="true" kind="con" path="org.springsource.ide.eclipse.gradle.classpathcontainer"/>
	<classpathentry kind="output" path="bin"/>
</classpath>
```

Gradle の Eclipse プラグインを使って生成した Eclipse プロジェクトだと、 `.classpath` に jar のフルパスが記述されてて開発者毎の環境に依存しないように工夫をしないといけないけど、この方法だと問題なさそう。

##Web アプリケーションのプロジェクトを WTP としてインポートする

こっち参照→「[Java - EclipseのGradleプラグイン使ってるときにprovidedCompileで指定しているjarもWEB-INF/libに配備されて困ったときの話 - Qiita [キータ]](http://qiita.com/opengl-8080/items/a00fa878fdfc9f35ae04)」

##Eclipse プロジェクト上での JRE を指定する
特に指定しない場合、ワークスペースのデフォルトの JRE を使うようになる。

任意の JRE を使用したい場合は、以下のように build.gradle を設定する。

```build.gradle（一部）
ext.jreName = 'jdk1.7.0_51'

eclipse {
    classpath {
        containers.clear()
        containers.add("org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/${jreName}")
    }
}
```

`jreName` は、 Eclipse に登録している「インストール済み JRE」の名前を指定する。

__参考__

- [java - Specifiy JRE Container with gradle eclipse plugin - Stack Overflow](http://stackoverflow.com/questions/11901737/specifiy-jre-container-with-gradle-eclipse-plugin)

#プロジェクトの依存関係を確認する
##dependencies タスクで確認する
```groovy:build.gradle
apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    compile 'commons-dbcp:commons-dbcp:1.4'
    compile 'com.google.inject:guice:3.0'
    testCompile 'junit:junit:4.11'
}
```

コンパイル時の依存ライブラリに Apache Commons DBCP と Google Guice を、テストコンパイル時の依存ライブラリに JUnit をとりあえず設定している。

この状態で `dependencies` タスクを実行すると、各タスク毎での依存ライブラリの様子が確認できる。

```text:
>gradle dependencies

（中略）

compile - Compile classpath for source set 'main'.
+--- commons-dbcp:commons-dbcp:1.4
|    \--- commons-pool:commons-pool:1.5.4
\--- com.google.inject:guice:3.0
     +--- javax.inject:javax.inject:1
     +--- aopalliance:aopalliance:1.0
     \--- org.sonatype.sisu.inject:cglib:2.2.1-v20090111
          \--- asm:asm:3.1

（中略）

testCompile - Compile classpath for source set 'test'.
+--- commons-dbcp:commons-dbcp:1.4
|    \--- commons-pool:commons-pool:1.5.4
+--- com.google.inject:guice:3.0
|    +--- javax.inject:javax.inject:1
|    +--- aopalliance:aopalliance:1.0
|    \--- org.sonatype.sisu.inject:cglib:2.2.1-v20090111
|         \--- asm:asm:3.1
\--- junit:junit:4.11
     \--- org.hamcrest:hamcrest-core:1.3

（中略）

BUILD SUCCESSFUL

Total time: 9.731 secs
```

##レポートプラグインを使って出力する
```groovy:build.gradle
apply plugin: 'java'
apply plugin: 'project-report'

repositories {
    mavenCentral()
}

dependencies {
    compile 'commons-dbcp:commons-dbcp:1.4'
    compile 'com.google.inject:guice:3.0'
    testCompile 'junit:junit:4.11'
}
```

`apply plugin: 'project-report'`  を追加すると、レポートプラグインが使える。

###dependencyReport タスク
```text:dependencyReportタスクの実行
>gradle dependencyReport
```

`build\reports\project` の下に `dependencies.txt` というファイルが出力される。
内容は、 `dependencies` タスクを実行したのと同じ。

###htmlDependencyReport タスク
```text:htmlDependencyReportタスクの実行
>gradle htmlDependencyReport
```

`build\reports\project\dependencies` の下に色々とファイルが出力されるので、 index.html を開くと HTML 形式のレポートが見れる。

![依存関係レポート_index.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/627af8b3-8c48-bd40-3dae-456e7bd74711.jpeg)

![依存関係レポート_project.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/4e0940d5-e66e-3ac0-dd37-4a04039c6a29.jpeg)

###htmlDependencyReport タスク（マルチプロジェクトの場合）
マルチプロジェクトで何も設定せずに `htmlDependencyReport` タスクを実行すると、サブプロジェクト毎に HTML レポートが出力されてしまう。
１つの HTML レポートに、すべてのサブプロジェクトの依存関係を出力したい場合は、次のように `build,gradle` を記述する。

```groovy:build.gradle
allprojects {
    apply plugin: 'java'
    apply plugin: 'project-report'
    
    repositories {
        mavenCentral()
    }

    dependencies {
        testCompile 'junit:junit:4.11'
    }
}

project(':hoge') {
    dependencies {
        compile 'commons-dbcp:commons-dbcp:1.4'
    }
}

project(':fuga') {
    dependencies {
        compile 'com.google.inject:guice:3.0'
    }
}

htmlDependencyReport {
    projects = project.allprojects
}
```

`htmlDependencyReport ` で `projects = project.allprojects` を指定すれば、以下のようにルートの HTML レポートにすべてのサブプロジェクトのレポートをまとめて出力できる。

![依存関係レポート_multi_index.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/de637e38-2561-ad0b-13bc-92751a8f0c72.jpeg)

![依存関係レポート_multi_hoge.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/6e079fa1-1ada-a79e-6bfc-1619e74da014.jpeg)

ただし、 `projects = project.allprojects` という指定方法は今後の Gradle のバージョンでは変更になる可能性があるらしい（2013/12/19 現在）。

> Note: This class is incubating and may change in a future version of Gradle.

[HtmlDependencyReportTask - Gradle DSL Version 1.11-20131203060736+0000](http://gradle.monochromeroad.com/docs/dsl/org.gradle.api.reporting.dependencies.HtmlDependencyReportTask.html)

#プロパティファイルを使う
`build.gradle` があるフォルダに `gradle.properties` という名前でプロパティファイルを配置しておけば、プロパティファイルに宣言したキーの名前で通常の変数と同じように使えるようになる。

```properties:gradle.properties
hoge=HOGE
```

```groovy:build.gradle
task sample << {
    println "hoge=${hoge}"
}
```

```text:実行
>gradle :sample
:sample
hoge=HOGE

BUILD SUCCESSFUL

Total time: 2.566 secs
```

でも、せっかく Groovy が使えるので、後述の `ConfigSlurper` を使った方がいい気がする。

#ConfigSlurper を使う
使い方自体は普通に [Groovy で使う](http://qiita.com/opengl-8080/items/b260e4f2df75901239c7#1-11) のと同じ。

唯一気をつけないと行けないのは、 __読み込んだコンフィグ情報をトップレベルの変数で宣言してはいけない__ 、という点。

```groovy:config.gradle
hoge {
    name = 'HOGE'
    fuga = [1, 2, 3]
    
    piyo {
        value = false
    }
}
```

```groovy:build.gradle
config = new ConfigSlurper().parse(new File('config.gradle').toURL())

task config << {
    println config
}
```

```text:実行結果
>gradle config
Creating properties on demand (a.k.a. dynamic properties) has been deprecated and is scheduled to be removed in Gradle 2.0. Please read http://gradle.org/docs/current/dsl/org.gradle.api.plugins.ExtraPropertiesExtension.html for information on the replacement for dynamic properties.
Deprecated dynamic property: "config" on "root project 'gradle'", value: "{hoge={name=HOGE, fuga...".
:config
{hoge={name=HOGE, fuga=[1, 2, 3], piyo={value=false}}}

BUILD SUCCESSFUL

Total time: 2.701 secs
```

タスクは成功するが、ガッツリ警告が表示される。

理由は以下。

> Gradle 1.0 milestone 9より、拡張プロパティを追加する際にはextを使用することが強く推奨されるようになっていますが、まだ強制はされません。 そのため存在しないプロパティに値を設定してもGradleの実行は失敗せず、警告が表示されます。 

- [13.4.2. 拡張プロパティ | 第13章 ビルドスクリプトの記述](http://gradle.monochromeroad.com/docs/userguide/writing_build_scripts.html#sec:extra_properties)

ということで、拡張プロパティをセットするときは `ext` に追加してあげる。

```build.gradle
ext.config = new ConfigSlurper().parse(new File('config.gradle').toURL())

task config << {
    println config
}
```

```text:実行結果
>gradle config
:config
{hoge={name=HOGE, fuga=[1, 2, 3], piyo={value=false}}}

BUILD SUCCESSFUL

Total time: 2.782 secs
```


#Ant タスクを実行する
```groovy:build.gradle
task ant << {
    ant.mkdir dir: 'dir'
    
    ant.echo message: 'ant echo', file: 'ant.txt'
    
    ant.copy(todir: 'dir') {
        fileset file: 'ant.txt'
    }
}
```

```bat:実行
>dir /b
build.gradle

>gradle :ant
:ant

BUILD SUCCESSFUL

Total time: 2.825 secs

>tree /f
│  ant.txt
│  build.gradle
│
└─dir
        ant.txt
```

- `ant` という名前の変数に ant のタスクと同じ名前のメソッドが定義されているので、それを使う。
- 属性は `<属性名>: <値>` という形式でタスクメソッドの引数に渡す。
- ネストされる要素は、タスクメソッドにクロージャーで渡す。

以下のようにもまとめて書くこともできる。

```groovy:
task ant << {
    ant {
        mkdir dir: 'dir'
        echo message: 'ant echo', file: 'ant.txt'
        copy(todir: 'dir') {
            fileset file: 'ant.txt'
        }
    }
}
```

#Gradle Wrapper を使う

Gradle Wrapper（ラッパー）を有効にすると、ビルドに必要な Gradle をコマンド１つで自動インストールできるようになる。

Gradle のバージョンを、開発者ごとに揃えることができる。

##Gradle Wrapper を有効にする
```groovy:build.gradle
task wrapper(type: Wrapper) {
    gradleVersion = '1.11'
}
```

`build.gradle` に、上記のようにタスクを追加する。

そして、このタスクを実行する。

```text:
> gradle wrapper
:wrapper

BUILD SUCCESSFUL

Total time: 4.854 secs
```

すると、以下のようにファイルが追加される。

```text:追加されるファイル
|-gradle/
|  `-wrapper/
|     |-gradle-wrapper.jar
|     `-gradle-wrapper.properties 
|-gradlew
`-gradlew.bat
```

これらのファイルは、全てバージョン管理システムに追加する。

##Gradle Wrapper を実行する

各開発者は、プロジェクトをバージョン管理システムからチェックアウトしてきたら、ルートにある `gradlew.bat` または `gradlew` を実行する。

すると、 Gradle が自動でインストールされる。

タスクは、 `> gradlew <タスク>` で実行することができる。

#参考
- [Gradle入門 - Qiita [キータ]](http://qiita.com/vvakame/items/83366fbfa47562fafbf4)
- [Gradle 日本語ドキュメント](http://gradle.monochromeroad.com/docs/)
- [Gradle DSL Version 1.9](http://www.gradle.org/docs/current/dsl/)
- [Gradle API 1.9](http://www.gradle.org/docs/current/javadoc/)
- [Gradle Goodness: Changing the Gradle User Home Directory - Messages from mrhaki](http://mrhaki.blogspot.jp/2010/09/gradle-goodness-changing-gradle-user.html)