ふるてつのぶろぐ

福岡在住のエンジニアです。

写真提供:福岡市

いまだにJava 8 備忘録 - CheckstyleとFormatterの使い方(Google Styleguide)

今日すること

こんにちはふるてつです。

きょうはCheckstyleFormatterのおはなしをします。
f:id:tetsufuru:20210314215338p:plain
わたしは客先に常駐するタイプの仕事をしていてどこの客先でもCheckstyleは見かけます。
慣れているはずですが自分でいちから設定するといつもCheckstyle設定とFormatterとで、つじつまが合わなくなり途中でやめてしまいます。

みなさんそのような経験はないですか?😑

わたしのような不器用なかたはCheckstyleFormatterの両方ともに「google提供の設定ファイル」を使うのがおすすめです。
わたしは EclipseGradleを使っていますので、GradleでのCheckstyle設定についても最後の方に書きたいと思います。

1. EclipseCheckstyle pluginの設定

Checkstyle pluginを使うと Eclipse の画面上でチェック結果を確認できます。
一番なじみのある使い方だと思います。

1 - 1. Checkstyle Plugin をインストール

まずは EclipseCheckstyle Pluginをインストールします。
Eclipse のメニューから「ヘルプ」-「Eclipseマーケットプレイス」を選びます。
f:id:tetsufuru:20210318015343p:plain

そして「Eclipseマーケットプレイス」の画面で「checkstyle」などのキーワードで検索して下記のようにインストールします。
いまバージョンは 8.36.1 が最新のようです。
f:id:tetsufuru:20210317005211p:plain

※ここで注意点ですが、おなじEclipseでも Pleiades のオールインワンを使っているかたは、すでにビルトインでCheckstyle Pluginが入っています。
マーケットプレイスからさらにインストールすると競合して動かなくなるので注意しましょう。

いまの環境にCheckstyle Pluginが入っているかどうかは設定画面で確認します。
下記の左側メニューに「Checkstyle」が表示されている場合はすでに入っていますのでインストールする必要はありません。
f:id:tetsufuru:20210318015651p:plain

1 - 2. Checkstyleの設定ファイル「google_checks.xml」をダウンロード

次にCheckstyleの git から googleCheckstyleの設定ファイルを入手します。

Checkstyleの git はこちらになります。
f:id:tetsufuru:20210318020751p:plain
https://github.com/checkstyle/checkstyle

チェックスタイル本体とプラグインのバージョンは若干づれていてプラグインが少し遅れ気味です。
ダウンロードする際はバージョンに気をつけてください。
Eclipseにインストールしたプラグインより上のバージョンのファイルを使うとCheckstyleが動かないことがあります。

そこで上の git の写真の右側にある「Releases」のところからプラグインと同じバージョンの checkstyle-8.36.1 を選んで「Source code(zip)」をダウンロードして中身を展開しておきます。
f:id:tetsufuru:20210317011620p:plain
https://github.com/checkstyle/checkstyle/releases/tag/checkstyle-8.36.1

1 - 3. Eclipse に設定ファイル「google_checks.xml」を配置

次に Eclipse のプロジェクト直下にCheckstyleの設定ファイル用のフォルダを作成します。
置き場所はデフォルトで名前が決まっていて下記になります。

[プロジェクト直下]/config/checkstyle/

こちらのフォルダに checkstyle-8.36.1 中の src/main/resources/ から「google_checks.xml」をコピーします。

checkstyle-8.36.1の中(コピー元です)
f:id:tetsufuru:20210317092937p:plain

Eclipseのworkspaceの中(コピー先です)
f:id:tetsufuru:20210317095657p:plain

1 - 4. Checkstyleの新規構成を作成

では設定を取り込みます。
Eclipse のメニューから「ウィンドウ」-「設定」を選んで設定画面を開きます。
設定画面の左側メニューから「Checkstyle」をクリックすると下記の画面になります。
f:id:tetsufuru:20210318021359p:plain

すでにグローバルチェック構成のところに「Google Checks」はビルトインで入っていますが、Gradle側と設定を共有したいのでビルトインは使いません。
「新規」ボタンをクリックして
「型」は外部構成ファイル
「名前」は小文字の google_checks
「ロケーション」はEclipseのプロジェクトに置いた「google_checks.xml」を選びます。
f:id:tetsufuru:20210317102130p:plain

OKをクリックすると警告が出ますがそのまま「続行」をクリックして新規作成を完了します。
f:id:tetsufuru:20210318021534p:plain

新しく小文字の google_checks が増えたのでこれを「デフォルトとして設定」しておきます。
下記のような感じになります。
f:id:tetsufuru:20210318021646p:plain

これでCheckstyleのルール設定が新しくなりました。
あとは自動で検査が始まって、Checkstyle違反があるとパッケージエクスプローラーにマークがでると思います。
エラーの例(工事中のような!アイコンがでてきます)
f:id:tetsufuru:20210318022813p:plain

なにも出てこなければパッケージエクスプローラーでプロジェクトを「右クリック」-「Checkstyle」-「Checkstyle でコードチェック」を手動でおこなってみてください。
f:id:tetsufuru:20210318024327p:plain

あとメニューから「ビュー」の表示で「Checkstyle 違反」も見れるようにしておくといいと思います。
f:id:tetsufuru:20210317104003p:plain

1 - 5. Checkstyleの除外設定

Checkstyle Pluginの除外設定について説明しておきます。
除外設定は画面から行います。
設定方法ですが、まずパッケージエクスプローラーでプロジェクトを「右クリック」-「プロパティ」を開きます。
プロパティ画面左側のメニューで「Checkstyle」を選ぶと下記の画面のようにCheckstyle画面が表示されます。
※「ウィンドウ」-「設定」から表示される画面と似ているので間違えないようにしてください。
f:id:tetsufuru:20210318025231p:plain

上記画面で「パッケージのファイル」をクリック、「変更」ボタンをクリックします。
フィルターの画面が表示されるので除外するパッケージをチェックします。
f:id:tetsufuru:20210318025804p:plain

こちらはわたしの例になりますがMyBatisで自動作成した entity や repository のパッケージを除外しています。

2. Formatter設定

2 - 1. 設定ファイルのダウンロードとライセンスについて

次はFormatterの設定を行います。
Googleが提供しているStyleguideを使用します。
こちらのサイトです。
f:id:tetsufuru:20210319021230p:plain https://github.com/google/styleguide

このなかの「eclipse-java-google-style.xml」をダウンロードしてきます。
このファイルは最終更新日が3年前になっています、だいぶ以前からあったようです。
わたしもっと早く気づけばよかったですねぇ😎

ファイルの置き場所はCheckstyleに合わせて config の下に formatter のフォルダを作ってそこに置きます。

[プロジェクト直下]/config/formatter/

f:id:tetsufuru:20210319032414p:plain

ちなみにStyleguideの README にライセンスのことが書いてありこのファイルは「CC-By 3.0 License」とのことです。
f:id:tetsufuru:20210319031157p:plain

これは「クリエイティブコモンズライセンス」といいます。
大まかに説明すると、原作者のクレジット(氏名、作品タイトルなど)を表示すれば、自由にしていいライセンスです。
商業的にも問題ありませんし、修正も可能です。

そこでクレジットを「eclipse-java-google-style.xml」ファイルに追加します。
下記のように2行目にコメントで追加しておきます。
名前と取得元のURLを英語で書いた感じで良いと思います、これでライセンス的に問題なく使えるはずです。

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- ここから
    Used this style from Google Style Guides.
    That can be found at https://github.com/google/styleguide
-->  ここまで
<profiles version="13">
以下省略

ちなみにもしソースを git で公開する場合は READMEに使っている旨をひとこと書いた方が良いと思います。
あと補足になりますが、クリエイティブコモンズライセンスについて詳しくは下記を参照ください。
クリエイティブ・コモンズ・ライセンスとは | クリエイティブ・コモンズ・ジャパン

2 - 2. 設定ファイルをインポート

では次に保存した設定ファイル「eclipse-java-google-style.xml」をインポートします。
Eclipse のメニューから「ウィンドウ」-「設定」を選んで設定画面を開きます。
設定画面の左側メニューで「Java」- 「コードスタイル」-「フォーマッター」を選びます。
f:id:tetsufuru:20210319033802p:plain

フォーマッターの画面で「インポート」ボタンをクリックして「eclipse-java-google-style.xml」をインポートします。
インポートが終わると「アクティブなプロファイル」の欄に「GoogleStyle」と表示されます。
f:id:tetsufuru:20210319034650p:plain

2 - 3. 保存アクションの設定

いったんインポートは終わりですが、「保存アクション」の設定も変えておきます。
設定画面の左側メニューで「Java」- 「エディター」「保存アクション」を選びます。
f:id:tetsufuru:20210319035535p:plain

上記のように保存アクション画面で保存時にソースコードのフォーマットを行うように設定します。
これで保存時に毎回Formatterソースコードをフォーマットするようになりました。
補足になりますが、わたしは「インポートの構成」もチェックONにしています。
「インポートの構成」をONにするとソースコードの保存時に Eclipse が自動でインポート文の並び順を調整します。
しかし今度はCheckstyleと合わなくなり、結局Checkstyleの設定ファイルを修正してCustomImportOrderの定義をコメントアウトしました。
同じように設定する場合、参考にしてください。

google_checks.xml の編集内容

<!--
<module name="CustomImportOrder"> ↓ ここからをコメントアウト
    <property name="sortImportsInGroupAlphabetically" value="true"/>
    <property name="separateLineBetweenGroups" value="true"/>
    <property name="customImportOrderRules" value="STATIC###THIRD_PARTY_PACKAGE"/>
    <property name="tokens" value="IMPORT, STATIC_IMPORT, PACKAGE_DEF"/>
</module> ↑ ここまでをコメントアウト
-->

3. GradleでのCheckstyle設定

ではGradleでのCheckstyle設定を説明します。
同じCheckstyleですが、最初に書いた「Eclipseマーケットプレイス」からインストールしたリアルタイムで動くほうのCheckstyle Pluginとは別物と思ってください。
こちらはリアルタイムではなくGradlebuildコマンドを実行したときにバッチ実行されてソースをチェックします。
ビルドをせずチェックのみをおこないたい場合はcheckコマンドで単独で実行できます。

Gradleで使うCheckstyleのサイトはこちらになります。
f:id:tetsufuru:20210319210428p:plain
https://docs.gradle.org/current/userguide/checkstyle_plugin.html

3 - 1. Gradleの設定ファイルにcheckstyleを追加する

ではまず build.gradle ファイルにcheckstyleの設定を追加します。

シングルプロジェクトの場合

プロジェクトが一つだけの普通のプロジェクトの場合はあたらしい書き方ができます。
バージョンや設定ファイルの定義は plugins{ } の下の checkstyle { } の中の Extension 部分に書きます。
プラグインのバージョンは toolVersion で定義します。
Gradleで使うcheckstyleの最新バージョンは現在 '8.41' ですが、わたしはリアルタイムで動くほうのCheckstyle Pluginと同じに合わせたかったので '8.36.1'にしています。
設定ファイルも同一ファイルを使いたいので同じ「google_checks.xml」を指定します。

build.gradle の内容

plugins {
    id 'checkstyle'
}
checkstyle {
    toolVersion = '8.36.1'
    configFile = rootProject.file('config/checkstyle/google_checks.xml')
}

マルチプロジェクトの場合

Gradleでは複数のプロジェクトまとめることができます。
この場合はあたらしい書き方にはまだできないので少し古い書き方になり、subprojects の中に追加します。
内容を少し簡略化していますが下記のような感じになります。
バージョンや設定ファイルはシングルプロジェクトと同じ書き方になります。

build.gradle の内容

subprojects {
    apply plugin: 'checkstyle'

    checkstyle {
        toolVersion = '8.36.1'
        configFile = rootProject.file('config/checkstyle/google_checks.xml')
    }
}
project(':biz') {}

project(':example_project') {
    dependencies {
        implementation project(':biz')
    }
}

3 - 2. チェックスタイルの除外設定ファイルを作成

Gradleで動かすcheckstyleの除外設定はファイルで行います。
設定のサンプルがcheckstyleの git にあります、こちらです。
f:id:tetsufuru:20210319214655p:plain
https://github.com/checkstyle/checkstyle/blob/master/config/suppressions.xml

これをひな型にしてチェックから除外したいパッケージやファイル名を指定します。
具体的は内容ですが例えばわたしはMyBatisで自動作成した entity や repository のパッケージを除外しています。
ほかにはMyBatis Generator の設定ファイルも除外しています「generationConfig.xml
下記を参考にしてみてください。

suppressions.xml の内容例

<?xml version="1.0"?>

<!DOCTYPE suppressions PUBLIC
    "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
    "https://checkstyle.org/dtds/suppressions_1_2.dtd">

<suppressions>
    <suppress checks=".*" files="com[\\/]example[\\/]demo[\\/]entity[\\/]domain[\\/]"/>
    <suppress checks=".*" files="com[\\/]example[\\/]demo[\\/]repository[\\/]"/>
    <suppress checks=".*" files="generationConfig.xml"/>
</suppressions>

あと除外ファイルの置き場所は「google_checks.xml」と同じ場所にしたいので下記フォルダ内にします。

[プロジェクト直下]/config/checkstyle/

名前もそのまま「suppressions.xml」として、下図のように保存しておきます。
f:id:tetsufuru:20210319221157p:plain

3 - 3. google_checks.xml ファイルを再編集

最後に「google_checks.xml」ファイルの中を再び編集して「suppressions.xml 」とリンクさせます。
module name = "Checker" のタグの中に、module name="SuppressionFilter" と書いてあるタグがあります。
そこの property の file を書き換えます。
google_checks.xmlの変更前

<!-- https://checkstyle.org/config_filters.html#SuppressionFilter -->
<module name="SuppressionFilter">
    <property name="file" value="${org.checkstyle.google.suppressionfilter.config}"
              default="checkstyle-suppressions.xml" />
    <property name="optional" value="true"/>
</module>

google_checks.xmlの変更後

<!-- https://checkstyle.org/config_filters.html#SuppressionFilter -->
<module name="SuppressionFilter">
    <property name="file" value="${config_loc}/suppressions.xml"/>   <!-- この行を書き換え -->
    <property name="optional" value="true"/>
</module>

${config_loc}Checkstyleのビルトインのプロパティでプロジェクト直下のconfigフォルダの意味になります。

3 - 4. Gradle で build コマンドを実行

これで一通りの設定が終わりました。
では build コマンドを実行してみます、プロジェクト直下で gradle のラッパーのコマンドを実行します。

gradlew build

実行結果はプロジェクト直下/build/reports/checkstyle/ に html ファイルが出力されます。
main.html を開いてみます、だいぶ割愛していますが下のようなイメージになります。

Checkstyleレポートの例
f:id:tetsufuru:20210319224317p:plain

感想


おつかれさまでした。
今回はCheckstyleFormatterについて書きました。
わたしはCheckstyleが長いこと苦手で、いままで避けてとおってきましたがブログにこうやって書くことで整理でき、やっと苦手を克服できたかなと思います。
Checkstyleをいちから設定する機会はそれほど多くはないと思いますので、少しでも皆さんの参考になればと思います。

それではまた😎