かんがるーさんの日記

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

AdoptOpenJDK を 11.0.8+10 → 11.0.9.1+1 へ、IntelliJ IDEA を 2020.2.2 → 2020.2.4 へ、Git for Windows を 2.28.0 → 2.29.2.2 へバージョンアップ

AdoptOpenJDK を 11.0.8+10 → 11.0.9.1+1 へバージョンアップする

※ksbysample-webapp-lending プロジェクトを開いた状態でバージョンアップしています。

  1. https://adoptopenjdk.net/ を見ると 11.0.9.1+1 がダウンロードできるようになっていましたので、11.0.9.1+1 へバージョンアップします。

    f:id:ksby:20201129221530p:plain

  2. インストール時に削除されるかもしれないので D:\Java\jdk-11.0.8.10-hotspot → D:\Java\jdk-11.0.8.10-hotspotx にリネームします。

  3. OpenJDK11U-jdk_x64_windows_hotspot_11.0.9.1_1.msi をダウンロードして D:\Java\jdk-11.0.9.101-hotspot へインストールした後、環境変数 JAVA_HOME のパスを D:\Java\jdk-11.0.9.101-hotspot へ変更します。

    コマンドプロンプトから java -version を実行し、11.0.9.1 に変更されていることを確認します。

    f:id:ksby:20201129222945p:plain

  4. D:\Java\jdk-11.0.8.10-hotspotx → D:\Java\jdk-11.0.8.10-hotspot に戻します。

  5. IntelliJ IDEA を再起動した後、プロジェクトで使用する JDK を 11.0.9.1+1 へ変更します。

  6. ダイアログ下部の「Configure」-「Structure for New Projects」を選択します。

    f:id:ksby:20201129223515p:plain

  7. 「Project Structure for New Projects」ダイアログが表示されます。画面左側で「Project Settings」-「Project」を選択後、画面右側の「Project SDK」のドロップダウンリストで D:\Java\jdk-11.0.9.101-hotspot を選択します。

    f:id:ksby:20201129223736p:plain

  8. 「Project SDK」の「Edit」ボタンをクリックします。

    f:id:ksby:20201129224045p:plain

  9. 画面左側で「Platform Settings」-「SDKs」が選択された状態になるので、画面右上の入力フィールドで "11" → "11.0.9.101" へ変更します。

    f:id:ksby:20201129224421p:plain

  10. 次に中央のリストから「11.0.8.10」を選択した後、リストの上の「-」ボタンをクリックして削除します。

    f:id:ksby:20201129224659p:plain

  11. 「OK」ボタンをクリックして「Project Structure for New Projects」ダイアログを閉じます。

  12. 「Welcome to IntelliJ IDEA」ダイアログに戻ったら、ksbysample-webapp-lending プロジェクトを開きます。

  13. IntelliJ IDEA のメイン画面が開いたら、メニューから「File」-「Project Structure...」を選択します。

  14. 「Project Structure」ダイアログが表示されます。以下の画像の状態になっているので、

    f:id:ksby:20201129225010p:plain

    「Project SDK」を選択し直します。「Project SDK」を「11.0.9.101」に変更すると「Project language level」も自動で「SDK default (11 - Local variable syntax for lambda param」が選択されました。

    f:id:ksby:20201129225120p:plain

  15. 「OK」ボタンをクリックして「Project Structure」ダイアログを閉じます。

  16. メイン画面に戻ると画面右下に「Indexing...」の表示が出るので。。。と思ったのですが、何かすぐに終わりました。

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

  18. clean タスク実行 → Rebuild Project 実行 → build タスクを実行して、"BUILD SUCCESSFUL" のメッセージが出力されることを確認します。

    f:id:ksby:20201129230206p:plain

  19. Project Tool Window で src/test でコンテキストメニューを表示して「Run 'All Tests' with Coverage」を選択すると、テストが全て失敗しました。

    f:id:ksby:20201129230544p:plain

    エラーが出ていたのは以下の3種類でした。

    • java.lang.NoClassDefFoundError: org/junit/rules/TestWatcher
    • java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
    • java.lang.NoClassDefFoundError: org/junit/rules/ExternalResource

    IntelliJ IDEA を 2020.1.4 → 2020.2.2 へバージョンアップ の時は成功していたのと、JDK のバージョンも 11 のままなので、IntelliJ IDEA のメインメニューから「File」-「Invalidate Caches / Restart...」を選択して「Invalidate Caches」ダイアログを表示した後「Invalidate and Restart」ボタンを押して Cache をクリアしてみます。

    再度「Run 'All Tests' with Coverage」を選択すると、テストが全て成功しました。

    f:id:ksby:20201129233820p:plain

  20. 特に問題は発生しませんでした。11.0.9+101 で開発を進めます。

IntelliJ IDEA を 2020.2.2 → 2020.2.4 へバージョンアップする

IntelliJ IDEA の 2020.2.4 がリリースされているのでバージョンアップします。

※ksbysample-webapp-lending プロジェクトを開いた状態でバージョンアップしています。

  1. IntelliJ IDEA のメインメニューから「Help」-「Check for Updates...」を選択します。

  2. IDE and Plugin Updates」ダイアログが表示されます。右下に「Update and Restart」ボタンが表示されていますので、「Update and Restart」ボタンをクリックします。

    f:id:ksby:20201129234908p:plain

  3. Plugin の update も表示されました。このまま「Update and Restart」ボタンをクリックします。

    f:id:ksby:20201129235006p:plain

  4. Patch がダウンロードされて IntelliJ IDEA が再起動します。

  5. IntelliJ IDEA が起動すると画面下部に「Indexing」のメッセージが表示されますので、終了するまで待機します。

    f:id:ksby:20201129235834p:plain

  6. IntelliJ IDEA のメインメニューから「Help」-「About」を選択し、2020.2.4 へバージョンアップされていることを確認します。

  7. clean タスク実行 → Rebuild Project 実行 → build タスクを実行して、"BUILD SUCCESSFUL" のメッセージが出力されることを確認します。

    f:id:ksby:20201130000742p:plain

  8. Project Tool Window で src/test でコンテキストメニューを表示して「Run 'All Tests' with Coverage」を選択し、テストが全て成功することを確認します。

    f:id:ksby:20201130001321p:plain

Git for Windows を 2.28.0 → 2.29.2.2 へバージョンアップする

Git for Windows の 2.29.2.2 がリリースされていたのでバージョンアップします。

  1. https://gitforwindows.org/ の「Download」ボタンをクリックして Git-2.29.2.2-64-bit.exe をダウンロードします。

  2. Git-2.29.2.2-64-bit.exe を実行します。

  3. 「Git 2.29.2.2 Setup」ダイアログが表示されます。インストーラーの画面を一通り見たいので「Only show new options」のチェックを外してから [Next >] ボタンをクリックします。

  4. 「Select Components」画面が表示されます。「Git LFS(Large File Support)」だけチェックした状態で [Next >]ボタンをクリックします。

  5. 「Choosing the default editor used by Git」画面が表示されます。「Use Vim (the ubiquitous text editor) as Git's default editor」が選択された状態で [Next >]ボタンをクリックします。

  6. 「Adjusting the name of the initial branch in new repositories」画面が表示されます(新画面)。「Let Git decide」が選択されていることを確認後、[Next >]ボタンをクリックします。

  7. 「Adjusting your PATH environment」画面が表示されます。中央の「Git from the command line and also from 3rd-party software」が選択されていることを確認後、[Next >]ボタンをクリックします。

  8. 「Choosing HTTPS transport backend」画面が表示されます。「Use the OpenSSL library」が選択されていることを確認後、[Next >]ボタンをクリックします。

  9. 「Configuring the line ending conversions」画面が表示されます。一番上の「Checkout Windows-style, commit Unix-style line endings」が選択されていることを確認した後、[Next >]ボタンをクリックします。

  10. 「Configuring the terminal emulator to use with Git Bash」画面が表示されます。「Use Windows'default console window」が選択されていることを確認した後、[Next >]ボタンをクリックします。

  11. 「Choose the default behavior of git pull」画面が表示されます。「Default (fast-forward or merge)」が選択されていることを確認した後、[Next >]ボタンをクリックします。

  12. 「Choose a credential helper」画面が表示されます。「None」が選択されていることを確認した後、[Next >]ボタンをクリックします。

  13. 「Configuring extra options」画面が表示されます。「Enable file system caching」だけがチェックされていることを確認した後、[Next >]ボタンをクリックします。

  14. 「Configuring experimental options」画面が表示されます。何もチェックせずに [Install]ボタンをクリックします。

  15. インストールが完了すると「Completing the Git Setup Wizard」のメッセージが表示された画面が表示されます。中央の「View Release Notes」のチェックを外した後、[Next >]ボタンをクリックしてインストーラーを終了します。

  16. コマンドプロンプトを起動して git --version を実行し、git のバージョンが git version 2.29.2.windows.2 になっていることを確認します。

    f:id:ksby:20201130002635p:plain

  17. 特に問題はないようですので、2.29.2.2 で作業を進めたいと思います。

IntelliJ IDEA を 2020.1.4 → 2020.2.2 へバージョンアップ

IntelliJ IDEA を 2020.1.4 → 2020.2.2 へバージョンアップする

IntelliJ IDEA の 2020.2.2 がリリースされているのでバージョンアップします。

※ksbysample-webapp-lending プロジェクトを開いた状態でバージョンアップしています。

  1. IntelliJ IDEA のメインメニューから「Help」-「Check for Updates...」を選択します。

  2. IDE and Plugin Updates」ダイアログが表示されます。右下に「Update and Restart」ボタンが表示されていますので、「Update and Restart」ボタンをクリックします。

    f:id:ksby:20200927231936p:plain

  3. Plugin の update も表示されました。このまま「Update and Restart」ボタンをクリックします。

    f:id:ksby:20200927232033p:plain

  4. Patch がダウンロードされて IntelliJ IDEA が再起動します。

  5. IntelliJ IDEA が起動すると画面下部に「Indexing」のメッセージが表示されますので、終了するまで待機します。今回から Indexing 中のライブラリが表示されるようになりました。

    f:id:ksby:20200927233742p:plain

  6. IntelliJ IDEA のメインメニューから「Help」-「About」を選択し、2020.2.2 へバージョンアップされていることを確認します。

  7. clean タスク実行 → Rebuild Project 実行 → build タスクを実行して、"BUILD SUCCESSFUL" のメッセージが出力されることを確認します。

    f:id:ksby:20200927234757p:plain

  8. Project Tool Window で src/test でコンテキストメニューを表示して「Run 'All Tests' with Coverage」を選択し、テストが全て成功することを確認します。

    f:id:ksby:20200927235542p:plain

  9. 最後にメジャーバージョンアップなので以前のバージョンの C:\Users\root\AppData\Local\JetBrains\IntelliJIdea2020.1 を削除します。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その8 )( SpotBugs を 4.0.0-beta4 → 4.1.1 へバージョンアップする )

概要

記事一覧はこちらです。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その7 )( Error Prone を 2.3.4 → 2.4.0 へバージョンアップする ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • SpotBugs を 4.0.0-beta4 → 4.1.1 へバージョンアップします。
    • SpotBugs の最新バージョンは 4.1.2 ですが、spotbugs-gradle-plugin の最新バージョン 4.5.0 に対応する SpotBugs のバージョンは 4.1.1 なので 4.1.1 にします。対応バージョンは SpotBugs version mapping に記載されています。

参照したサイト・書籍

  1. SpotBugs
    https://spotbugs.github.io/

  2. spotbugs / spotbugs
    https://github.com/spotbugs/spotbugs

  3. spotbugs / spotbugs-gradle-plugin
    https://github.com/spotbugs/spotbugs-gradle-plugin

目次

  1. build.gradle を変更する

手順

build.gradle を変更する

コメントアウトしていたのを解除して、以下の点を変更します。

plugins {
    id "java"
    id "eclipse"
    id "idea"
    id "org.springframework.boot" version "2.3.2.RELEASE"
    id "io.spring.dependency-management" version "1.0.9.RELEASE"
    id "groovy"
    id "checkstyle"
    id "com.github.spotbugs" version "4.5.0"
    id "pmd"
    id "net.ltgt.errorprone" version "1.2.1"
    id "com.gorylenko.gradle-git-properties" version "2.2.3"
}

..........

spotbugs {
    toolVersion = "4.1.1"
    ignoreFailures = true
    spotbugsTest.enabled = false
}
spotbugsMain {
    reports {
        html {
            enabled = true
            stylesheet = "color.xsl"
        }
    }
}

..........

dependencies {
    def jdbcDriver = "org.postgresql:postgresql:42.2.14"
    def spockVersion = "1.3-groovy-2.5"
    def domaVersion = "2.26.0"
    def lombokVersion = "1.18.12"
    def errorproneVersion = "2.4.0"
    def powermockVersion = "2.0.7"
    def spotbugsVersion = "4.1.1"

    ..........

    // for SpotBugs
    spotbugs("com.github.spotbugs:spotbugs:${spotbugsVersion}")
    compileOnly("com.github.spotbugs:spotbugs-annotations:${spotbugsVersion}")
    spotbugsPlugins("com.h3xstream.findsecbugs:findsecbugs-plugin:1.10.1")
}
  • plugins block の以下の点を変更します。
    • id "com.github.spotbugs" version "3.0.0"id "com.github.spotbugs" version "4.5.0"
  • spotbugs block の以下の点を変更します。
    • toolVersion = "4.0.0-beta4"toolVersion = "4.1.1"
    • effort = "max" を削除します。
  • tasks.withType(com.github.spotbugs.SpotBugsTask) {spotbugsMain { に変更します。
  • spotbugsMain block の以下の点を変更します。
    • xml.enabled = false を削除します。
    • reports { ... }reports { html { ... } }
    • stylesheet = resources.text.fromArchiveEntry(configurations.spotbugsStylesheets, "color.xsl")stylesheet = "color.xsl"
  • dependencies block の以下の点を変更します。
    • def spotbugsVersion = "4.0.0-beta4"def spotbugsVersion = "4.1.1"
    • compileOnly("com.github.spotbugs:spotbugs:${spotbugsVersion}")spotbugs("com.github.spotbugs:spotbugs:${spotbugsVersion}")
    • exclude group: "pull-parser", module: "pull-parser" を削除します。4.1.1 では依存関係からなくなっていました。
    • 以下の3行も削除します。
      • compileOnly("net.jcip:jcip-annotations:1.0")
      • testImplementation("com.google.code.findbugs:jsr305:3.0.2")
      • spotbugsStylesheets("com.github.spotbugs:spotbugs:${spotbugsVersion}")

Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新した後、clean タスク実行 → Rebuild Project 実行 → build タスクを実行すると "BUILD SUCCESSFUL" のメッセージが出力されました。

f:id:ksby:20200823000446p:plain

正式バージョンになって設定がすっきりしました。

履歴

2020/08/23
初版発行。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その7 )( Error Prone を 2.3.4 → 2.4.0 へバージョンアップする )

概要

記事一覧はこちらです。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その6 )( PMD を 6.20.0 → 6.26.0 へバージョンアップする ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • Error Prone を 2.3.4 → 2.4.0 へバージョンアップします。

参照したサイト・書籍

  1. Command-line flags
    https://errorprone.info/docs/flags

  2. Criteria for new checks
    https://errorprone.info/docs/criteria

目次

  1. build.gradle を変更する
  2. 警告の原因を取り除く
    1. 警告:[EmptyBlockTag] A block tag (@param, @return, @throws, @deprecated) has an empty description. Block tags without descriptions don't add much value for future readers of the code; consider removing the tag entirely or adding a description.
    2. 警告:[MissingSummary] A summary line is required on public/protected Javadocs.
    3. 警告:[InlineFormatString] Prefer to create format strings inline, instead of extracting them to a single-use constant
    4. 警告:[InvalidThrows] The documented method doesn't actually throw this checked exception.
    5. 警告:[JdkObsolete] StringBuffer performs synchronization that is usually unnecessary; prefer StringBuilder.
  3. 2.4.0 から追加された WARNING の check を有効にするには build.gradle に options.errorprone.errorproneArgs.add("-Xep:<checkName>") を記述する
  4. メモ書き

手順

build.gradle を変更する

plugins {
    id "java"
    id "eclipse"
    id "idea"
    id "org.springframework.boot" version "2.3.2.RELEASE"
    id "io.spring.dependency-management" version "1.0.9.RELEASE"
    id "groovy"
    id "checkstyle"
//    id "com.github.spotbugs" version "3.0.0"
    id "pmd"
    id "net.ltgt.errorprone" version "1.2.1"
    id "com.gorylenko.gradle-git-properties" version "2.2.3"
}

..........

[compileJava, compileTestGroovy, compileTestJava]*.options*.encoding = "UTF-8"
[compileJava, compileTestGroovy, compileTestJava]*.options*.compilerArgs = ["-Xlint:all,-options,-processing,-path"]
tasks.withType(JavaCompile).configureEach {
    options.errorprone.disableWarningsInGeneratedCode = true
}
tasks.named("compileTestJava").configure {
    options.errorprone.enabled = false
}

..........

dependencies {
    def jdbcDriver = "org.postgresql:postgresql:42.2.14"
    def spockVersion = "1.3-groovy-2.5"
    def domaVersion = "2.26.0"
    def lombokVersion = "1.18.12"
    def errorproneVersion = "2.4.0"
    def powermockVersion = "2.0.7"
    def spotbugsVersion = "4.0.0-beta4"
    ..........
  • plugins block の以下の点を変更します。
    • id "net.ltgt.errorprone" version "1.1.1"id "net.ltgt.errorprone" version "1.2.1"
  • tbroyer / gradle-errorprone-plugin に記載されていた記述で、今回 build した時に自動生成されたコードに対しても Error Prone が警告を出したので tasks.withType(JavaCompile).configureEach { options.errorprone.disableWarningsInGeneratedCode = true } を追加します。
  • dependencies block の以下の点を変更します。
    • def errorproneVersion = "2.3.4"def errorproneVersion = "2.4.0"

Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新した後、clean タスク実行 → Rebuild Project 実行 → build タスクを実行すると compileJava タスクで警告が 100個以上出ました(コンソールには 100個と出力されていますが警告が 100個以上あっても1度には 100個までしか出力されません)。

f:id:ksby:20200818002529p:plain

警告の原因を取り除く

警告:[EmptyBlockTag] A block tag (@param, @return, @throws, @deprecated) has an empty description. Block tags without descriptions don't add much value for future readers of the code; consider removing the tag entirely or adding a description.

Error Prone のマニュアルの EmptyBlockTag です。Javadoc で @param, @return, @throws, @deprecated の説明文を記述していないと警告が出るようになっていました。@throws の説明文を記述していなかったのが原因です。

f:id:ksby:20200818010123p:plain

@throws の説明文を追加します。

警告:[MissingSummary] A summary line is required on public/protected Javadocs.

Error Prone のマニュアルの MissingSummary です。public/protected の Javadoc で summary line を記述していないと警告が出るようになっていました。

f:id:ksby:20200818010727p:plain

summary line を記述します。

警告:[InlineFormatString] Prefer to create format strings inline, instead of extracting them to a single-use constant

Error Prone のマニュアルの InlineFormatString です。String.format で呼び出すフォーマット文字列を定数で定義していたのですが、inline で書くか helper メソッドを使用するよう警告が出ていました。正しい引数を渡しているかチェックしにくいので String.format とフォーマット文字列は近くに書くように、という指摘のようです。

f:id:ksby:20200818015808p:plain

今回は定数をやめて inline に変更します。

警告:[InvalidThrows] The documented method doesn't actually throw this checked exception.

Error Prone のマニュアルの InvalidThrows です。throws がないのに Javadoc に @throws を記述していたので警告が出ていました。

f:id:ksby:20200818020906p:plain

削除します。

警告:[JdkObsolete] StringBuffer performs synchronization that is usually unnecessary; prefer StringBuilder.

Error Prone のマニュアルの JdkObsolete です。指摘されたのは以下の箇所で、

f:id:ksby:20200819225119p:plain

HttpServletRequest#getRequestURL の戻り値の型が StringBuffer のためでした。

f:id:ksby:20200819232153p:plain

String 型を返す HttpServletRequest#getRequestURI に変更します。

2.4.0 から追加された WARNING の check を有効にするには build.gradle に options.errorprone.errorproneArgs.add("-Xep:<checkName>") を記述する

https://github.com/google/error-prone/releases/tag/v2.4.0 を見ると new checks に追加された check が記述されていますが、CheckedExceptionNotThrown が検知できるのか試してみたいと思い、 ksbysample.webapp.lending.ErrorProneCheck クラスを作成して以下の内容を記述した後、

f:id:ksby:20200820000038p:plain

compileJava タスクを実行しても何も検知されませんでした。

f:id:ksby:20200820000303p:plain

Error Prone のマニュアルを見ると SerSeverity.WARNING の check については、

f:id:ksby:20200820000921p:plain

build.gradle に options.errorprone.errorproneArgs.add("-Xep:<checkName>") の記述を追加しないと有効にならないからでした。

build.gradle に 'options.errorprone.errorproneArgs.add("-Xep:CheckedExceptionNotThrown")' を追加してから、

tasks.withType(JavaCompile).configureEach {
    options.errorprone.disableWarningsInGeneratedCode = true
    options.errorprone.errorproneArgs.add("-Xep:CheckedExceptionNotThrown")
}

compileJava タスクを実行すると今度は 警告:[CheckedExceptionNotThrown] This method cannot throw a checked exception that it claims to. This may cause consumers of the API to incorrectly attempt to handle, or propagate, this exception. のメッセージが出力されました。

f:id:ksby:20200820001543p:plain

メモ書き

これまで全然何もエラー・警告を出さなかったのに 2.4.0 にバージョンアップしたら急に警告が出るようになりました。しかも実装に関する警告よりも Javadoc の警告が出るようになったのが意外です。Checkstyle、PMD に加えて Error Prone も入れておけば Javadoc の記述漏れをかなり検知できるのではないでしょうか。

履歴

2020/08/20
初版発行。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その6 )( PMD を 6.20.0 → 6.26.0 へバージョンアップする )

概要

記事一覧はこちらです。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その5 )( Checkstyle を 8.28 → 8.35 へバージョンアップする ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • PMD を 6.20.0 → 6.26.0 へバージョンアップします。

参照したサイト・書籍

目次

  1. build.gradle を変更する
  2. 警告の原因を取り除く
    1. The initializer for variable '...' is never used (overwritten on line ...)

手順

build.gradle を変更する

pmd {
    toolVersion = "6.26.0"
    sourceSets = [project.sourceSets.main]
    ignoreFailures = true
    consoleOutput = true
    ruleSetFiles = rootProject.files("/config/pmd/pmd-project-rulesets.xml")
    ruleSets = []
}
  • toolVersion = "6.20.0"toolVersion = "6.26.0" に変更します。

Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新した後、clean タスク実行 → Rebuild Project 実行 → build タスクを実行すると pmdMain タスクで警告が出ました。

f:id:ksby:20200815104254p:plain

警告の原因を取り除く

The initializer for variable '...' is never used (overwritten on line ...)

生成されたレポートファイル build/reports/pmd/main.html をブラウザで開くと2箇所指摘されており、どちらも Problem には The initializer for variable '...' is never used (overwritten on line ...) が表示されていました。

f:id:ksby:20200815104812p:plain

6.26.0 から追加された UnusedAssignment による警告でした。

  • 2箇所は、変数宣言時に = null と初期値をセットしていたが、その後の処理で必ず値がセットされるので警告が出ていたのが原因でした。変数宣言時に初期値をセットしている部分を削除します。
  • 1箇所はデータをロックするために select していた時に取得したデータを使用しないにもかかわらず変数にセットしていたのが原因でした。取得したデータを変数にセットしないように変更します。

変更後に clean タスク実行 → Rebuild Project 実行 → build タスクを実行すると BUILD SUCCESSFUL が表示されました。

f:id:ksby:20200815105845p:plain

履歴

2020/08/15
初版発行。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その5 )( Checkstyle を 8.28 → 8.35 へバージョンアップする )

概要

記事一覧はこちらです。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その4 )( Release Notes を見て必要な箇所を変更する ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • Checkstyle を 8.28 → 8.35 へバージョンアップします。
    • 最新版の google_checks.xml の内容も反映します。

参照したサイト・書籍

  1. checkstyle / checkstyle
    https://github.com/checkstyle/checkstyle

  2. checkstyle/checkstyle - checkstyle/src/main/resources/google_checks.xml
    https://github.com/checkstyle/checkstyle/blob/master/src/main/resources/google_checks.xml

目次

  1. build.gradle を変更する
  2. IntelliJ IDEA の CheckStyle-IDEA Plugin が使用する Checkstyle のバージョンを 8.34 に変更する
  3. 最新版の google_checks.xml から設定をコピーする

手順

build.gradle を変更する

checkstyle {
    configFile = file("${rootProject.projectDir}/config/checkstyle/google_checks.xml")
    toolVersion = "8.35"
    sourceSets = [project.sourceSets.main]
}
  • toolVersion = "8.28"toolVersion = "8.35" に変更します。

Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新した後、clean タスク実行 → Rebuild Project 実行 → build タスクを実行すると BUILD SUCCESSFUL が表示されました。

f:id:ksby:20200812224944p:plain

IntelliJ IDEA の CheckStyle-IDEA Plugin が使用する Checkstyle のバージョンを 8.34 に変更する

CheckStyle-IDEA Plugin に指定できるバージョンが 8.34 までだったので 8.34 を指定します。

f:id:ksby:20200812225531p:plain

最新版の google_checks.xml から設定をコピーする

最新版の google_checks.xml から差分を反映します。。。が、2020/08/12 時点の google_checks.xml の差分を反映したところ checkstyleMain タスクでいくつかエラーが出て削除することがありました。

今回反映した内容を箇条書きで記述しておきます。

  • <module name="RightCurly"><property name="tokens">valueENUM_DEF, INTERFACE_DEF を追加しました。
  • <module name="SuppressionXpathSingleFilter">...</module> を追加しました。
  • <module name="WhitespaceAfter">...</module> を追加しました。
  • <module name="AbbreviationAsWordInName"><property name="tokens">value に PATTERN_VARIABLE_DEF を追加しました。
  • <module name="NoWhitespaceBefore"><property name="tokens">value から ELLIPSIS を削除し LABELED_STAT を追加しました。

以下の変更は checkstyleMain タスク実行時にエラーが出たので削除しました。Java 14 の機能向けの定義のようです。つまり google_checks.xml には Java 14 向けの定義も記述されるので Java 11 で開発する場合にはそのままでは使えない(エラーが出たものは取り除く必要がある)ということでした。

  • <module name="EmptyLineSeparator"><property name="tokens">value に RECORD_DEF を追加。
  • <module name="PatternVariableName">...</module> の追加。
  • <module name="AbbreviationAsWordInName"><property name="tokens">value に RECORD_DEF, RECORD_COMPONENT_DEF を追加。
  • <module name="MethodParamPad"><property name="tokens">value に RECORD_DEF を追加。
  • <module name="ParenPad"><property name="tokens">value に RECORD_DEF を追加。

変更後に clean タスク実行 → Rebuild Project 実行 → build タスクを実行すると BUILD SUCCESSFUL が表示されました。

f:id:ksby:20200813001139p:plain

履歴

2020/08/13
初版発行。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その4 )( Release Notes を見て必要な箇所を変更する )

概要

記事一覧はこちらです。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その3 )( Spring Boot を 2.2.9 → 2.3.2 へバージョンアップする ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。

参照したサイト・書籍

  1. Spring BootのGraceful shutdownって内部でどうやって実現されているの?
    https://speakerdeck.com/kawakawaryuryu/spring-bootfalsegraceful-shutdowntutenei-bu-dedouyatuteshi-xian-sareteirufalse

  2. Spring BootのGraceful shutdown処理が内部でどう呼ばれているかソースコードリーディングしてみた結果
    https://qiita.com/kawakawaryuryu/items/bc92453f9c43d98c1a26

  3. Spring Boot 2.3 の Liveness & Readiness Probes 対応 について調べてみた
    https://speakerdeck.com/otty375/spring-boot-2-dot-3-liveness-and-readiness-probes

  4. Kubernetes Probes
    https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-kubernetes-probes

  5. Liveness and Readiness Probes with Spring Boot
    https://spring.io/blog/2020/03/25/liveness-and-readiness-probes-with-spring-boot

  6. Liveness and Readiness Probes in Spring Boot
    https://www.baeldung.com/spring-liveness-readiness-probes

  7. Kubernetes のヘルスチェック(Liveness Probe,Readiness Probe)を検証する
    https://qiita.com/toshihirock/items/c7e94e70c1c9650488df

目次

  1. server.shutdown=graceful を設定する
  2. management.endpoint.health.probes.enabled=true を設定する

手順

server.shutdown=graceful を設定する

Graceful shutdown によると 設定ファイルに server.shutdown=graceful を記述すれば Graceful shutdown をしてくれるようになったので、src/main/resources/application.properties に設定します。

..........
management.endpoint.health.show-details=always

server.shutdown=graceful

#spring.autoconfigure.exclude=com.integralblue.log4jdbc.spring.Log4jdbcAutoConfiguration
spring.datasource.hikari.jdbc-url=jdbc:postgresql://localhost/ksbylending
..........

動作を確認するために src/main/java/ksbysample/webapp/lending/web/GracefulShutdownTestController.java を新規作成して以下の内容を記述します。http://localhost:8080/gracefulShutdownTest にアクセスすると 5分間 sleep してからレスポンスを返す Controller クラスです。Graceful shutdown が有効になっていれば、この URL にアクセスしてから Tomcat を停止しようとすると 30秒(spring.lifecycle.timeout-per-shutdown-phase のデフォルト値)待ってから停止するはず。

package ksbysample.webapp.lending.web;

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

/**
 * Spring Boot 2.3 から追加された Graceful shutdown の機能をテストするための Controller
 */
@Controller
public class GracefulShutdownTestController {

    /**
     * アクセス後 5分 sleep してからレスポンスを返す
     *
     * @return "OK"の文字列
     * @throws InterruptedException
     */
    @GetMapping("/gracefulShutdownTest")
    @ResponseBody
    public String index() throws InterruptedException {
        Thread.sleep(60_000 * 5);
        return "OK";
    }

}

src/main/java/ksbysample/webapp/lending/config/WebSecurityConfig.java.antMatchers("/gracefulShutdownTest/**").permitAll() の記述を追加して、認証不要にします。

    @Configuration
    public static class FormLoginWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    // 認証の対象外にしたいURLがある場合には、以下のような記述を追加します
                    // 複数URLがある場合はantMatchersメソッドにカンマ区切りで対象URLを複数列挙します
                    // .antMatchers("/country/**").permitAll()
                    ..........
                    .antMatchers("/sample/**").permitAll()
                    .antMatchers("/gracefulShutdownTest/**").permitAll()
                    .anyRequest().hasAnyRole("USER", "ADMIN", "APPROVER");
            ..........

Tomcat を起動して Graceful shutdown の機能を試してみると、

  • IntelliJ IDEA から起動した時は機能しません。すぐに Tomcat が停止します(停止は Navigation bar や Services Tool Window の Stop ボタンで行いました)。
  • jar ファイルを作成してコマンドラインすると、/gracefulShutdownTest にアクセスして 5秒後に Ctrl+C を押す → 30秒何も起こらない → バッチ ジョブを終了しますか (Y/N)? が表示される、という動きになりました。Graceful shutdown が機能しています。
2020-08-09 20:50:50.080  INFO 23156 --- [SpringContextShutdownHook] o.s.a.r.l.SimpleMessageListenerContainer : Waiting for workers to finish.
2020-08-09 20:50:50.709  INFO 23156 --- [SpringContextShutdownHook] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish.
2020-08-09 20:50:50.714  INFO 23156 --- [SpringContextShutdownHook] o.s.b.w.e.tomcat.GracefulShutdown        : Commencing graceful shutdown. Waiting for active requests to complete
2020-08-09 20:51:20.717  INFO 23156 --- [SpringContextShutdownHook] o.s.c.support.DefaultLifecycleProcessor  : Failed to shut down 1 bean with phase value 2147483647 within timeout of 30000ms: [webServerGracefulShutdown]
2020-08-09 20:51:20.740  INFO 23156 --- [tomcat-shutdown] o.s.b.w.e.tomcat.GracefulShutdown        : Graceful shutdown aborted with one or more requests still active
..........
2020-08-09 20:51:22.954  INFO 23156 --- [SpringContextShutdownHook] o.s.a.r.l.SimpleMessageListenerContainer : Shutdown ignored - container is not active already
2020-08-09 20:51:22.955  INFO 23156 --- [SpringContextShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
2020-08-09 20:51:22.963  INFO 23156 --- [SpringContextShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2020-08-09 20:51:22.977  INFO 23156 --- [SpringContextShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
2020-08-09 20:51:23.018  WARN 23156 --- [SpringContextShutdownHook] io.lettuce.core.RedisChannelHandler      : Connection is already closed
2020-08-09 20:51:23.018  WARN 23156 --- [SpringContextShutdownHook] io.lettuce.core.RedisChannelHandler      : Connection is already closed
2020-08-09 20:51:23.018  WARN 23156 --- [SpringContextShutdownHook] io.lettuce.core.RedisChannelHandler      : Connection is already closed
2020-08-09 20:51:23.048  INFO 23156 --- [SpringContextShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService
2020-08-09 20:51:23.049  WARN 23156 --- [SpringContextShutdownHook] io.lettuce.core.RedisChannelHandler      : Connection is already closed
  • nssm.exe でサービスに登録して起動した時に Graceful shutdown したい場合、登録時に「Shutdown」タブで「Generate Control-C」だけをチェックして「Timeout」に spring.lifecycle.timeout-per-shutdown-phase に設定した時間より長い時間をセットする必要があります(デフォルトでは全てチェックされていて「Timeout」に 1500 がセットされている)。

    f:id:ksby:20200810234708p:plain

    この設定にすると、サービス起動 → /gracefulShutdownTest にアクセスして 5秒後に「サービスの停止」リンククリック → 60秒何も起こらない(spring.lifecycle.timeout-per-shutdown-phase に設定された秒数ではなく nssm.exe で設定した Timeout の秒数) → サービスが停止する、という動きになりました。ログファイルを見ると Graceful shutdown が機能して Tomcat は 30秒後に停止していますが、サービスが停止するまでには nssm.exe で設定した Timeout の秒数を待つ必要があります(処理中のリクエストがなくてもnssm.exe で設定した Timeout の秒数を必ず待つようになります)。

2020-08-10 23:50:46.445  INFO 3384 --- [SpringContextShutdownHook] o.s.a.r.l.SimpleMessageListenerContainer : Waiting for workers to finish.
2020-08-10 23:50:46.979  INFO 3384 --- [SpringContextShutdownHook] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish.
2020-08-10 23:50:46.983  INFO 3384 --- [SpringContextShutdownHook] o.s.b.w.e.tomcat.GracefulShutdown        : Commencing graceful shutdown. Waiting for active requests to complete
2020-08-10 23:51:16.987  INFO 3384 --- [SpringContextShutdownHook] o.s.c.support.DefaultLifecycleProcessor  : Failed to shut down 1 bean with phase value 2147483647 within timeout of 30000ms: [webServerGracefulShutdown]
2020-08-10 23:51:16.989  INFO 3384 --- [tomcat-shutdown] o.s.b.w.e.tomcat.GracefulShutdown        : Graceful shutdown aborted with one or more requests still active
..........
2020-08-10 23:51:19.272  INFO 3384 --- [SpringContextShutdownHook] o.s.a.r.l.SimpleMessageListenerContainer : Shutdown ignored - container is not active already
2020-08-10 23:51:19.273  INFO 3384 --- [SpringContextShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
2020-08-10 23:51:19.283  INFO 3384 --- [SpringContextShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2020-08-10 23:51:19.297  INFO 3384 --- [SpringContextShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
2020-08-10 23:51:19.357  INFO 3384 --- [SpringContextShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService
2020-08-10 23:51:19.358  WARN 3384 --- [SpringContextShutdownHook] io.lettuce.core.RedisChannelHandler      : Connection is already closed
  • ローカルで Docker で Tomcat を起動した場合、Commencing graceful shutdown. のログが出力されましたので Graceful shutdown が機能しています。
2020-08-11 00:15:11.433  INFO 1 --- [extShutdownHook] o.s.a.r.l.SimpleMessageListenerContainer : Waiting for workers to finish.
2020-08-11 00:15:12.174  INFO 1 --- [extShutdownHook] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish.
2020-08-11 00:15:12.180  INFO 1 --- [extShutdownHook] o.s.b.w.e.tomcat.GracefulShutdown        : Commencing graceful shutdown. Waiting for active requests to complete

management.endpoint.health.probes.enabled=true を設定する

Liveness and Readiness probes によると、アプリが実行中かどうか(liveness)、リクエストに応答できる準備が出来ているかどうか(readiness)を Actuator で取得できる機能が提供されたとのこと。Kubernetes 環境向けの機能なので、KubernetesContainer probes の説明が分かりやすいです。

Kubernetes の環境で実行しないとあまり意味はなさそうですが(Kubernetes 環境だと自動で設定されるらしい)、面白そうなので設定してみます。

src/main/resources/application.properties を以下のように変更します。

..........
management.endpoint.health.show-details=always
management.endpoint.health.probes.enabled=true
management.endpoint.health.group.liveness.include=livenessStateProbeIndicator,cacheCheck
management.endpoint.health.group.readiness.include=readinessStateProbeIndicator,cacheCheck

server.shutdown=graceful

..........
  • 以下の3行を追加します。
    • management.endpoint.health.probes.enabled=true
    • management.endpoint.health.group.liveness.include=livenessStateProbeIndicator,cacheCheck
    • management.endpoint.health.group.readiness.include=readinessStateProbeIndicator,cacheCheck
  • Liveness and Readiness probes には management.endpoint.health.probes.enabled=true の記述しかないのですが、他の2つも設定しないと /actuator/health/liveness、/actuator/health/readiness にアクセスした時に 404 Not Found が返ってきました。

Tomcat を起動してから http://localhost:8080/actuator/health/liveness にアクセスすると 200 OK と以下の画像のレスポンスが返ってきました。

f:id:ksby:20200812000549p:plain

http://localhost:8080/actuator/health/readiness も 200 OK が返ってきます。

f:id:ksby:20200812000744p:plain

履歴

2020/08/12
初版発行。