Maven で checkstyle の設定を複数のモジュールで共通にする

checkstyle に限らずですが、ビルド時の設定ファイルを色々なモジュールで共通にしたいと思うことがあると思います。モジュールごとに配置すると管理に手間がかかり、管理が行き届かなくなると内容がバラバラになったりするからです。そうならないよう共通化する方法を紹介します。

Web 上に配置して URL で指定する方法もありますが公開したくない場合もあります。また絶対パス指定の方法もありますが、これもすべての環境のファイルパスを統一するのは手間です。また maven の変数で指定しようとしても、 mvn コマンドを実行した時の作業ディレクトリか、 -f オプションで指定した pom.xml の場所しか取得できず、ルートの pom.xml のディレクトリのパスを確実に取得できないという問題があります。

ですので今回は checkstyle プラグインのドキュメント に書かれている jar としてパッケージ化する方法を紹介します。

実施することは以下の2つです。

  • 設定ファイルのみを持つ jar を作成
  • checkstyle プラグインに依存関係を追加

ディレクトリ構造とファイルの配置

project-root
├ build-tools
│├ src
││└ main
││ └ resources
││  └ app
││   └ checkstyle
││    ├ checkstyle.xml
││    └ checkstyle-suppressions.xml
│└ pom.xml ②
├ build-parent
│└ pom.xml ③
├ app1
│└ pom.xml ④
└ pom.xml ①

ルートモジュール

① の pom はマルチモジュールの最上位の階層の設定です。サブモジュールのパスと、 checkstyle プラグインの基本設定を入れます。以下のように記述します。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.zu_min.app</groupId>
  <artifactId>parent</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>pom</packaging>
  <name>Parent</name>
  <modules>
    <module>build-tools</module>
    <module>build-parent</module>
    <module>app1</module>
    <!-- ... -->
  </modules>
  <properties>
    <checkstyle.plugin.version>3.1.2</checkstyle.plugin.version>
    <checkstyle.version>8.45.1</checkstyle.version>
  </properties>
  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-checkstyle-plugin</artifactId>
          <version>${checkstyle.plugin.version}</version>
          <configuration>
            <!-- (a) -->
            <configLocation>app/checkstyle/checkstyle.xml</configLocation>
          </configuration>
          <dependencies>
            <dependency>
              <groupId>com.puppycrawl.tools</groupId>
              <artifactId>checkstyle</artifactId>
              <version>${checkstyle.version}</version>
            </dependency>
            <dependency> <!-- (b) -->
              <groupId>com.zu_min.app</groupId>
              <artifactId>build-tools</artifactId>
              <version>${project.version}</version>
            </dependency>
          </dependencies>
          <executions>
            <execution> <!-- (c) -->
              <id>validate</id>
              <goals>
                <goal>check</goal>
              </goals>
              <phase>validate</phase>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

  • (a) 次で作成する build-tools モジュールを依存関係に追加します
  • (b) configLocation は build-tools の resources に入った設定ファイルをクラスパスとして指定します。
  • (c) pluginManagement に書いた execution は共通設定のような立ち位置で、そのままでは validate フェーズで実行されません。以下の ③ の pom.xml の設定で使用されます。

設定ファイル用モジュール

② は設定ファイルを格納するモジュールの pom.xml です。以下のように記述します。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.zu_min.app</groupId>
    <artifactId>parent</artifactId>
    <version>1.0.0-SNAPSHOT</version>
  </parent>
  <artifactId>build-configs</artifactId>
  <name>Build Tools</name>
</project>
  • src/main/resources に設定ファイルを持つだけのモジュールです。

ビルド時の実行設定用モジュール

③ は checkstyle の実行設定を記述するための pom.xml です。以下のように記述します。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.zu_min.app</groupId>
    <artifactId>parent</artifactId>
    <version>1.0.0-SNAPSHOT</version>
  </parent>
  <artifactId>build-parent</artifactId>
  <packaging>pom</packaging>
  <name>Build Parent</name>
  <profiles>
    <profile>
      <id>validation</id>
      <activation> <!-- (a) -->
        <activeByDefault>true</activeByDefault>
      </activation>
      <build>
        <plugins>
          <plugin> <!-- (b) -->
            <artifactId>maven-checkstyle-plugin</artifactId>
            <executions>
              <execution>
                <id>validate</id> <!-- (c) -->
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
</project>
  • (a) activeByDefault を true にすることで、 build-parent を継承する各子モジュールでデフォルトで有効になるようにします。
  • (b) checkstyle の execution を設定します。
  • (c) <id>validate</id> の実行設定の詳細は①の pom に書かれています。

子モジュール全部一括で checkstyle を有効化しようとして、ルートの pom.xml ① に checkstyle の execution 設定を入れると、 The projects in the reactor contain a cyclic reference というエラーになってしまいます。そのため、 checkstyle を適用したいモジュールとルートモジュールの間に build-parent というモジュールをはさんでいます。

checkstyle を適用するモジュール

④ は checkstyle を適用するモジュールの pom.xml です。以下のように記述します。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.zu_min.app</groupId>
    <artifactId>build-parent</artifactId> <!-- (a) -->
    <version>1.0.0-SNAPSHOT</version>
    <relativePath>../build-parent/pom.xml</relativePath> <!-- (b) -->
  </parent>
  <artifactId>app1</artifactId>
  <name>App1</name>
</project>
  • (a) 親モジュールを build-parent にします。そうすることで build-parent の設定が継承され、 validate フェーズで checkstyle が実行されるようになります。
  • (b) relativePath のデフォルト値は ../pom.xml なので、build-parent の pom.xml の位置を指定します。

checkstyle 単体で実行する場合

validate フェーズで実行されるので checkstyle 単体で実行することはあまりないかと思いますが、単体で実行する場合は以下の順で実行します。

  1. mvn install
  2. mvn checkstyle:check

build-tools モジュールは先にローカルレポジトリにインストールする必要があります。ですので、 mvn install を先に実施してから mvn checkstyle:check を実行しないと Could not find artifact エラーが発生します。

また設定ファイルの変更を反映した場合、 install するまで反映されないので注意が必要です。

checkstyle.xml 内でのクラスパス指定

checkstyle の設定ファイル内にある SuppressionFilter などでのファイル指定では、頭にスラッシュが必要になります。

  <module name="SuppressionFilter">
    <property name="file" value="/app/checkstyle/checkstyle-suppressions.xml" />
  </module>

checkstyle 以外での使用

同じように plugin の dependencies に設定すれば、 checkstyle 以外でも同じような指定が可能です。たとえば PMD や spotless などがあります。

サンプルソース

少々ディレクトリ構造が異なりますが、こちらにこの記事の検証に使用したコードがあります。

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください