Gradleで作るSpringBoot2.x系プロジェクト

# はじめに

毎回複数のサイトを回って記述しているので、自分向けにテンプレを置いておく。

* SpringBoot 2.2.2.RELEASE （+junit5)
* lombok 1.18.10
* checkstyle 8.28
* pmd 6.20.0
* spotbugs 3.1.12
* jacoco 0.8.5

(2020.01.10時点での各最新バージョン）

# 環境

Gradle5.0を使用していたのでアップデート。

```sh
$ brew upgrade gradle
```

アップデート後、バージョンの確認
（2020.01.10時点では6.0.1）

```sh
$ gradle --version
------------------------------------------------------------
Gradle 6.0.1
------------------------------------------------------------

Build time:   2019-11-18 20:25:01 UTC
Revision:     fad121066a68c4701acd362daf4287a7c309a0f5

Kotlin:       1.3.50
Groovy:       2.5.8
Ant:          Apache Ant(TM) version 1.10.7 compiled on September 1 2019
JVM:          1.8.0_192 (Oracle Corporation 25.192-b12)
OS:           Mac OS X 10.15.2 x86_64

```

# プロジェクトの作成

適当なディレクトリを作成しGradleプロジェクトを作成。

```sh
$ mkdir hoge
$ cd hoge
$ gradle init
```
質問は以下を入力。

> 1: basic
> 1: Groovy
> Project name: (任意)

# build.gradleの作成

結果このようなファイルになった。
各種ツールのバージョン指定は別途gradle.propertiesに宣言。

plugins{}内で変数を使いたいためにGradleの更新をした。

```gradle:build.gradle

plugins {
  id "java"
  id "idea"
  id "eclipse"
  id "checkstyle"
  id "pmd"
  id "jacoco"
  id "com.github.spotbugs" version "3.0.0"
  id "org.springframework.boot" version "${springBootVersion}"
  id "io.spring.dependency-management" version "${dependencyManagementVersion}"
  id "io.franzbecker.gradle-lombok" version "3.2.0"
}

repositories {
  jcenter()
  mavenCentral()
}

dependencies {
  implementation "org.springframework.boot:spring-boot-starter-web"
  implementation "org.springframework.boot:spring-boot-devtools"

  testImplementation("org.springframework.boot:spring-boot-starter-test") {
    exclude(group: 'org.junit.vintage')
  }
}

checkstyle {
  toolVersion "${checkstyleVersion}"
  ignoreFailures true
  configFile file("${rootDir}/config/checkstyle/google_checks.xml")
}

tasks.withType(Checkstyle) {
  reports {
    xml.enabled false
    html.enabled true
  }
}

pmd {
  toolVersion "${pmdVersion}"
  ignoreFailures true
  ruleSets = [
    'java-basic',
    'java-braces',
  ]
}

spotbugs {
  toolVersion "${spotbugsVersion}"
  ignoreFailures true
  reportsDir file("${buildDir}/reports/spotbugs")
}

tasks.withType(com.github.spotbugs.SpotBugsTask) {
  reports {
    xml.enabled false
    html.enabled true
  }
}

jacoco {
  toolVersion "${jacocoVersion}"
}

jacocoTestReport {
  reports {
    xml.enabled false
    csv.enabled false
    html.destination file("${buildDir}/reports/jacoco")
  }
}

lombok {
  version "${lombokVersion}"
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

def defaultEncoding = 'UTF-8'
tasks.withType(AbstractCompile)*.options*.encoding = defaultEncoding
tasks.withType(GroovyCompile)*.groovyOptions*.encoding = defaultEncoding

idea.module.inheritOutputDirs = true

```

## 簡単な説明

### SpringBoot

公式にあるとおりSpringBoot本体とdependency-managementを使用。
合わせてjunit4ではなくjunit5を使うように変更。（junit4を除外）
あとdevtools。

```gradle
plugins {
  id "java"
  id "org.springframework.boot" version "${springBootVersion}"
  id "io.spring.dependency-management" version "${dependencyManagementVersion}"
}

dependencies {
  implementation "org.springframework.boot:spring-boot-starter-web"
  implementation "org.springframework.boot:spring-boot-devtools"

  testImplementation("org.springframework.boot:spring-boot-starter-test") {
    exclude(group: 'org.junit.vintage')
  }
}
```

### checkstyle/pmd/spotbugs/jacoco

ｐｍｄのruleSetsのわかりにくさはなんとかならないのか。
公式ドキュメントみてもいまいち・・・。

* checkstyle
    * [google_checks.xml](https://github.com/checkstyle/checkstyle/blob/master/src/main/resources/google_checks.xml)を採用
        * 定義とtoolversionを揃えること
    * 警告がでても処理継続
    * htmlレポートの作成
* pmd
    * [ruleSets](https://pmd.github.io/pmd-6.20.0/pmd_rules_java.html)は仮
        * 「java-{ルール名}」で定義可能？ [リソース一覧](https://github.com/pmd/pmd/tree/master/pmd-java/src/main/resources/rulesets/java)
    * 警告がでても処理継続
* spotbugs
    * 出力先を他のレポートと合わせる
    * 警告がでても処理継続
    * htmlレポートの作成
* jacoco
    * htmlレポートの作成

### JavaConfig

javacの設定とエンコード指定。
intelliJを使っているのでIDEのビルド出力先を変更。

```gradle
sourceCompatibility = 1.8
targetCompatibility = 1.8

def defaultEncoding = 'UTF-8'
tasks.withType(AbstractCompile)*.options*.encoding = defaultEncoding
tasks.withType(GroovyCompile)*.groovyOptions*.encoding = defaultEncoding

idea.module.inheritOutputDirs = true
```