Spring Boot 1.5.x の Web アプリを 2.0.x へバージョンアップする ( その5 )( checkstyle を 7.8.1 → 8.12 に、PMD を 5.8.1 → 6.7.0 にバージョンアップする )
概要
記事一覧はこちらです。
- 今回の手順で確認できるのは以下の内容です。
- checkstyle を 7.8.1 → 8.12 にバージョンアップします。
- PMD を 5.8.1 → 6.7.0 にバージョンアップします。
参照したサイト・書籍
目次
- checkstyle を 7.8.1 → 8.12 にバージョンアップする
- PMD を 5.8.1 → 6.7.0 にバージョンアップする
- build.gradle を変更して build してみる
The constant name 'springProfiles' doesn't match '[A-Z][A-Z_0-9]*'
Do not use hard coded encryption keys
Comment is too large: Too many lines
Avoid throwing raw exception types.
The constant name 'logger' doesn't match '[A-Z][A-Z_0-9]*'
StringBuffer (or StringBuilder).append is called consecutively without reusing the target variable.
This class has too many methods, consider refactoring it.
Avoid unnecessary constructors - the compiler will generate these for you
It is a good practice to call super() in a constructor
A method/constructor should not explicitly throw java.lang.Exception
The constant name 'serialVersionUID' doesn't match '[A-Z][A-Z_0-9]*'
Useless parentheses.
Document empty constructor
There is log block not surrounded by if
Avoid short class names like ...
Avoid using Literals in Conditional Statements
Avoid instantiating new objects inside loops
Prefer StringBuilder (non-synchronized) or StringBuffer (synchronized) over += for concatenating strings
Assigning an Object to null is a code smell. Consider refactoring.
Avoid using redundant field initializer for 'errcode'
Avoid catching generic exceptions such as NullPointerException, RuntimeException, Exception in try-catch block
- 最後に
手順
checkstyle を 7.8.1 → 8.12 にバージョンアップする
build.gradle の以下の点を変更します。
checkstyle { configFile = file("${rootProject.projectDir}/config/checkstyle/google_checks.xml") toolVersion = "8.12" sourceSets = [project.sourceSets.main] }
- checkstyle タスクで
toolVersion = "7.8.1"
→toolVersion = "8.12"
に変更します。
変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
clean タスク実行 → Rebuild Project 実行 → build タスクを実行すると、checkstyleMain タスクで失敗しました。
コマンドラインから gradlew --stacktrace --debug build > gradle-debug.log 2>&1
コマンドを実行してログをファイルに出力した後、gradle-debug.log を IntelliJ IDEA のメインメニューの「Tools」-「Tail File in Console...」で開きます。
Property 'maxLineLength' in module LeftCurly does not exist, please check the documentation
というエラーが出ていました。Spring Boot + npm + Geb で入力フォームを作ってテストする ( その28 )( Spring Boot を 1.5.4 → 1.5.7 へ、error-prone を 2.0.15 → 2.1.1 へバージョンアップする ) で書きましたが、LeftCurly module から maxLineLength プロパティがなくなったので削除します。
config/checkstyle/google_checks.xml を以下のように変更します。
<module name="NeedBraces"/> <module name="LeftCurly"/> <module name="RightCurly"> <property name="id" value="RightCurlySame"/> <property name="tokens" value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_DO"/> </module>
- LeftCurly module に記述していた
<property name="maxLineLength" value="100"/>
を削除して、<module name="LeftCurly">...</module>
→<module name="LeftCurly"/>
に変更します。
再度 clean タスク実行 → Rebuild Project 実行 → build タスクを実行すると、今度は BUILD SUCCESSFUL が表示されました。
Checkstyle plugin の設定も 8.12 に変更しておきます。
PMD を 5.8.1 → 6.7.0 にバージョンアップする
以下の記事をベースに進めます。
- Spring Boot + npm + Geb で入力フォームを作ってテストする ( その55 )( PMD を 5.8.1 → 6.4.0 へバージョンアップする )
- Spring Boot + npm + Geb で入力フォームを作ってテストする ( その56 )( PMD を 5.8.1 → 6.4.0 へバージョンアップする2 )
設定ファイルも以下のファイルをコピーします。
build.gradle を変更して build してみる
まずは build.gradle の以下の点を変更します。
pmd { toolVersion = "5.8.1" sourceSets = [project.sourceSets.main] ignoreFailures = true consoleOutput = true ruleSetFiles = rootProject.files("/config/pmd/pmd-project-rulesets.xml") ruleSets = [] }
toolVersion = "5.8.1"
→toolVersion = "6.7.0"
に変更します。
変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
pmd-project-rulesets.xml をダウンロードして、config/pmd/pmd-project-rulesets.xml にコピーします。
clean タスク実行 → Rebuild Project 実行 → build タスクを実行しますが、警告が大量に出力されました。1つずつ解消していきます。
The constant name 'springProfiles' doesn't match '[A-Z][A-Z_0-9]*'
定数名を 英大文字+スネークケースにしていなかったので、警告が出ていました。警告に従って springProfiles
→ SPRING_PROFILES
に変更します。
Do not use hard coded encryption keys
SecretKeySpec クラスのコンストラクタの第1引数に渡すキー文字列をクラス内に定数として定義していたので、外部に定義するよう警告が出ていました。このサンプルではこのままにしますので、クラスに @SuppressWarnings({"PMD.HardCodedCryptoKey"})
を付けて警告が出ないようにします。
Comment is too large: Too many lines
コメントの行数が多いという警告なのですが、警告が出たところを見ると以下の内容でした。
この警告は不要なので削除します。config/pmd/pmd-project-rulesets.xml では一旦 exclude した後、<rule ref="category/java/documentation.xml/CommentSize">...</rule>
で定義し直していたのですが、<rule ref="category/java/documentation.xml/CommentSize">...</rule>
を削除して exclude するだけにします。
Avoid throwing raw exception types.
適切な Exception クラスを定義せずに throw new RuntimeException(e);
と RuntimeException を throw していたので警告が出ていました。このサンプルでは config/pmd/pmd-project-rulesets.xml を以下のように変更して、警告が出ないようにします。
<rule ref="category/java/design.xml"> <exclude name="AvoidThrowingRawExceptionTypes"/> <exclude name="CyclomaticComplexity"/> <exclude name="DataClass"/> <exclude name="LawOfDemeter"/> <exclude name="LoosePackageCoupling"/> <exclude name="NcssCount"/> <exclude name="UseObjectForClearerAPI"/> <exclude name="UseUtilityClass"/> </rule>
<exclude name="AvoidThrowingRawExceptionTypes"/>
を追加します。
The constant name 'logger' doesn't match '[A-Z][A-Z_0-9]*'
logger を private static final Logger logger = LoggerFactory.getLogger(ControllerAndEventNameLogger.class);
と定義していたので、定数なのに英大文字+スネークケースでないと警告が出ていました。でも、変数は logger のままにしたいので static
を削除すると、今度は The Logger variable declaration does not contain the static and final modifiers
という警告が出ます。
今回は static を削除して private static final Logger logger = ...
→ private final Logger logger = ...
に変更し、config/pmd/pmd-project-rulesets.xml を以下のように変更します。
<rule ref="category/java/errorprone.xml"> <exclude name="BeanMembersShouldSerialize"/> <exclude name="DataflowAnomalyAnalysis"/> <exclude name="LoggerIsNotStaticFinal"/> <exclude name="MissingStaticMethodInNonInstantiatableClass"/> </rule>
<exclude name="LoggerIsNotStaticFinal"/>
を追加します。
StringBuffer (or StringBuilder).append is called consecutively without reusing the target variable.
1行ずつ .append(...)
を呼び出していたので警告が出ていました。
.append(...)
を連続で呼び出すようにします。
This class has too many methods, consider refactoring it.
メソッド数が多いので警告が出ていました。この警告は不要なので、config/pmd/pmd-project-rulesets.xml を以下のように変更します。
<rule ref="category/java/design.xml"> <exclude name="AvoidThrowingRawExceptionTypes"/> <exclude name="CyclomaticComplexity"/> <exclude name="DataClass"/> <exclude name="LawOfDemeter"/> <exclude name="LoosePackageCoupling"/> <exclude name="NcssCount"/> <exclude name="TooManyMethods"/> <exclude name="UseObjectForClearerAPI"/> <exclude name="UseUtilityClass"/> </rule>
<exclude name="TooManyMethods"/>
を追加します。
Avoid unnecessary constructors - the compiler will generate these for you
以下のように空の public コンストラクタを定義していたら不要との警告でした。コンストラクタの定義を削除します。
It is a good practice to call super() in a constructor
継承クラスのコンストラクタで super();
を呼び出していないという警告でした。super();
の呼び出しを追加します。
A method/constructor should not explicitly throw java.lang.Exception
メソッドに throws Exception
を付けているとこの警告が出ていました。メソッドに付けている throws Exception
を削除し、もしメソッド内から呼び出しているメソッドに throws Exception
が付いていて削除できない場合には、メソッドに @SuppressWarnings("PMD.SignatureDeclareThrowsException")
を付けて警告が出ないようにします。
The constant name 'serialVersionUID' doesn't match '[A-Z][A-Z_0-9]*'
private static final long serialVersionUID = ...
と static final
が付いているので定数と判断されたが、英大文字/数字+スネークケースでないので警告が出ていました。serialVersionUID はこういう宣言だと思うので警告出さなくてもいいと思うのですが。。。 @SuppressWarnings("PMD.FieldNamingConventions")
を付けて警告が出ないようにします。
Useless parentheses.
不要なカッコが書かれているという警告でした。この警告は不要なので、config/pmd/pmd-project-rulesets.xml を以下のように変更します。
<rule ref="category/java/codestyle.xml"> <exclude name="AtLeastOneConstructor"/> <exclude name="ClassNamingConventions"/> <exclude name="CommentDefaultAccessModifier"/> <exclude name="DefaultPackage"/> <exclude name="LongVariable"/> <exclude name="LocalVariableCouldBeFinal"/> <exclude name="MethodArgumentCouldBeFinal"/> <exclude name="OnlyOneReturn"/> <exclude name="ShortVariable"/> <exclude name="UnnecessaryAnnotationValueElement"/> <exclude name="UselessParentheses"/> <exclude name="VariableNamingConventions"/> </rule>
<exclude name="UselessParentheses"/>
を追加します。
Document empty constructor
コンストラクタをオーバーロードしている時に、中身が空でコメントも書かれていないものがあると出る警告でした。// This constructor is intentionally empty. Nothing special is needed here.
というコメントを記述して警告が出ないようにします。
There is log block not surrounded by if
logger.info("★★★ リトライ回数 = " + context.getRetryCount());
のようにlogger で変数を出力する時に {}
を使わずに +
で結合しているために警告が出ていました。logger.info("★★★ リトライ回数 = {}", context.getRetryCount());
という書き方に変更します。
Avoid short class names like ...
クラス名が短い(デフォルトでは5文字以内)と出る警告でした。この警告は不要なので、config/pmd/pmd-project-rulesets.xml を以下のように変更します。
<rule ref="category/java/codestyle.xml"> <exclude name="AtLeastOneConstructor"/> <exclude name="ClassNamingConventions"/> <exclude name="CommentDefaultAccessModifier"/> <exclude name="DefaultPackage"/> <exclude name="LongVariable"/> <exclude name="LocalVariableCouldBeFinal"/> <exclude name="MethodArgumentCouldBeFinal"/> <exclude name="OnlyOneReturn"/> <exclude name="ShortClassName"/> <exclude name="ShortVariable"/> <exclude name="UnnecessaryAnnotationValueElement"/> <exclude name="UselessParentheses"/> <exclude name="VariableNamingConventions"/> </rule>
<exclude name="ShortClassName"/>
を追加します。
Avoid using Literals in Conditional Statements
メソッドの処理内に数値リテラルを直接記述していたので警告が出ていました。定数を定義して、数値リテラルと置き換えます。
Avoid instantiating new objects inside loops
ループ処理内で new でオブジェクトを生成していたので警告が出ていました。@SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
を付けるか、ループの外で生成したオブジェクトをループ内で使い回すように変更します。
Prefer StringBuilder (non-synchronized) or StringBuffer (synchronized) over += for concatenating strings
+=
を使用しているところを StringBuilder か StringBuffer に置き換えるように出た警告でした。StringBuilder を使用するよう変更します。
Assigning an Object to null is a code smell. Consider refactoring.
変数宣言時以外の場所で変数に null をセットしていると出る警告でした。直接 null をセットしないよう実装を変えるようにします。
Avoid using redundant field initializer for 'errcode'
int の変数を宣言した時に 0 をセットしていたのですが、default の初期値なので警告が出ていました。セットしないようにします。
Avoid catching generic exceptions such as NullPointerException, RuntimeException, Exception in try-catch block
catch (Exception e) { ... }
を記述していると出る警告でした。使用している外部ライブラリが Exception を throw するため変更も削除もできないので、`` を付けて警告が出ないようにします。
最後に
これで全ての警告に対応しました。clean タスク実行 → Rebuild Project 実行 → build タスクを実行すると BUILD SUCCESSFUL の文字が出力されます。
config/pmd/pmd-project-rulesets.xml は以下のようになりました。
<?xml version="1.0" encoding="UTF-8"?> <ruleset name="mybraces" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd"> <description>project rulesets</description> <!-- rulesets の種類・説明は 以下の URL 参照 https://github.com/pmd/pmd/tree/master/pmd-java/src/main/resources/category/java https://github.com/pmd/pmd/tree/master/pmd-java/src/main/resources/rulesets/java https://pmd.github.io/pmd-6.7.0/pmd_rules_java.html ※"pmd-6.7.0" の部分は適用しているバージョンに変更すること。 --> <rule ref="category/java/bestpractices.xml"/> <rule ref="category/java/codestyle.xml"> <exclude name="AtLeastOneConstructor"/> <exclude name="ClassNamingConventions"/> <exclude name="CommentDefaultAccessModifier"/> <exclude name="DefaultPackage"/> <exclude name="LocalVariableCouldBeFinal"/> <exclude name="LongVariable"/> <exclude name="MethodArgumentCouldBeFinal"/> <exclude name="OnlyOneReturn"/> <exclude name="ShortClassName"/> <exclude name="ShortVariable"/> <exclude name="UnnecessaryAnnotationValueElement"/> <exclude name="UselessParentheses"/> <exclude name="VariableNamingConventions"/> </rule> <rule ref="category/java/design.xml"> <exclude name="AvoidThrowingRawExceptionTypes"/> <exclude name="CyclomaticComplexity"/> <exclude name="DataClass"/> <exclude name="LawOfDemeter"/> <exclude name="LoosePackageCoupling"/> <exclude name="NcssCount"/> <exclude name="TooManyMethods"/> <exclude name="UseObjectForClearerAPI"/> <exclude name="UseUtilityClass"/> </rule> <rule ref="category/java/documentation.xml"> <!-- CommentRequired はここでは exclude し、下で別途定義する --> <exclude name="CommentRequired"/> <exclude name="CommentSize"/> <exclude name="UncommentedEmptyMethodBody"/> </rule> <rule ref="category/java/documentation.xml/CommentRequired"> <properties> <property name="fieldCommentRequirement" value="Ignored"/> <property name="enumCommentRequirement" value="Ignored"/> </properties> </rule> <rule ref="category/java/errorprone.xml"> <exclude name="BeanMembersShouldSerialize"/> <exclude name="DataflowAnomalyAnalysis"/> <exclude name="LoggerIsNotStaticFinal"/> <exclude name="MissingStaticMethodInNonInstantiatableClass"/> </rule> <rule ref="category/java/multithreading.xml"> <exclude name="UseConcurrentHashMap"/> </rule> <rule ref="category/java/performance.xml"/> <rule ref="category/java/security.xml"/> </ruleset>
履歴
2018/09/21
初版発行。