かんがるーさんの日記

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

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
初版発行。