1. 概要

Maven multi-module プロジェクトでは、効果的なPOMは、モジュールとその親内で定義されたすべての構成をマージした結果です。

モジュール間の冗長性や重複を避けるために、共有の親で共通の構成を維持することがよくあります。 ただし、すべての兄弟に影響を与えずに子モジュールのカスタム構成を作成する必要がある場合は、問題が発生する可能性があります。

このチュートリアルでは、親プラグイン構成をオーバーライドする方法を学習します。

2. デフォルトの構成の継承

プラグイン構成により、プロジェクト間で共通のビルドロジックを再利用できます。 親がプラグインを持っている場合、子は追加の構成なしで自動的にプラグインを持ちます。 これは継承のようなものです。

これを実現するために、MavenはXMLファイルを要素レベルでマージします。 子が異なる値の要素を定義すると、親の要素が置き換えられます。 これを実際に見てみましょう。

2.1. プロジェクト構造

まず、実験するマルチモジュールMavenプロジェクトを定義しましょう。 私たちのプロジェクトは、1人の親と2人の子供で構成されます。

+ parent
     + child-a
     + child-b

モジュール間で異なるJavaバージョンを使用するようにmaven-compiler-pluginを構成するとします。 一般にJava11を使用するようにプロジェクトを構成しますが、子-はJava8を使用します。

構成から始めます。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>11</source>
        <target>11</target>
        <maxmem>512m</maxmem>
    </configuration>
</plugin>

ここでは、これも使用する追加のプロパティmaxmemを指定しました。 ただし、child-aには独自のコンパイラ設定が必要です。

それでは、child-aをJava8を使用するように構成しましょう。

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

例ができたので、これが効果的なPOMにどのように影響するかを見てみましょう。

2.2. 効果的なPOMを理解する

有効なPOMは、継承、プロファイル、外部設定などのさまざまな要因の影響を受けます。 実際のPOMを確認するために、child-aディレクトリからmvnhelp:effective-pomを実行してみましょう。

mvn help:effective-pom

...
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <maxmem>512m</maxmem>
    </configuration>
</plugin>

予想どおり、 child-a には、sourceおよびtarget値の独自のバリエーションがあります。 ただし、もう1つの驚きは、親からのmaxmemプロパティも持っていることです。

これは、子プロパティが定義されている場合はそれが優先され、それ以外の場合は親プロパティが使用されることを意味します。

3. 高度な構成の継承

マージ戦略を微調整する場合は、属性を使用できます。 これらの属性は、制御するXML要素に配置されます。 また、それらは継承され、第1レベルの子にのみ影響します。

3.1. リストの操作

前の例では、子の値が異なる場合に何が起こるかを確認しました。 ここで、子が異なる要素のリストを持っている場合を見ていきます。 例として、maven-resources-pluginを使用して複数のリソースディレクトリを含める方法を見てみましょう。

ベースラインとして、[X31X]parent-resourcesディレクトリのリソースを含めるようにparentを構成しましょう。

<plugin>
    <artifactId>maven-resources-plugin</artifactId>
    <configuration>
        <resources>
            <resource>
                <directory>parent-resources</directory>
            </resource>
        </resources>
    </configuration>
</plugin>

この時点で、child-aはこのプラグイン構成をその親から継承します。 ただし、child-aの代替リソースディレクトリを定義したいとします。

<plugin>
    <artifactId>maven-resources-plugin</artifactId>
    <configuration>
        <resources>
            <resource>
                <directory>child-a-resources</directory>
            </resource>
        </resources>
    </configuration>
</plugin>

それでは、効果的なPOMを確認しましょう。

mvn help:effective-pom
...
<configuration>
    <resources>
        <resource>
            <directory>child-a-resources</directory>
        </resource>
    </resources>
</configuration>

この場合、リスト全体が子構成によってオーバーライドされます

3.2. 親構成を追加する

おそらく、一部の子に共通のリソースディレクトリを使用し、追加のリソースディレクトリを定義してもらいたいと考えています。 このために、親のresources要素でcombine.children =” append” を使用して、親構成を追加できます。

<resources combine.children="append">
    <resource>
        <directory>parent-resources</directory>
    </resource>
</resources>

したがって、有効なPOMには次の両方が含まれます。

mvn help:effective-pom
....
<resources combine.children="append">
    <resource>
        <directory>parent-resources</directory>
    </resource>
    <resource>
        <directory>child-a-resources</directory>
    </resource>
</resources>

組み合わせ属性は、ネストされた要素に伝播されません。 したがって、 resources セクションが複雑な構造である場合、ネストされた要素はデフォルトの戦略を使用してマージされます。

3.3. 子構成をオーバーライドする

前の例では、親の結合戦略のために、子は最終的なPOMを完全に制御していませんでした。 子は、 resources 要素にcombine.self=” override” を追加することで、親を無効にすることができます。

<resources combine.self="override">
    <resource>
        <directory>child-a-resources</directory>
    </resource>
</resources>

この場合、子は制御を取り戻します。

mvn help:effective-pom
...
<resources combine.self="override">
    <resource>
        <directory>child-a-resources</directory>
    </resource>
</resources>

4. 継承できないプラグイン

前の属性は微調整には適していますが、子が親と完全に一致しない場合は適切ではありません。

プラグインがまったく継承されないようにするために、親レベルでプロパティfalse追加できます。

<plugin>
    <inherited>false</inherited>
    <groupId>org.apache.maven.plugins</groupId>
    ...
</plugin>

これは、プラグインが親にのみ適用され、その子には伝播されないことを意味します。

5. 結論

この記事では、親プラグインの構成をオーバーライドする方法を説明しました。

まず、デフォルトの動作を調べました。 次に、親がマージポリシーを定義する方法と、子がそれを拒否する方法を確認しました。 最後に、すべての子がプラグインをオーバーライドする必要がないように、プラグインを継承不可としてマークする方法を確認しました。

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