かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

Gradle で Multi-project を作成する ( その4 )( lib+webappx2編、Multi-project の設定ファイルと Spring Boot ベースの Web アプリケーション(メイン)のプロジェクトを作成する )

概要

記事一覧はこちらです。

Gradle で Multi-project を作成する ( その3 )( lib+cmdapp編、Spring Boot ベースのコマンドラインアプリケーションのプロジェクトを作成する ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • Gradle で Spring を使用しないライブラリ+Spring Boot ベースの Web アプリケーション x 2(メインとスタブ)の Multi-project を作成します。
    • 2回に分けて書きます。
    • Spring を使用しないライブラリは lib+cmdapp 編で作成した sample-lib プロジェクトをそのままコピーして利用します。
    • Spring Boot ベースの Web アプリケーション x 2(メインとスタブ)は新規に作成します。

参照したサイト・書籍

目次

  1. 方針
  2. gradle-multiprj-lib-webapp2 ディレクトリを作成する
  3. gradle-multiprj-lib-cmdapp プロジェクトからファイルをコピーする
  4. IntelliJ IDEA で gradle-multiprj-lib-webapp2 プロジェクトをオープンする
  5. clean タスク実行 → Rebuild Project 実行 → build タスク実行を行う
  6. Spring Boot ベースの Web アプリケーション(メイン)のプロジェクトを作成する
    1. IntelliJ IDEA で sample-webapp プロジェクトを作成する
    2. sample-webapp プロジェクトから不要なファイルを削除する
    3. settings.gradle に sample-webapp プロジェクトの include 文を追加する
    4. gradle-multiprj-lib-webapp2 プロジェクトの build.gradle にサブプロジェクトの Web アプリケーション共通の設定を追加し、sample-webapp プロジェクトの build.gradle を削除する
    5. SampleController クラスを新規作成して仮実装する
  7. 続く。。。

手順

方針

gradle-multiprj-lib-webapp2
├ sample-lib    <-- Spring を使用しないライブラリの Project
├ sample-stubapp    <-- Spring Boot ベースの Web アプリケーション(スタブ)の Project
└ sample-webapp    <-- Spring Boot ベースの Web アプリケーション(メイン)の Project
  • Spring Boot ベースの Web アプリケーション x 2(メインとスタブ)の Project では Profile は作成しません。
  • テスティングフレームワークは全ての Project で JUnit 5 と Spock を使用できるようにします。
  • checkstyle, spotbugs, pmd, error-prone は今回は導入しません。
  • Spring Boot ベースの Web アプリケーション(メイン)では 8080番ポートを、Spring Boot ベースの Web アプリケーション(スタブ)では 9080番ポートを使用します。
  • Web アプリケーションが2つあるので、
    • build.gradle の共通の設定は各サブプロジェクトの build.gradle ではなく gradle-multiprj-lib-webapp2 の build.gradle に記述します。
    • IntelliJ IDEA の Run Dashboard から Spring Boot ベースの Web アプリケーション x 2(メインとスタブ)を起動できるようにします。

gradle-multiprj-lib-webapp2 ディレクトリを作成する

ksby/ksbysample-boot-miscellaneous の repository を checkout している D:\project-springboot\ksbysample-boot-miscellaneous の下に gradle-multiprj-lib-webapp2 ディレクトリを作成します。

f:id:ksby:20190421091351p:plain

gradle-multiprj-lib-cmdapp プロジェクトからファイルをコピーする

D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-cmdapp\ から以下のファイルをコピーします。

settings.gradle は以下の内容に変更します。

rootProject.name = 'gradle-multiprj-lib-webapp2'
include 'sample-lib'

コピー後、コマンドプロンプトから gradlew wrapper コマンドを実行します。

f:id:ksby:20190421092716p:plain

D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-webapp2\ の下には以下のディレクトリ・ファイルがある状態になります。

f:id:ksby:20190421092840p:plain

IntelliJ IDEA で gradle-multiprj-lib-webapp2 プロジェクトをオープンする

gradle-multiprj-lib-webapp2 プロジェクトをオープンします。

f:id:ksby:20190421093232p:plain

オープン後 Project Tool Window は以下のようになり、

f:id:ksby:20190421093449p:plain

Gradle Tool Window は以下のようになります。

f:id:ksby:20190421094634p:plain

gradle-multiprj-lib-cmdapp プロジェクトの時は gradle-multiprj-lib-cmdapp(root) と表示されていたのですが、今回は Tasks と表示されていますね。。。 Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新しても変わりませんでした。

gradle-multiprj-lib-cmdapp プロジェクトをオープンしてみるとこちらも Tasks に変わっていました。どうも IntelliJ IDEA を 2019.1 にバージョンアップしたのが原因のようです。

f:id:ksby:20190421095118p:plain

※Project SDK は default の設定で JDK 11 を使うように設定済なので、今回は変更の手順は書きません。

clean タスク実行 → Rebuild Project 実行 → build タスク実行を行う

ここまでで build タスクが正常に終了するか確認します。clean タスク実行 → Rebuild Project 実行 → build タスク実行を行うと、BUILD SUCCESSFUL のメッセージが出力されました。

f:id:ksby:20190421095554p:plain

sample-lib/build/libs の下に sample-lib-1.0.0-RELEASE.jar も生成されており、問題ないようです。

f:id:ksby:20190421100521p:plain

Spring Boot ベースの Web アプリケーション(メイン)のプロジェクトを作成する

IntelliJ IDEA で sample-webapp プロジェクトを作成する

IntelliJ IDEA から Spring Initializr を利用して Spring Boot ベースの Web アプリケーションのプロジェクトを作成します。

f:id:ksby:20190421105255p:plain f:id:ksby:20190421154449p:plain f:id:ksby:20190421105540p:plain f:id:ksby:20190421105611p:plain ※DevTools と Web の2つをチェックします。

f:id:ksby:20190421105709p:plain f:id:ksby:20190421105820p:plain

作成後 IntelliJ IDEA のウィンドウが開きますが、何もせずに閉じます。

sample-webapp プロジェクトから不要なファイルを削除する

D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-webapp2\sample-webapp\ の下には以下のディレクトリ・ファイルがありますが、

f:id:ksby:20190421111036p:plain

src ディレクトリと build.gradle 以外を削除します。削除すると以下の状態になります。

f:id:ksby:20190421111404p:plain

settings.gradle に sample-webapp プロジェクトの include 文を追加する

D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-webapp2 の下の settings.gradle に include 'sample-webapp' を追加します。

rootProject.name = 'gradle-multiprj-lib-webapp2'
include 'sample-lib'
include 'sample-webapp'

追加後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新すると sample-webappIntelliJ IDEA 209.1 から左側に : が付かなくなったようです)が追加されます。

f:id:ksby:20190421150647p:plain

また sample-webapp 起動用の Run/Debug Configuration も自動で追加されます。

f:id:ksby:20190421162742p:plain

gradle-multiprj-lib-webapp2 プロジェクトの build.gradle にサブプロジェクトの Web アプリケーション共通の設定を追加し、sample-webapp プロジェクトの build.gradle を削除する

gradle-multiprj-lib-webapp2 プロジェクトの build.gradle を以下のように変更します。今回は Spring Boot ベースの Web アプリケーションを2つ作成するので、共通の設定は各サブプロジェクトの build.gradle に記述するのではなく gradle-multiprj-lib-webapp2 の build.gradle に記述するようにします。

buildscript {
    repositories {
        mavenCentral()
        maven { url "https://plugins.gradle.org/m2/" }
        maven { url "https://repo.spring.io/release/" }
    }
    dependencies {
        classpath "io.spring.gradle:dependency-management-plugin:1.0.7.RELEASE"
        classpath "org.springframework.boot:spring-boot-gradle-plugin:2.1.4.RELEASE"
    }
}

allprojects {
    repositories {
        mavenCentral()
    }
}

subprojects {
    group "ksby.ksbysample-boot-miscellaneous"
    version "1.0.0-RELEASE"

    apply plugin: "java"
    apply plugin: "groovy"
    apply plugin: "io.spring.dependency-management"

    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11

    [compileJava, compileTestGroovy, compileTestJava]*.options*.encoding = "UTF-8"
    [compileJava, compileTestGroovy, compileTestJava]*.options*.compilerArgs = ["-Xlint:all,-options,-processing,-path"]

    dependencyManagement {
        imports {
            mavenBom("org.junit:junit-bom:5.4.2")
        }
    }

    dependencies {
        def assertjVersion = "3.12.2"
        def spockVersion = "1.3-groovy-2.5"

        // for Spock
        testImplementation("org.spockframework:spock-core:${spockVersion}")
        testImplementation("org.spockframework:spock-spring:${spockVersion}")

        // for JUnit 5 + AssertJ
        // junit-jupiter で junit-jupiter-api, junit-jupiter-params, junit-jupiter-engine の3つが依存関係に追加される
        testCompile("org.junit.jupiter:junit-jupiter")
        testRuntime("org.junit.platform:junit-platform-launcher")
        testImplementation("org.assertj:assertj-core:${assertjVersion}")
    }

    def jvmArgsDefault = [
            "-ea",
            "-Dfile.encoding=UTF-8",
            "-Dsun.nio.cs.map=x-windows-iso2022jp/ISO-2022-JP"
    ]
    def jvmArgsAddOpens = [
            "--add-opens=java.base/java.io=ALL-UNNAMED",
            "--add-opens=java.base/java.lang=ALL-UNNAMED",
            "--add-opens=java.base/java.lang.invoke=ALL-UNNAMED",
            "--add-opens=java.base/java.lang.ref=ALL-UNNAMED",
            "--add-opens=java.base/java.lang.reflect=ALL-UNNAMED",
            "--add-opens=java.base/java.net=ALL-UNNAMED",
            "--add-opens=java.base/java.security=ALL-UNNAMED",
            "--add-opens=java.base/java.util=ALL-UNNAMED"
    ]
    def printTestCount = { desc, result ->
        if (!desc.parent) { // will match the outermost suite
            println "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} successes, ${result.failedTestCount} failures, ${result.skippedTestCount} skipped)"
        }
    }

    task testJUnit4AndSpock(type: Test) {
        jvmArgs = jvmArgsDefault +
                jvmArgsAddOpens

        testLogging {
            afterSuite printTestCount
        }
    }
    test.dependsOn testJUnit4AndSpock
    test {
        jvmArgs = jvmArgsDefault +
                jvmArgsAddOpens

        // for JUnit 5
        useJUnitPlatform()

        testLogging {
            afterSuite printTestCount
        }
    }
}

configure(subprojects.findAll { it.name ==~ /^(sample-webapp)$/ }) {
    apply plugin: "org.springframework.boot"

    dependencyManagement {
        imports {
            mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)
        }
    }

    dependencies {
        implementation("org.springframework.boot:spring-boot-starter-web")
        runtimeOnly("org.springframework.boot:spring-boot-devtools")
        testImplementation("org.springframework.boot:spring-boot-starter-test")
    }
}
  • buildscript の以下の点を変更します。
    • repositories に maven { url "https://repo.spring.io/release/" } を追加します。
    • dependencies に classpath "org.springframework.boot:spring-boot-gradle-plugin:2.1.4.RELEASE" を追加します。
  • configure(subprojects.findAll { it.name ==~ /^(sample-webapp)$/ }) { ... } の設定を追加します。

sample-webapp プロジェクトの build.gradle に残す設定はないのでファイルを削除します。

変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。

clean タスク実行 → Rebuild Project 実行 → build タスク実行を行うと、BUILD SUCCESSFUL のメッセージが出力されました。

f:id:ksby:20190421163648p:plain

Project Tool Window を見ると以下のディレクトリ構成になっています。sample-webapp/build/libs の下に sample-webapp-1.0.0-RELEASE.jar が生成されています。

f:id:ksby:20190421165042p:plain

SampleController クラスを新規作成して仮実装する

Controller クラスが1つもないので /sample にアクセスしたら "sample-webapp" の文字を返す SampleController クラスを作成します。現時点では仮実装で、sample-stubapp を作成したら、sample-stubapp 内に実装する WebAPI を呼び出すように変更します。

sample-webapp/src/main/java/ksbysample/webapp/samplewebapp/SampleController.java を新規作成し、以下の内容を記述します。

package ksbysample.webapp.samplewebapp;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/sample")
public class SampleController {

    @RequestMapping
    @ResponseBody
    public String index() {
        return "sample-webapp";
    }

}

Rebuild Project してエラーが出ないことを確認した後、sample-webapp の Tomcat を起動します。

f:id:ksby:20190421170027p:plain f:id:ksby:20190421170133p:plain

http://localhost:8080/sample にアクセスして "sample-webapp" の文字が出力されることを確認します。

f:id:ksby:20190421170325p:plain

確認後 Tomcat を停止します。

続く。。。

次回は sample-stubapp プロジェクト(こちらが sample-lib の StrNumUtils クラスを呼び出します)を作成した後、sample-webapp の SampleController クラスを本実装して Multi-project を完成させます。

履歴

2019/04/21
初版発行。