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(メインとスタブ)は新規に作成します。
参照したサイト・書籍
目次
- 方針
- gradle-multiprj-lib-webapp2 ディレクトリを作成する
- gradle-multiprj-lib-cmdapp プロジェクトからファイルをコピーする
- IntelliJ IDEA で gradle-multiprj-lib-webapp2 プロジェクトをオープンする
- clean タスク実行 → Rebuild Project 実行 → build タスク実行を行う
- Spring Boot ベースの Web アプリケーション(メイン)のプロジェクトを作成する
- 続く。。。
手順
方針
- 以下のディレクトリ構成の Multi-project を作成します。
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つあるので、
gradle-multiprj-lib-webapp2 ディレクトリを作成する
ksby/ksbysample-boot-miscellaneous の repository を checkout している D:\project-springboot\ksbysample-boot-miscellaneous
の下に gradle-multiprj-lib-webapp2 ディレクトリを作成します。
gradle-multiprj-lib-cmdapp プロジェクトからファイルをコピーする
D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-cmdapp\
から以下のファイルをコピーします。
- gradle ディレクトリ
- sample-lib ディレクトリ
- この下の build, out ディレクトリは削除します。
- .gitignore
- build.gradle
- gradlew
- gradlew.bat
- settings.gradle
settings.gradle は以下の内容に変更します。
rootProject.name = 'gradle-multiprj-lib-webapp2' include 'sample-lib'
コピー後、コマンドプロンプトから gradlew wrapper
コマンドを実行します。
D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-webapp2\
の下には以下のディレクトリ・ファイルがある状態になります。
IntelliJ IDEA で gradle-multiprj-lib-webapp2 プロジェクトをオープンする
gradle-multiprj-lib-webapp2 プロジェクトをオープンします。
オープン後 Project Tool Window は以下のようになり、
Gradle Tool Window は以下のようになります。
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 にバージョンアップしたのが原因のようです。
※Project SDK は default の設定で JDK 11 を使うように設定済なので、今回は変更の手順は書きません。
clean タスク実行 → Rebuild Project 実行 → build タスク実行を行う
ここまでで build タスクが正常に終了するか確認します。clean タスク実行 → Rebuild Project 実行 → build タスク実行を行うと、BUILD SUCCESSFUL のメッセージが出力されました。
sample-lib/build/libs の下に sample-lib-1.0.0-RELEASE.jar も生成されており、問題ないようです。
Spring Boot ベースの Web アプリケーション(メイン)のプロジェクトを作成する
IntelliJ IDEA で sample-webapp プロジェクトを作成する
IntelliJ IDEA から Spring Initializr を利用して Spring Boot ベースの Web アプリケーションのプロジェクトを作成します。
※DevTools と Web の2つをチェックします。
作成後 IntelliJ IDEA のウィンドウが開きますが、何もせずに閉じます。
sample-webapp プロジェクトから不要なファイルを削除する
D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-webapp2\sample-webapp\
の下には以下のディレクトリ・ファイルがありますが、
src ディレクトリと build.gradle 以外を削除します。削除すると以下の状態になります。
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-webapp
(IntelliJ IDEA 209.1 から左側に :
が付かなくなったようです)が追加されます。
また sample-webapp 起動用の Run/Debug Configuration も自動で追加されます。
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"
を追加します。
- repositories に
configure(subprojects.findAll { it.name ==~ /^(sample-webapp)$/ }) { ... }
の設定を追加します。
sample-webapp プロジェクトの build.gradle に残す設定はないのでファイルを削除します。
変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
clean タスク実行 → Rebuild Project 実行 → build タスク実行を行うと、BUILD SUCCESSFUL のメッセージが出力されました。
Project Tool Window を見ると以下のディレクトリ構成になっています。sample-webapp/build/libs の下に sample-webapp-1.0.0-RELEASE.jar が生成されています。
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 を起動します。
http://localhost:8080/sample にアクセスして "sample-webapp" の文字が出力されることを確認します。
確認後 Tomcat を停止します。
続く。。。
次回は sample-stubapp プロジェクト(こちらが sample-lib の StrNumUtils クラスを呼び出します)を作成した後、sample-webapp の SampleController クラスを本実装して Multi-project を完成させます。
履歴
2019/04/21
初版発行。
AdoptOpenJDK を 11.0.2+9 → 11.0.3+7 へ、IntelliJ IDEA を 2018.3.6 → 2019.1.1 へバージョンアップ
AdoptOpenJDK を 11.0.2+9 → 11.0.3+7 へバージョンアップする
※ksbysample-webapp-lending プロジェクトを開いた状態でバージョンアップしています。
https://adoptopenjdk.net/?variant=openjdk11&jvmVariant=hotspot を見ると 11.0.3+7 がダウンロードできるようになっていましたので、11.0.3+7 へバージョンアップします。
OpenJDK11U-jdk_x64_windows_hotspot_11.0.3_7.msi をダウンロードして D:\Java\jdk1.8.0_202 へインストールした後、環境変数 JAVA_HOME のパスを D:\Java\jdk-11.0.3+7 へ変更します。
コマンドプロンプトから
java -version
を実行し、11.0.3
に変更されていることを確認します。開いているプロジェクトを閉じて「Welcome to IntelliJ IDEA」ダイアログを表示します。
ダイアログ下部の「Configure」-「Project Defaults」-「Project Structure」を選択します。
「Default Project Structure」ダイアログが表示されます。画面左側で「Project Settings」-「Project」を選択後、画面右側の「Project SDK」の「New...」ボタンをクリックし、表示されるメニューから「JDK」を選択します。
「Select Home Directory for JDK」ダイアログが表示されます。D:\Java\jdk-11.0.3+7 を選択した後、「OK」ボタンをクリックします。
「Default Project Structure」ダイアログに戻るので、今度は「Project SDK」の「Edit」ボタンをクリックします。
画面左側で「Platform Settings」-「SDKs」が選択された状態になるので、画面右上の入力フィールドで "11" → "11.0.3+7" へ変更します。
次に中央のリストから「11.0.2+9」を選択した後、リストの上の「-」ボタンをクリックして削除します。
「OK」ボタンをクリックして「Default Project Structure」ダイアログを閉じます。
「Welcome to IntelliJ IDEA」ダイアログに戻ったら、ksbysample-webapp-lending プロジェクトを開きます。
IntelliJ IDEA のメイン画面が開いたら、メニューから「File」-「Project Structure...」を選択します。
「Project Structure」ダイアログが表示されます。以下の画像の状態になっているので、
「Project SDK」を選択し直します。「Project SDK」を「11.0.3+7」に変更すると「Project language level」も自動で「SDK default (11 - Local variable syntax for lambda pa」が選択されました。
「OK」ボタンをクリックして「Project Structure」ダイアログを閉じます。
メイン画面に戻ると画面右下に「Indexing...」の表示が出るので、終了するまで待ちます。
Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
clean タスク実行 → Rebuild Project 実行 → build タスクを実行して、"BUILD SUCCESSFUL" のメッセージが出力されることを確認します。
Project Tool Window で src/test/groovy/ksbysample、src/test/java/ksbysample でコンテキストメニューを表示して「Run 'Tests in 'ksbysample'' with Coverage」を選択し、テストが全て成功することを確認します。
特に問題は発生しませんでした。11.0.3+7 で開発を進めます。
IntelliJ IDEA を 2018.3.6 → 2019.1.1 へバージョンアップする
IntelliJ IDEA の 2019.1.1 がリリースされているのでバージョンアップします。
- IntelliJ IDEA 2019.1.1 is Here!
https://blog.jetbrains.com/idea/2019/04/intellij-idea-2019-1-1-is-here/
※ksbysample-webapp-lending プロジェクトを開いた状態でバージョンアップしています。
IntelliJ IDEA のメインメニューから「Help」-「Check for Updates...」を選択します。
「IDE and Plugin Updates」ダイアログが表示されます。左下に「Update and Restart」ボタンが表示されていますので、「Update and Restart」ボタンをクリックします。
Plugin の update も表示されました。このまま「Update and Restart」ボタンをクリックします。
Patch がダウンロードされて IntelliJ IDEA が再起動します。
メジャーバージョンアップなので起動時に「Import IntelliJ IDEA Settings From...」ダイアログが表示されます。「Previous version」を選択した状態で「OK」ボタンをクリックします。
IntelliJ IDEA が起動すると画面下部に「Indexing…」のメッセージが表示されますので、終了するまで待機します。
IntelliJ IDEA のメインメニューから「Help」-「About」を選択し、2019.1.1 へバージョンアップされていることを確認します。
Gradle Tool Window を見ると今回のバージョンからまた何も表示されなくなっていました。
左上にある「Refresh all Gradle projects」ボタンをクリックして更新すると、いつものツリーが表示されました。
clean タスク実行 → Rebuild Project 実行 → build タスクを実行して、"BUILD SUCCESSFUL" のメッセージが出力されることを確認します。
Project Tool Window で src/test/groovy/ksbysample、src/test/java/ksbysample でコンテキストメニューを表示して「Run 'Tests in 'ksbysample'' with Coverage」を選択し、テストが全て成功することを確認します。
最後に C:\Users\root.IntelliJIdea2018.3 を削除します。
Gradle で Multi-project を作成する ( その3 )( lib+cmdapp編、Spring Boot ベースのコマンドラインアプリケーションのプロジェクトを作成する )
概要
記事一覧はこちらです。
- 今回の手順で確認できるのは以下の内容です。
参照したサイト・書籍
目次
- Spring Boot ベースのコマンドラインアプリケーションのプロジェクトを作成する
- clean タスク実行 → Rebuild Project 実行 → build タスク実行を行う
java -jar sample-cmdapp-1.0.0-RELEASE.jar
コマンドを実行してみる- まとめ
手順
Spring Boot ベースのコマンドラインアプリケーションのプロジェクトを作成する
IntelliJ IDEA で sample-cmdapp プロジェクトを作成する
IntelliJ IDEA から Spring Initializr を利用して Spring Boot ベースのコマンドラインアプリケーションのプロジェクトを作成します。
※シンプルなコマンドアプリケーションなので何もチェックしません。
作成後 IntelliJ IDEA のウィンドウが開きますが、何もせずに閉じます。
.gitignore に設定を追加する
sample-cmdapp プロジェクトの下に作成された .gitignore から ### STS ###
、### IntelliJ IDEA ###
、### NetBeans ###
、### VS Code ###
の設定をコピーして、ルートディレクトリの .gitignore に追加します。
# Ignore Gradle project-specific cache directory .gradle # Ignore Gradle build output directory build ### STS ### .apt_generated .classpath .factorypath .project .settings .springBeans .sts4-cache ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr /out/ ### NetBeans ### /nbproject/private/ /nbbuild/ /dist/ /nbdist/ /.nb-gradle/ ### VS Code ### .vscode/
sample-cmdapp プロジェクトから不要なファイルを削除する
D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-cmdapp\sample-cmdapp\
の下には以下のディレクトリ・ファイルがありますが、
src ディレクトリと build.gradle 以外は不要なので削除します。削除すると以下の状態になります。
settings.gradle に sample-cmdapp プロジェクトの include 文を追加する
D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-cmdapp
の下の settings.gradle に include 'sample-cmdapp'
を追加します。
rootProject.name = 'gradle-multiprj-lib-cmdapp' include 'sample-lib' include 'sample-cmdapp'
追加後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新すると :sample-cmdapp
が追加されます。
sample-cmdapp プロジェクトの build.gradle から不要な記述を削除し、sample-lib プロジェクトへの依存関係を追加する
sample-cmdapp プロジェクトの build.gradle を以下の内容に変更します。
plugins { id "org.springframework.boot" version "2.1.4.RELEASE" } dependencyManagement { imports { mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES) } } dependencies { implementation("org.springframework.boot:spring-boot-starter") testImplementation("org.springframework.boot:spring-boot-starter-test") implementation project(":sample-lib") }
sample-cmdapp の設定はプロジェクトのルートディレクトリにある build.gradle に project(':sample-cmdapp') { ... }
で記述することも可能ですが、その場合 plugins { ... }
が使えなくなるので sample-cmdapp の下に build.gradle を残してこの中に設定を記述することにします。
変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
SampleCmdappApplication クラスに CommandLineRunner インターフェースを実装する
sample-cmdapp/src/main/java/ksbysample/cmdapp/samplecmdapp/SampleCmdappApplication.java を以下のように変更します。
package ksbysample.cmdapp.samplecmdapp; import ksbysample.lib.samplelib.StrNumUtils; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SampleCmdappApplication implements CommandLineRunner { public static void main(String[] args) { SpringApplication.run(SampleCmdappApplication.class, args); } @Override public void run(String... args) throws Exception { System.out.println("★★★ " + StrNumUtils.plus("1", "2")); } }
クラスに implements CommandLineRunner
を追加し run メソッドを実装します。run メソッド内で sample-lib プロジェクトの StrNumUtils クラスを呼び出すようにします。
次にテストクラスを作成します。Spring Initializr でプロジェクトを作成したので sample-cmdapp/src/test/java/ksbysample/cmdapp/samplecmdapp/SampleCmdappApplicationTests.java が作成されていますが、このテストはファイル毎削除して Spock で作り直します。
cmdapp/src/test/groovy/ksbysample/cmdapp/samplecmdapp/SampleCmdappApplicationTest.groovy が新規作成されますので、以下の内容を記述します。
package ksbysample.cmdapp.samplecmdapp import spock.lang.Specification class SampleCmdappApplicationTest extends Specification { def "sample-cmdapp を実行すると'★★★ 3'が出力される"() { setup: def buf = new ByteArrayOutputStream(1024) System.out = new PrintStream(buf) when: SampleCmdappApplication.main() then: buf.toString().contains("★★★ 3") } }
ここまでで以下のディレクトリ構成になります。
clean タスク実行 → Rebuild Project 実行 → build タスク実行を行う
clean タスク実行 → Rebuild Project 実行 → build タスク実行を行うと、BUILD SUCCESSFUL のメッセージが出力されました。
各プロジェクトの build/libs ディレクトリの下に sample-cmdapp-1.0.0-RELEASE.jar、sample-lib-1.0.0-RELEASE.jar が作成されています。
sample-cmdapp-1.0.0-RELEASE.jar を zip ソフトで開いてみると BOOT-INF/lib の下に sample-lib-1.0.0-RELEASE.jar が入っていることも確認できます。
java -jar sample-cmdapp-1.0.0-RELEASE.jar
コマンドを実行してみる
Multi-project で作成した sample-cmdapp-1.0.0-RELEASE.jar が問題なく動作することをコマンドラインから確認してみます。
コマンドラインから java -jar sample-cmdapp-1.0.0-RELEASE.jar
コマンドを実行すると "★★★ 3" が出力されることが確認できました。
まとめ
- Multi-project ではルートディレクトリの build.gradle の
subprojects { ... }
に共通の設定を記述する。plugin の設定だけplugins { ... }
が使えないのでapply plugin: "..."
で記述すること。 - Spring を使用しないライブラリのサブプロジェクトを作成したい時はサブプロジェクトのディレクトリを作成した後、settings.gradle に
include '<サブプロジェクトのディレクトリ名>'
を書いてから IntelliJ IDEA の Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新すればよい(おそらくコマンドだとgradle wrapper
だと思われる)。 - Spring Boot ベースのコマンドラインアプリケーションのサブプロジェクトを作成したい時は Spring Initializr でサブプロジェクトを作成してから src, build.gradle 以外を削除し、settings.gradle に
include '<サブプロジェクトのディレクトリ名>'
を書いてから IntelliJ IDEA の Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新すればよい。 - サブプロジェクトの build.gradle の設定はサブプロジェクトのディレクトリの下に build.gradle を置いてその中に記述するか、ルートディレクトリの build.gradle に
project(':<サブプロジェクトのディレクトリ名>') { ... }
の形式で記述する。
Multi-project を初めて作ってみましたが、Gradle Guides の Creating Multi-project Builds に基本は書かれているので、これを読めば何とか作れるものですね。
履歴
2019/04/20
初版発行。
Gradle で Multi-project を作成する ( その2 )( lib+cmdapp編、Multi-project の設定ファイルと Spring を使用しないライブラリのプロジェクトを作成する )
概要
記事一覧はこちらです。
Gradle で Multi-project を作成する ( その1 )( 概要 ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- Gradle で Spring を使用しないライブラリ+Spring Boot ベースのコマンドラインアプリケーションの Multi-project を作成します。
- 2回に分けて書きます。
- 今回は Multi-project のための各種設定ファイルとSpring を使用しないライブラリのプロジェクトを作成します。
参照したサイト・書籍
Gradle Guides - Creating Multi-project Builds
https://guides.gradle.org/creating-multi-project-builds/The Gradle Wrapper
https://docs.gradle.org/5.0/userguide/gradle_wrapper.html#sec:wrapper_generationAuthoring Multi-Project Builds
https://docs.gradle.org/current/userguide/multi_project_builds.html
目次
- 方針
- gradle-multiprj-lib-cmdapp ディレクトリを作成する
- Spring Initializr で作成したプロジェクトから Gradle Wrapper のファイルをコピーする
- Gradle を最新バージョンにする
- gradlew init を実行する
- build.gradle に subproject 共通の設定を追加する
- Spring を使用しないライブラリのプロジェクトを作成する
- IntelliJ IDEA で gradle-multiprj-lib-cmdapp プロジェクトをオープンする
- Project SDK を JDK 11 に設定する
- StrNumUtils クラスを追加する
- clean タスク実行 → Rebuild Project 実行 → build タスク実行を行う
- 続く。。。
手順
方針
- 以下のディレクトリ構成の Multi-project を作成します。
gradle-multiprj-lib-cmdapp ├ sample-cmdapp <-- Spring Boot ベースのコマンドラインアプリケーションの Project └ sample-lib <-- Spring を使用しないライブラリの Project
- Spring Boot ベースのコマンドラインアプリケーションの Project では Profile は作成しません。
- テスティングフレームワークは全ての Project で JUnit 5 と Spock を使用できるようにします。
- checkstyle, spotbugs, pmd, error-prone は今回は導入しません。
gradle-multiprj-lib-cmdapp ディレクトリを作成する
ksby/ksbysample-boot-miscellaneous の repository を checkout している D:\project-springboot\ksbysample-boot-miscellaneous
の下に gradle-multiprj-lib-cmdapp ディレクトリを作成します。
Spring Initializr で作成したプロジェクトから Gradle Wrapper のファイルをコピーする
IntelliJ IDEA で Spring Initializr の新規 Gradle プロジェクトを作成します。
ここから以下のディレクトリ・ファイルを D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-cmdapp
の下にコピーします。
- gradle ディレクトリ
- gradlew
- gradlew.bat
Gradle を最新バージョンにする
コピーした gradle/wrapper/gradle-wrapper.properties を見ると Gradle のバージョンは 5.2.1 だったのですが、https://gradle.org/releases/ を見ると Gradle の最新バージョンは 5.4 なので 5.4 にバージョンアップします。
コマンドプロンプトから gradlew wrapper --gradle-version=5.4
、gradlew --version
、gradlew wrapper
コマンドを実行します。
gradle/wrapper/gradle-wrapper.properties を見ると 5.4 になっています。
distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-5.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists
gradlew init を実行する
gradlew init
コマンドを実行します。選択肢は 1: basic
、1: groovy
を選択し、Project name は何も入力せずに Enter キーを押します。
gradle-multiprj-lib-cmdapp ディレクトリの下は以下のようになり、
生成された .gitignore、build.gradle、settings.gradle は以下の内容になっています。
■.gitignore
# Ignore Gradle project-specific cache directory .gradle # Ignore Gradle build output directory build
■build.gradle
/* * This file was generated by the Gradle 'init' task. * * This is a general purpose Gradle build. * Learn how to create Gradle builds at https://guides.gradle.org/creating-new-gradle-builds/ */
■settings.gradle
/* * This file was generated by the Gradle 'init' task. * * The settings file is used to specify which projects to include in your build. * * Detailed information about configuring a multi-project build in Gradle can be found * in the user manual at https://docs.gradle.org/5.4/userguide/multi_project_builds.html */ rootProject.name = 'gradle-multiprj-lib-cmdapp'
build.gradle に subproject 共通の設定を追加する
build.gradle に subproject 共通の設定を追加します。以下の内容に変更します。
buildscript { repositories { mavenCentral() maven { url "https://plugins.gradle.org/m2/" } } dependencies { classpath "io.spring.gradle:dependency-management-plugin:1.0.7.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 } } }
subprojects { ... }
内で subproject 共通の Gradle plugin を記述する時にplugins { ... }
は使えません。apply plugin: "..."
で記述します。
Spring を使用しないライブラリのプロジェクトを作成する
sample-lib ディレクトリを作成する
gradle-multiprj-lib-cmdapp ディレクトリの下に sample-lib ディレクトリを作成します。
settings.gradle に sample-lib プロジェクトの include 文を追加する
D:\project-springboot\ksbysample-boot-miscellaneous\gradle-multiprj-lib-cmdapp
の下の settings.gradle に include 'sample-lib'
を追加します。
rootProject.name = 'gradle-multiprj-lib-cmdapp' include 'sample-lib'
IntelliJ IDEA で gradle-multiprj-lib-cmdapp プロジェクトをオープンする
gradle-multiprj-lib-cmdapp プロジェクトを以下の画像の手順でオープンします。
IntelliJ IDEA のメイン画面が表示されると Project Tool Window には以下のように表示されます。
Gradle Tool Window は以下のように表示されます。
Project SDK を JDK 11 に設定する
IntelliJ IDEA のメインメニューから「File」-「Project Structure...」を選択し「Project Structure」ダイアログを表示し「Project SDK」で JDK 11 を、「Project language level」で「SDK default(11 - local variable syntax for lambda parameters)」を選択して「OK」ボタンをクリックします。
StrNumUtils クラスを追加する
sample-lib/src/main/java の下に ksbysample.lib.samplelib パッケージを作成し、その下に StrNumUtils.java を新規作成して以下の内容を記述します。
package ksbysample.lib.samplelib; public class StrNumUtils { public static String plus(String v1, String v2) { return String.valueOf(Integer.parseInt(v1) + Integer.parseInt(v2)); } }
テストクラスも作成します。今回は JUnit 5 で作成します。
src/test/java/ksbysample/lib/samplelib/StrNumUtilsTest.java が新規作成されるので、以下の内容を記述します。
package ksbysample.lib.samplelib; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; class StrNumUtilsTest { @Test @DisplayName("plusメソッドのテスト") void plus() { assertThat(StrNumUtils.plus("1", "2")).isEqualTo("3"); } }
ここまでで以下のディレクトリ構成になります。
clean タスク実行 → Rebuild Project 実行 → build タスク実行を行う
build タスクが正常に終了するか確認します。clean タスク実行 → Rebuild Project 実行 → build タスク実行を行うと、BUILD SUCCESSFUL のメッセージが出力されました。
sample-lib ディレクトリの下に build, out ディレクトリが作成されており、sample-lib/build/libs の下に sample-lib-1.0.0-RELEASE.jar が出力されていました。
ここまでは問題なさそうです。
続く。。。
次回は Spring Boot ベースのコマンドラインアプリケーションのプロジェクトを作成して Multi-project を完成させます。
履歴
2019/04/20
初版発行。
Gradle で Multi-project を作成する ( その1 )( 概要 )
概要
記事一覧はこちらです。
- Gradle の Multi-project を作成したことがないので、作成手順を覚えるために作成してみます。
- 以下のパターンの Multi-project を作成してみる予定です。Spring Boot ベースのアプリケーションを最低1つ+ライブラリのプロジェクト(Spring ベースかは問わない)を最低1つ+何か加えたものという構成です。
- 他にやりたいパターンが思い浮かんだら変えるかもしれません。
- 作成した Multi-project は ksby/ksbysample-boot-miscellaneous の repository にコミットします。
履歴
2019/04/18
初版発行。
Gradle で Multi-project を作成する ( 大目次 )
- その1 ( 概要 )
- その2 ( lib+cmdapp編、Multi-project の設定ファイルと Spring を使用しないライブラリのプロジェクトを作成する )
- その3 ( lib+cmdapp編、Spring Boot ベースのコマンドラインアプリケーションのプロジェクトを作成する )
- その4 ( lib+webappx2編、Multi-project の設定ファイルと Spring Boot ベースの Web アプリケーション(メイン)のプロジェクトを作成する )
- その5 ( lib+webappx2編、Spring Boot ベースの Web アプリケーション(スタブ)のプロジェクトを作成する )
- その6 ( Multi-project は settings.gradle に include を書くだけでもよいのでは? )
- 番外編 ( Spring Actuator を利用してアプリ起動時にメールサーバに接続できない場合には起動を中断させる )
- その7 ( doma2lib+cmdapp+webapp編、Multi-project の設定ファイルと docker-compose.yml を作成する )
- その8 ( doma2lib+cmdapp+webapp編、doma2-lib プロジェクトを作成する )
- その9 ( doma2lib+cmdapp+webapp編、sample-cmdapp プロジェクトを作成する )
- その10 ( doma2lib+cmdapp+webapp編、sample-cmdapp プロジェクトを作成する2 )
- その11 ( doma2lib+cmdapp+webapp編、log4jdbc-log4j2 を導入してトランザクションが有効なことを確認する )
- その12 ( doma2lib+cmdapp+webapp編、sample-webapp プロジェクトを作成する )
- その13 ( doma2lib+cmdapp+webapp編、PropertiesLauncher を利用して doma2-lib の jar ファイルを外部に出す )
- その14 ( vuejs+springboot編、Multi-project のベースと backend-app プロジェクトを作成する )
- その15 ( vuejs+springboot編、frontend-app プロジェクトを作成する )
- 感想
Spring Boot + npm + Geb で入力フォームを作ってテストする ( その83 )( Checkstyle を 8.11 → 8.19 へ、PMD を 6.6.0 → 6.13.0 へバージョンアップ+JUnit 5 の導入+ Oracle JDK 8u202 → AdoptOpenJDK 11.0.2+9 へ、error-prone を 2.3.1 → 2.3.3 へバージョンアップする)
概要
記事一覧はこちらです。
- 今回の手順で確認できるのは以下の内容です。
参照したサイト・書籍
https://github.com/apache/groovy/commit/92bd96fcdfe35e502987e1846715a08a45620db1
- Groovy で
--add-opens
オプションを付ける時に参照しました。
- Groovy で
目次
- Checkstyle を 8.11 → 8.19 へ、PMD を 6.6.0 → 6.13.0 へバージョンアップする
- JUnit 5 を導入する
- Oracle JDK 8u202 → AdoptOpenJDK 11.0.2+9 へ、error-prone を 2.3.1 → 2.3.3 へバージョンアップする
- testJUnit4AndSpock タスクで出る警告を解消する
- 失敗するテストの原因を調査・解消する
- compileTestGroovy タスクで出る警告を解消する。。。ことは出来ませんでした
- gebTest タスクが成功するようにする
手順
Checkstyle を 8.11 → 8.19 へ、PMD を 6.6.0 → 6.13.0 へバージョンアップする
build.gradle の以下の点を変更します。
checkstyle { configFile = file("${rootProject.projectDir}/config/checkstyle/google_checks.xml") toolVersion = "8.19" sourceSets = [project.sourceSets.main] } .......... pmd { toolVersion = "6.13.0" sourceSets = [project.sourceSets.main] ignoreFailures = true consoleOutput = true ruleSetFiles = rootProject.files("/config/pmd/pmd-project-rulesets.xml") ruleSets = [] }
- checkstyle block で
toolVersion = "8.11"
→toolVersion = "8.19"
に変更します。 - pmd block で
toolVersion = "6.6.0"
→toolVersion = "6.13.0"
に変更します。
変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
clean タスク実行 → Rebuild Project 実行 → build タスク実行を行うと、PMD で何件か警告が出ました。
D:\project-springboot\ksbysample-boot-miscellaneous\boot-npm-geb-sample\src\main\java\ksbysample\webapp\bootnpmgeb\Application.java:26: The constant name 'springProfiles' doesn't match '[A-Z][A-Z_0-9]*'
- 定数名を SPRING_PROFILES に変更します。
D:\project-springboot\ksbysample-boot-miscellaneous\boot-npm-geb-sample\src\main\java\ksbysample\webapp\bootnpmgeb\aspect\logging\ControllerAndEventNameLogger.java:17: The constant name 'logger' doesn't match '[A-Z][A-Z_0-9]*'
D:\project-springboot\ksbysample-boot-miscellaneous\boot-npm-geb-sample\src\main\java\ksbysample\webapp\bootnpmgeb\aspect\logging\MethodLogger.java:20: The constant name 'logger' doesn't match '[A-Z][A-Z_0-9]*'
D:\project-springboot\ksbysample-boot-miscellaneous\boot-npm-geb-sample\src\main\java\ksbysample\webapp\bootnpmgeb\aspect\logging\RequestAndResponseLogger.java:34: The constant name 'logger' doesn't match '[A-Z][A-Z_0-9]*'
再度 clean タスク実行 → Rebuild Project 実行 → build タスク実行を行うと、今度は BUILD SUCCESSFUL のメッセージが出力されました。
JUnit 5 を導入する
build.gradle の以下の点を変更します。
dependencyManagement { imports { // mavenBom は以下の URL のものを使用する // https://repo.spring.io/release/org/springframework/boot/spring-boot-starter-parent/2.1.4.RELEASE/ // bomProperty に指定可能な property は以下の URL の BOM に記述がある // https://repo.spring.io/release/org/springframework/boot/spring-boot-dependencies/2.1.4.RELEASE/spring-boot-dependencies-2.1.4.RELEASE.pom mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES mavenBom("org.junit:junit-bom:5.4.2") } } dependencies { .......... // for JUnit 5 // 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") } def jvmArgsForTask = [ "-ea", "-Dfile.encoding=UTF-8", "-Dsun.nio.cs.map=x-windows-iso2022jp/ISO-2022-JP" ] 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)" } } bootRun { jvmArgs = jvmArgsForTask + ["-Dspring.profiles.active=develop"] } tasks.withType(Test) { jvmArgs = jvmArgsForTask + ["-Dspring.profiles.active=unittest"] } task testJUnit4AndSpock(type: Test) { // testJUnit4AndSpock タスクの jvmArgs は tasks.withType(Test) { ... } で定義している exclude "geb/**" testLogging { afterSuite printTestCount } } test.dependsOn testJUnit4AndSpock test { // test タスクの jvmArgs は tasks.withType(Test) { ... } で定義している // for JUnit 5 useJUnitPlatform() testLogging { afterSuite printTestCount } } .......... webdriverBinaries { chromedriver "73.0.3683.68" geckodriver "0.24.0" } def drivers = ["chrome", "firefox"] drivers.each { driver -> task "${driver}Test"(type: Test) { // 前回実行時以降に何も更新されていなくても必ず実行する outputs.upToDateWhen { false } systemProperty "geb.env", driver exclude "ksbysample/**" // Gradle 5.3 で internal API が変更されて gradle-processes が動かなくなったのでコメントアウトする // dependsOn startServer // finalizedBy stopServer testLogging { afterSuite printTestCount } } } task gebTest { dependsOn drivers.collect { tasks["${it}Test"] } enabled = false }
- dependencyManagement block の import block 内に
mavenBom("org.junit:junit-bom:5.4.2")
を追加します。 - dependencies block に以下の2行を追加します。
testCompile("org.junit.jupiter:junit-jupiter")
testRuntime("org.junit.platform:junit-platform-launcher")
def jvmArgsForTask = [ ... ]
を追加します。def printTestCount = { ... }
を追加します。- bootRun タスクの jvmArgs の設定を jvmArgsForTask 変数を利用したものに変更します。
tasks.withType(Test) { ... }
の jvmArgs の設定を jvmArgsForTask 変数を利用したものに変更します。task testJUnit4AndSpock(type: Test) { ... }
を追加します。test.dependsOn testJUnit4AndSpock
を追加します。- test タスク内に以下の記述を追加します。
useJUnitPlatform()
testLogging { afterSuite printTestCount }
exclude "geb/**"
の記述は test タスクから testJUnit4AndSpock タスクへ移動します。drivers.each { driver -> task "${driver}Test"(type: Test) { ... } }
内にtestLogging { afterSuite printTestCount }
を追加します。
変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
clean タスク実行 → Rebuild Project 実行 → build タスク実行をすると、テストは問題なく成功し BUILD SUCCESSFUL のメッセージが出力されました。
gebTest タスクも BUILD SUCCESSFUL のメッセージが出力されました。
Oracle JDK 8u202 → AdoptOpenJDK 11.0.2+9 へ、error-prone を 2.3.1 → 2.3.3 へバージョンアップする
IntelliJ IDEA のメインメニューから「File」-「Project Structure...」を選択して「Project Structure」ダイアログを開き、「Project SDK」で「11.0.2+9」を選択してから「OK」ボタンをクリックしてダイアログを閉じます。
build.gradle の以下の点を変更します。
plugins { id "java" id "eclipse" id "idea" id "org.springframework.boot" version "2.1.4.RELEASE" id "io.spring.dependency-management" version "1.0.7.RELEASE" id "groovy" id "net.ltgt.errorprone" version "0.7.1" id "checkstyle" id "com.github.spotbugs" version "1.6.9" id "pmd" id "com.moowork.node" version "1.3.1" id "com.gorylenko.gradle-git-properties" version "2.0.0" // Gradle 5.3 で internal API が変更されて gradle-processes が動かなくなったのでコメントアウトする // id "com.github.johnrengelman.processes" version "0.5.0" id "com.energizedwork.webdriver-binaries" version "1.4" } 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"] tasks.named("compileTestJava").configure { options.errorprone.enabled = false } .......... dependencies { def spockVersion = "1.3-groovy-2.5" def domaVersion = "2.24.0" def lombokVersion = "1.18.6" def errorproneVersion = "2.3.3" def powermockVersion = "2.0.0" def seleniumVersion = "3.13.0" def spotbugsVersion = "3.1.11" .......... // for Geb + Spock testImplementation("org.gebish:geb-spock:2.3.1") { exclude group: "org.codehaus.groovy", module: "groovy-all" } .......... } def jvmArgsForTask = [ "-ea", "-Dfile.encoding=UTF-8", "-Dsun.nio.cs.map=x-windows-iso2022jp/ISO-2022-JP" ] // JDK 11 に変更後、test タスク実行時に groovy と powermock が JDKの内部部分にアクセスするためにコードでリフレクションを使用 // していて WARNING が出るため、JVM の起動時オプションの --add-opens を指定して WARNING が出ないようにする 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", "--add-opens=java.base/java.util.stream=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)" } } bootRun { jvmArgs = jvmArgsForTask + jvmArgsAddOpens + ["-Dspring.profiles.active=develop"] } tasks.withType(Test) { jvmArgs = jvmArgsForTask + jvmArgsAddOpens + ["-Dspring.profiles.active=unittest"] }
- plugins block の以下の点を変更します。
id "net.ltgt.errorprone" version "0.0.14"
→id "net.ltgt.errorprone" version "0.7.1"
- sourceCompatibility、targetCompatibility に指定する値を
1.8
→JavaVersion.VERSION_11
に変更します。 compileJava.options.compilerArgs += [ ... ]
を削除します。tasks.named("compileTestJava").configure { options.errorprone.enabled = false }
を追加します。- dependencies block の以下の点を変更します。
def errorproneVersion = "2.3.1"
→def errorproneVersion = "2.3.3"
def jvmArgsAddOpens = [ ... ]
を追加します。Spring Boot 2.0.x の Web アプリを 2.1.x へバージョンアップする ( その15 )( JDK を 8u202 → 11.0.2+9 に変更する ) で指定したものと同じものを指定しておきます。bootRun { ... }
とtasks.withType(Test) { ... }
内の jvmArgs の設定にjvmArgsAddOpens +
を追加します。- groovy も 2.5 にバージョンアップします。
- dependencies block 内で
def spockVersion = "1.3-groovy-2.4"
→def spockVersion = "1.3-groovy-2.5"
に変更します。 testImplementation("org.gebish:geb-spock:2.3.1")
→testImplementation("org.gebish:geb-spock:2.3.1") { exclude group: "org.codehaus.groovy", module: "groovy-all" }
に変更します。
- dependencies block 内で
変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
IntelliJ IDEA のメインメニューから「Run」-「Edit Configurations...」を選択して「Run/Debug Configurations」ダイアログを開き、画面左側のツリーから「Templates」-「JUnit」を選択後、画面右側の「VM options」に build.gradle の def jvmArgsAddOpens = [ ... ]
に記述したオプションを追加します。
また追加した結果 IntelliJ IDEA からテストを実行しようとすると Command line is too long.
のエラーメッセージが表示されて実行できなくなるので、画面右側の「Shorten command line」で「JAR manifest」を選択します。
clean タスク実行 → Rebuild Project 実行 → build タスク実行して出力される以下のエラーメッセージを取り除きます。
エラー: An unhandled exception was thrown by the Error Prone static analysis plugin.
- このエラーメッセージが出る箇所は PMD の @SuppressWarnings が付与されているので、
@SuppressWarnings({"PMD.UnusedPrivateMethod"})
→@SuppressWarnings({"PMD.UnusedPrivateMethod", "UnusedMethod"})
に変更します。
- このエラーメッセージが出る箇所は PMD の @SuppressWarnings が付与されているので、
警告:[JavaTimeDefaultTimeZone] LocalDateTime.now() is not allowed because it silently uses the system default time-zone. You must pass an explicit time-zone (e.g., ZoneId.of("America/Los_Angeles")) to this method.
LocalDateTime.now()
→LocalDateTime.now(ZoneId.of("Asia/Tokyo"))
に変更します。
ここまでやると以下の状態になります。
- compileTestGroovy タスクで警告が出る。
- testJUnit4AndSpock タスクで警告が出る。
- テストが1件失敗する。
testJUnit4AndSpock タスクで出る警告を解消する
出たのは以下3件のメッセージでした。
WARNING: Illegal reflective access by org.codehaus.groovy.reflection.CachedConstructor$1 (file:/C:/Users/root/.gradle/caches/modules-2/files-2.1/org.codehaus.groovy/groovy/2.5.6/6936e700f0fb1b50bac0698ada4347a769d40199/groovy-2.5.6.jar) to constructor java.util.stream.Collectors()
WARNING: Illegal reflective access by org.codehaus.groovy.reflection.CachedConstructor$1 (file:/C:/Users/root/.gradle/caches/modules-2/files-2.1/org.codehaus.groovy/groovy/2.5.6/6936e700f0fb1b50bac0698ada4347a769d40199/groovy-2.5.6.jar) to constructor java.nio.charset.StandardCharsets()
WARNING: Illegal reflective access by org.powermock.reflect.internal.WhiteboxImpl (file:/C:/Users/root/.gradle/caches/modules-2/files-2.1/org.powermock/powermock-reflect/2.0.0/cd452bc345ec9f88ec5efecd41139de0cb1d4265/powermock-reflect-2.0.0.jar) to method java.util.regex.Pattern.clazz(boolean)
build.gradle と IntelliJ IDEA の「Edit Configurations...」-「JUnit」の設定に以下のオプションを追加します。
--add-opens=java.base/java.util.stream=ALL-UNNAMED
--add-opens=java.base/java.nio.charset=ALL-UNNAMED
--add-opens=java.base/java.util.regex=ALL-UNNAMED
失敗するテストの原因を調査・解消する
エラーの原因を調べるために Project Tool Window で src/test/groovy/ksbysample でコンテキストメニューを表示して「Run 'Tests in 'ksbysample''」を選択してテストを実行してみると、
テストが失敗したのは src/test/groovy/ksbysample/webapp/bootnpmgeb/web/inquiry/form/InquiryInput02FormValidatorTest.groovy で、以下のように実装されていました。
@RunWith(PowerMockRunner) @PowerMockRunnerDelegate(SpringRunner) @SpringBootTest @PrepareForTest(EmailValidator) @PowerMockIgnore("javax.management.*") static class InquiryInput02FormValidator_メールアドレス { @Autowired private InquiryInput02FormValidator input02FormValidator ..........
@PowerMockIgnore("javax.management.*")
を変更し忘れていただけでした。。。 @PowerMockIgnore("javax.management.*")
→ @PowerMockIgnore(["javax.management.*", "com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.dom.*", "com.sun.org.apache.xalan.*"])
に変更します。ksbysample-webapp-lending と同じ変更だと Caused by: java.lang.IllegalAccessError: class com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl (in unnamed module @0x12e035a8) cannot access class jdk.xml.internal.JdkXmlUtils (in module java.xml) because module java.xml does not export jdk.xml.internal to unnamed module @0x12e035a8
というエラーメッセージが表示されたので、, "com.sun.org.apache.xalan.*"
を追加しています。
compileTestGroovy タスクで出る警告を解消する。。。ことは出来ませんでした
WARNING: Illegal reflective access by org.codehaus.groovy.reflection.CachedClass (file:/C:/Users/root/.gradle/caches/modules-2/files-2.1/org.codehaus.groovy/groovy/2.5.6/6936e700f0fb1b50bac0698ada4347a769d40199/groovy-2.5.6.jar) to method java.util.AbstractCollection.hugeCapacity(int)
というエラーメッセージが出ているので compileTestGroovy タスクの jvmArgs にも --add-opens
オプションを設定しようと思い設定方法を調べたところ、gradle/gradle に Unable to add multiple --add-opens
args to forked Groovy compiler #7045 という Issue を見つけました。
試してみたところ "--add-opens"
を1行だけ書いた時は問題ないのですが、以下のように2行記述すると、
[compileJava, compileTestGroovy, compileTestJava]*.options*.encoding = "UTF-8" [compileJava, compileTestGroovy, compileTestJava]*.options*.compilerArgs = ["-Xlint:all,-options,-processing,-path"] tasks.named("compileTestJava").configure { options.errorprone.enabled = false } compileTestGroovy { options.forkOptions.jvmArgs += [ "--add-opens", "java.base/java.util=ALL-UNNAMED", "--add-opens", "java.base/java.lang.annotation=ALL-UNNAMED" ] }
下の画像のエラーメッセージが表示されます。
他にも調べてみましたがさっぱり解決方法が分かりませんでした。Issue のクローズ待ちでしょうか。。。 今回は compileTestGroovy の警告メッセージは解消するのは諦めます。
ここまでの対応で clean タスク実行 → Rebuild Project 実行 → build タスク実行を行うと compileTestGroovy タスクで警告のメッセージが出ますが、BUILD SUCCESSFUL のメッセージが表示されるようになりました。
gebTest タスクが成功するようにする
gebTest タスクを実行すると1件警告が出ます。
WARNING: Illegal reflective access by org.codehaus.groovy.reflection.CachedConstructor$1 (file:/C:/Users/root/.gradle/caches/modules-2/files-2.1/org.codehaus.groovy/groovy/2.5.6/6936e700f0fb1b50bac0698ada4347a769d40199/groovy-2.5.6.jar) to constructor java.beans.Introspector(java.lang.Class,java.lang.Class,int)
java.beans は https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/java/beans/package-summary.html を見ると Module java.desktop
と書かれていたので、
build.gradle と IntelliJ IDEA の「Edit Configurations...」-「JUnit」の設定に "--add-opens=java.desktop/java.beans=ALL-UNNAMED"
を追加します。
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.nio.charset=ALL-UNNAMED", "--add-opens=java.base/java.security=ALL-UNNAMED", "--add-opens=java.base/java.util=ALL-UNNAMED", "--add-opens=java.base/java.util.regex=ALL-UNNAMED", "--add-opens=java.base/java.util.stream=ALL-UNNAMED", "--add-opens=java.desktop/java.beans=ALL-UNNAMED" ]
これで gebTest タスクは正常に終了するようになりました。
以上で今回の boot-npm-geb-sample プロジェクトのバージョンアップ作業は完了です。
履歴
2019/04/16
初版発行。