触って覚えるGradle

# Gradleって何が嬉しいの？
　これはDockerを人に勧める時にも同じことを思ったんだけど、正直口で言って良さを伝えるのは難しい。
　gradleにしてもDockerにしてもどの部分に魅力を感じるかは人それぞれってのもあるし、便利を伝えてみても実感として伴わない。聞いてる方は「なるほど、便利そうだね」という位置に留まる。
　そもそも「マジかよ！　じゃあ早速使ってみるよ！」って人は、自分でガシガシ触ってみて、どういうものか掴もうとするから説明の必要がない。
　自分で「とりあえず使う」が出来るればいい。しかしそれをやれるスキルに至っていないという事が多々ある。とりあえず……何をすればいいんだろう？

　よってこの記事のタグには「研修」をつけている。
　世界に数多ある有用なツールを自分で戦力化できるようになるためには、いくつかのツールを戦力化するという実績を積むのが一番の近道だろう。

　この記事は、gradleを自分の戦力として扱うための手助けをする。
　何が嬉しいか分かった時、その時にはすでに武器を一つ手に入れている。

# gradleのインストール
　この記事では開発マシンのOSはWindowsを想定している。またIDEはEclipseだ。よっていくらかそれに特化した手順や記述が出てくる。
　インストールがまだの人は、是非ともパッケージマネージャを使ってみよう。
　MacではHomebrewなどあるが、Windowsを想定しているためscoopでの手順を記す。
　まずは管理者権限でパワーシェルを立ち上げよう。

## スクリプト実行を許可する
```
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force
```
## scoopをインストールする
```
iex (new-object net.webclient).downloadstring('https://get.scoop.sh')
```
## gradleをインストールする
```
scoop install gradle
```

　プロキシを通る場合はもう少し手順が増えるが（PowerShellでプロキシを潜る方法は拙稿[Docker for Windowのインストールから利用までの(ほぼ)CUI手順](https://qiita.com/Teramonte4/items/9d18f15cb470cb3e647f)にあるので参照願いたい）コマンド３行コピペすればインストールできるのだから、便利な時代になったものだ。
　scoopというパッケージマネージャは入れておいて損はない。この機会に入れておくと後々幸せかも知れない。

# プロジェクトのフォルダを作る
　早速gradleを使ってみよう。なにはともあれプロジェクトのフォルダを作る。
　プロジェクト名でフォルダを作る。今回は「Yebisu」とした。勿論、今飲んでいるビールである。作ったらエクスプローラでYebisuフォルダの中に入り、**Shift+右クリック**でメニューを出そう。**PowerShell ウィンドウをここで開く**というメニューがあるはずだ。それを選択してPowerShellを起動しよう。

# gradleプロジェクトの作成
```
gradle init
```
　これを実行するといくつかのアンケートがある。今回はjava-appicationという事で以下のように入力してみよう。

- Select type of project to generate -> 2 (application)
- Select implementation language -> 3 (Java)
- Select build script DSL -> 1 (Groovy)
- Select test framework -> 4 (JUnit Jupiter)
- Project name -> そのままエンター(default)
- Source package -> 任意 (今回はyebisuとした）

```
PS D:\git-private\Yebisu> gradle init
Starting a Gradle Daemon, 1 busy Daemon could not be reused, use --status for details

Select type of project to generate:
  1: basic
  2: application
  3: library
  4: Gradle plugin
Enter selection (default: basic) [1..4] 2

Select implementation language:
  1: C++
  2: Groovy
  3: Java
  4: Kotlin
  5: Swift
Enter selection (default: Java) [1..5] 3

Select build script DSL:
  1: Groovy
  2: Kotlin
Enter selection (default: Groovy) [1..2] 1

Select test framework:
  1: JUnit 4
  2: TestNG
  3: Spock
  4: JUnit Jupiter
Enter selection (default: JUnit 4) [1..4] 4

Project name (default: Yebisu):

Source package (default: Yebisu): yebisu


> Task :init
Get more help with your project: https://docs.gradle.org/6.1/userguide/tutorial_java_projects.html

BUILD SUCCESSFUL in 1m 28s
2 actionable tasks: 2 executed
```

これでプロジェクトが作成できた。
このPowerShellウィンドウは閉じずに置いといて欲しい。

# Eclipseプロジェクトにする
　今回のIDEはEclipseである。EclipseプロジェクトにするためにはEclipseプラグインを使う。この辺はお決まりの手順である。
　すでにフォルダの中にはbuild.gradleがあるはずなので、テキストエディタで開いてみよう。
　pluginsにeclipseを追加する。**id 'application'**の次行に**id 'eclipse'**を追記すればよい。尚、私は分かり切ったコメントが嫌いなので、コメントはとっとと消してしまっている。

```build.gradle
plugins {
    id 'java'
    id 'application'
    id 'eclipse'
}

// 必要に応じてエンコーディングを指定
compileJava.options.encoding = 'UTF-8'
compileTestJava.options.encoding = 'UTF-8'

repositories {
    jcenter()
}

dependencies {
    implementation 'com.google.guava:guava:28.1-jre'
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.5.2'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.5.2'
}

application {
    mainClassName = 'yebisu.App'
}

test {
    useJUnitPlatform()
}
```

編集が終わったらPowerShellで以下のコマンドを走らせよう。

```
./gradlew eclipse
```

これで**.project** **.classpath**ファイル等が作られ、Eclipseに取り込める形となる。

# Eclipseにインポートする
メニューバーの**[File]** -> **Import**でインポートウィザードを出そう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117698/b5097929-cc6b-cb2b-e03a-f23ac41f3629.png)

**Existing Projects into Workspace**を選択して**Next**だ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117698/4a4a8e5b-8612-4d28-12b6-7e06337180ac.png)

**Select root directory**にさっき作ったプロジェクトのパスを入力する。
**Projects**でチェックが入っている事を確認して**Finish**ボタンを押そう。

App.javaというソースファイルがあり、そこにmainが出来ているはずである。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117698/334fb1c7-1b2f-7d84-18d1-de5dd64400d3.png)

- src/main/java 本体のソースファイル
- src/main/resources 本体のリソースファイル
- src/test/java 単体テストのソースファイル
- src/test/resources 単体テストのリソースファイル

# ライブラリを追加する
　**Apache Commons IO**のFilenameUtilsが使いたい！
　こういう場合どうしていただろうか？　もしかしたらCommons IOのjarをダウンロードしてプロジェクトの依存関係に追加していたかも知れない。
　gradleではそんな事は必要ない。これを使うための一行を見つけてくればいいのだ。
　検索ワードは、**FilenameUtils maven**としてググってみよう。
　**MVNrepository**というサイトを見つけられるはずだ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117698/747f4a82-9f27-3fd3-4882-79d3f29542d8.png)

　**Gradle**タブを選択すると、その下のテキストボックスに呪文が出てくる。この呪文をコピーしよう。
　これをbuild.gradleのdependenciesに貼り付ける。本当はcompileはimplementationにした方がいいのだが、今回はこのままベタリと貼り付けよう。

```build.gradle
dependencies {
    implementation 'com.google.guava:guava:28.1-jre'

	// https://mvnrepository.com/artifact/org.apache.commons/commons-io
	compile group: 'org.apache.commons', name: 'commons-io', version: '1.3.2'

    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.5.2'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.5.2'
}
```

build.gradleをセーブしたら、PowerShellに戻って以下のコマンドだ。

```
./gradlew eclipse
```

# これでFilenameUtilsはもう使える
　Eclipseに戻って、プロジェクトをF5で更新しよう。プロジェクトを右クリックしてリフレッシュでも構わない。
　**Referenced Libraries**のツリーを開いてみると、commmons-io-1.3.2.jarがある。
　試しに使ってみよう。

　App.javaのmainに以下の行を書くと・・・

```
System.out.println(FilenameUtils.getExtension("c:/foo/bar/hoge.fuga"));
```
　**Ctrl+Shift+'O'**で**import org.apache.commons.io.FilenameUtils;**が自動挿入されると思う。
　早速実行してみよう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117698/239c9ae3-2ccd-3bee-dae4-5939bfac4adf.png)

画像ではEclipseから実行したが、gradleから実行する事もできる。

```
./gradlew run
```

```powershell
> Task :run
fuga
Hello world.

BUILD SUCCESSFUL in 2s
2 actionable tasks: 1 executed, 1 up-to-date
```

# 一応正しく書き直す
compileは実は古い書き方だ。group, name, versionの記述ももっとシンプルにできる。

```build.gralde
compile group: 'org.apache.commons', name: 'commons-io', version: '1.3.2'
　↓
implementation 'org.apache.commons:commons-io:1.3.2'
```

また複数のimplementationはまとめて書くことができる。

```
    implementation('com.google.guava:guava:28.1-jre'
                  ,'org.apache.commons:commons-io:1.3.2')
```

# Lombokを追加する
ほとんどのライブラリは上のやり方で取り込めるのだが、アノテーションプロセッサはやり方が変わってくる。私はLombokがないと知らぬ間に築いてた自分らしさの檻の中でもがいてしまうため無条件でdependenciesに以下を追加する。

```build.gradle
	compileOnly 'org.projectlombok:lombok:1.18.4'
	annotationProcessor "org.projectlombok:lombok:1.18.4"
	testCompileOnly 'org.projectlombok:lombok:1.18.4'
	testAnnotationProcessor "org.projectlombok:lombok:1.18.4"
```

もしLombokのインストールが済んでいない場合は、インストールが必要だ。説明はLombokの使い方を説明してあるサイトに委ねるが、簡単にいうとLombok.jarをダブルクリックで起動させてインストールすればよい。eclipse.iniに記述されるため一回インストールしとけば、プロジェクトでの使用は上記の4行を頭空っぽにしてベトンと貼り付ければ良い。

# Jarを作る
ここまででも、世界にあるライブラリが簡単に取り込めて使える、しかも依存関係ごと取り込んでくれるという素敵な感じが伝わったと思う。伝わっていて欲しい。伝わっているといいな。

springBootを使うようになるとgradleをより崇拝するようになるのだが、今回の記事はJarを作って最後とする。

実はいま時点でもJarは作れてしまう。

```
./gradlew jar
```

これだけだ。
**./build/libs**フォルダの下にjarが出来ていると思う。
これはただjarにしただけなので-jarでは動かないし、manifestにも何も書かれていない。

そして今回は一つのjarファイルに依存関係を全部ぶちこみ、それだけで動作可能な実行可能jarにしてみよう。（普段はやんないんだけどね）
build.gradleに以下の記述を追加する。

```build.gradle
jar {
    manifest {
        attributes('Implementation-Title': 'Yebisu'
                 , 'Implementation-Version': 1.0 
                 , 'Main-Class': 'yebisu.App')
    }
    from configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
```

こうして```./gradlew jar```でjarを生成し、以下のコマンドを実行するとちゃんと動作すると思う。

```
java -jar .\build\libs\Yebisu.jar
```

MANIFEST.MFにバージョンやタイトルもちゃんと入っている。

```MANIFEST.MF
Manifest-Version: 1.0
Implementation-Title: Yebisu
Implementation-Version: 1.0
Main-Class: yebisu.App
```

# 最後に
この次のステップは、単体テストを記述する、Jacocoでカバレッジを取るといったところになるだろうか。build.gradleはGroovyという言語で書かれている。（Kotlinでも書ける）

だからといってGroovyやKotlinの読み書きが必須という事はない。もちろんあるに越したことはないが。しかしまあ、gradleでやりたい事が出来たならば、googleを使って世界に問いかけてみれば、大体の答えはそこにある。そういうものだ。**だってgraldeは新しい技術ではないもの。**

世界にはまだまだ便利なものが山程ある。
その多くは学習コストによって嫌われていると私は思っている。しかし世の中で多く使われているライブラリやツールは、学習コストを払うに見合うものが殆どだ。

今の方法でも出来ているから問題ないという考えは悪癖である。
是非とも積極的に、武器を探し、手に取り、自分のものとして戦力化して欲しい。そうやって培った生産力の差が、五年後十年後には莫大なものになる。
　
　
　
　
　かも知れない。