1. 概要

Apache Maven は、プラグインを使用して、Javaプロジェクトのすべてのビルドおよびレポートタスクを自動化および実行する強力なツールです。

ただし、特にマルチモジュールプロジェクトでは、これらのプラグインのいくつかがさまざまなバージョンや構成とともにビルドで使用される可能性があります。 これにより、プラグインアーティファクトが冗長または重複している複雑なPOMファイルや、さまざまな子プロジェクトに散在する構成の問題が発生する可能性があります。

この記事では、Mavenのプラグイン管理メカニズムを使用してこのような問題を処理し、プロジェクト全体でプラグインを効果的に維持する方法を説明します。

2. プラグインの構成

Mavenには2種類のプラグインがあります。

  • ビルド–ビルドプロセス中に実行されます。 例には、Clean、Install、およびSurefireプラグインが含まれます。 これらは、POMのbuildセクションで構成する必要があります。
  • レポート–さまざまなプロジェクトレポートを作成するためにサイト生成中に実行されます。 例には、JavadocおよびCheckstyleプラグインが含まれます。 これらは、プロジェクトPOMのreportingセクションで構成されます。

Mavenプラグインは、プロジェクトビルドの実行と管理に必要なすべての便利な機能を提供します。

たとえば、POMでJarプラグインを宣言できます。

<build>
    ....
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.2.0</version>
            ....
        </plugin>
    ....
    </plugins>
</build>

ここでは、 build セクションにプラグインを含めて、プロジェクトをjarにコンパイルする機能を追加しています。

3. プラグイン管理

プラグインに加えて、POMのpluginManagementセクションでプラグインを宣言することもできます。 これには、前に見たのとほぼ同じ方法でplugin要素が含まれています。 ただし、 pluginManagement セクションにプラグインを追加することにより、このPOM、およびすべての継承する子POMでプラグインを使用できるようになります。

つまり、子POMは、 plugin セクションでプラグインを参照するだけで、プラグインの実行を継承します。 構成を複製したりバージョンを管理したりすることなく、関連するgroupIdartifactIdを追加するだけです。

依存関係管理メカニズムと同様に、これはプラグインのバージョンと関連する構成を管理するための中央の場所を提供するため、マルチモジュールプロジェクトで特に役立ちます。

4. 例

2つのサブモジュールを持つ単純なマルチモジュールプロジェクトを作成することから始めましょう。 親POMにビルドヘルパープラグインを含めます。これには、ビルドライフサイクルを支援するためのいくつかの小さな目標が含まれています。 この例では、これを使用して、子プロジェクトのプロジェクト出力にいくつかの追加リソースをコピーします。

4.1. 親POM構成

まず、親POMのpluginManagementセクションにプラグインを追加します。

<pluginManagement>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>build-helper-maven-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>add-resource</id>
                    <phase>generate-resources</phase>
                    <goals>
                        <goal>add-resource</goal>
                    </goals>
                    <configuration>
                        <resources>
                            <resource>
                                <directory>src/resources</directory>
                                <targetPath>json</targetPath>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
            </executions>
        </plugin>
   </plugins>
</pluginManagement>

これにより、プラグインのadd-resourceゴールがデフォルトのPOMライフサイクルgenerate-resourcesフェーズにバインドされます。 追加のリソースを含むsrc/resourcesディレクトリも指定しました。 プラグインを実行すると、必要に応じて、これらのリソースがプロジェクト出力のターゲットの場所にコピーされます。

次に、mavenコマンドを実行して、構成が有効であり、ビルドが成功していることを確認しましょう。

$ mvn clean test

これを実行した後、ターゲットの場所にはまだ期待されるリソースが含まれていません。

4.2. 子POM構成

それでは、子POMからこのプラグインを参照しましょう。

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>build-helper-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

依存関係の管理と同様に、バージョンやプラグインの構成は宣言しません。 代わりに、子プロジェクトは親POMの宣言からこれらの値を継承します。

最後に、ビルドを再度実行して、出力を確認しましょう。

....
[INFO] --- build-helper-maven-plugin:3.3.0:add-resource (add-resource) @ submodule-1 ---
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ submodule-1 ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.

[INFO] Copying 1 resource to json
....

ここで、プラグインはビルド中に実行されますが、対応する宣言を持つ子プロジェクトでのみ実行されます。 その結果、プロジェクトの出力には、予想どおり、指定されたプロジェクトの場所からの追加のリソースが含まれるようになりました。

のみ親POMにはプラグイン宣言と構成が含まれ、子プロジェクトは必要に応じてこれを参照するだけであることに注意してください。

子プロジェクトは、必要に応じて継承された構成を自由に変更できます。

5. コアプラグイン

デフォルトでは、ビルドライフサイクルの一部として使用されるMavenコアプラグインがいくつかあります。 たとえば、cleanおよびcompilerプラグインを明示的に宣言する必要はありません。

ただし、これらはPOMのpluginManagement要素で明示的に宣言および構成できます。 主な違いは、コアプラグイン構成が子プロジェクトで参照なしで自動的に有効になることです。

コンパイラプラグインをおなじみのpluginManagementセクションに追加して、これを試してみましょう。

<pluginManagement>
    ....
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.10.0</version>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
        </configuration>
    </plugin>
    ....
</pluginManagement>

ここでは、プラグインのバージョンをロックダウンし、Java8を使用してプロジェクトをビルドするように構成しました。 ただし、子プロジェクトで必要な追加のplugin宣言はありません。 ビルドフレームワークは、デフォルトでこの構成をアクティブにします。 したがって、この構成は、ビルドでJava 8を使用して、すべてのモジュールでこのプロジェクトをコンパイルする必要があることを意味します。

全体として、マルチモジュールプロジェクトで必要なプラグインの構成を明示的に宣言し、バージョンをロックダウンすることは良い習慣です。 したがって、異なる子プロジェクトは、親POMから必要なプラグイン構成のみを継承し、必要に応じてそれらを適用できます。

これにより、重複する宣言が排除され、POMファイルが簡素化され、ビルドの再現性が向上します。

6. 結論

この記事では、プロジェクトの構築に必要なMavenプラグインを一元化および管理する方法について説明しました。

まず、プロジェクトPOMでのプラグインとその使用法を確認しました。 次に、Mavenプラグイン管理メカニズムと、これが重複を減らし、ビルド構成の保守性を向上させるのにどのように役立つかを詳しく調べました。

いつものように、サンプルコードはGitHubから入手できます。