51

ビルド中に同じ一連の Maven プラグイン実行をすべて実行する必要がある一連のプロジェクトがあります。すべてのプロジェクトでこの構成をすべて再宣言することを避けたいので、これらのプラグインの実行 (8 つの異なる mojos) のみを含む親 pom「テンプレート」プロジェクトからすべてを継承させました。しかし、これらのプラグインの実行は子プロジェクトでのみ実行され、Maven ビルド中に親プロジェクトでは実行されないようにしたいと考えています。

私はこの 4 つの異なる方法を実行しようとしましたが、それぞれに好ましくない副作用があります。

  1. 親 pom のbuild/plugins要素でプラグインの実行を宣言し、properties-maven-plugin を使用して、親プロジェクトの他のプラグインのプロパティをオンにします。skipプラグインの目標 (maven-dependency-plugin:build-classpath) の 1 つにskipプロパティがないため、これは機能しませんでした。

  2. 親 pom のbuild/pluginManagement要素でプラグインの実行を宣言します。残念ながら、これには、build/plugins次のように、すべての子プロジェクトの pom の要素で8 つのプラグインのそれぞれを再宣言する必要があります。

    <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
    </plugin>
    ...
    

    これは繰り返しが多すぎて、テンプレート pom のプラグインを変更する必要がある場合に問題になります。

  3. ファイルの欠如によってアクティブ化される親 pom のプロファイルでプラグインの実行を宣言しnobuild.txtます (親 pom に存在するため、プラグインはそこで実行されません)。

    <profiles>
        <profile>
            <activation>
                <file>
                    <missing>nobuild.txt</missing>
                </file>
            </activation>
            <build>
                ....
            </build>
        </profile>
    </profiles>
    

    これは、要素内のファイル パスがプロジェクト ベースのディレクトリではなく、現在の作業ディレクトリmissingに基づいているように見えることを除いて、ほとんどの部分で機能します。これは、私がやりたいマルチモジュールビルドのいくつかを壊します。 編集:明確にするために、親の「テンプレート」プロジェクトは実際にはそれ自体がマルチモジュールプロジェクトのモジュールであり、たとえばルートで a を実行しようとするとビルドが中断します。プロジェクト構造は次のようになります。mvn install

    + job
    |- job-core
    |- job-template
    |- job1                   inherits from job-template
    |- job2                   inherits from job-template
    
  4. カスタム ライフサイクルとパッケージングを設定します。これにより、プラグインをライフサイクルフェーズにバインドできるようですが、構成を指定することはできません

では、複数のプロジェクトで再利用できる一連の Maven プラグイン実行を指定する別の方法はありますか (これらのプロジェクトの各 pom での繰り返しを最小限に抑えます)。

4

5 に答える 5

11

私は、mojo-executorを利用して他のmojoを呼び出す独自のプラグインを作成することになりました。これにより、1)ビルド構成を一元化し、2)各子プロジェクトで複製される構成の量を最小限に抑えることができます。

(このすべての理由に興味がある場合:各子プロジェクトはコマンドラインから実行されるジョブです。ビルドは呼び出し元のシェルスクリプトを設定し、それをビルドにアタッチして、アーティファクトにチェックインされるようにします。リポジトリ。デプロイスクリプトは、後でこれらを実行するマシンにプルダウンします。)

テンプレートプロジェクトのpomの関連部分:

<project ...>
    <parent> ... </parent>
    <artifactId>job-template</artifactId>
    <packaging>pom</packaging>
    <name>job project template</name>
    <build>
        <pluginManagement>
            <plugin>
                <groupId>...</groupId>
                <artifactId>job-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>generate-sources-step</id>
                        <goals><goal>job-generate-sources</goal></goals>
                    </execution>
                    <execution>
                        <id>package-step</id>
                        <goals><goal>job-package</goal></goals>
                    </execution>
                    ... (a couple more executions) ...
                </executions>
            </plugin>
        </pluginManagement>
    </build>
</project>

新しいmaven-pluginプロジェクト(job-maven-plugin)を作成する必要がありました。Pomは次のようになります:

<project ...>
    <parent> ... </parent>
    <artifactId>job-maven-plugin</artifactId>
    <packaging>maven-plugin</packaging>
    <name>job maven executor plugin</name>
    <dependencies>
        <dependency>
            <groupId>org.twdata.maven</groupId>
            <artifactId>mojo-executor</artifactId>
            <!-- version 1.5 supports Maven 2, while version 2.0 only supports Maven 3 -->
            <version>1.5</version>
        </dependency>
    </dependencies>
</project>

テンプレートプロジェクトからわかるように、プラグインには複数のmojoがありました(フェーズごとに1つ、何かが発生する必要がありました)。例として、ジョブパッケージmojoはパッケージフェーズにバインドされ、mojo-executorライブラリを使用して他の2つのmojo(ビルドアーティファクトをアタッチするだけ)を実行します。

/**
 * @goal job-package
 * @phase package
 */
public class PackageMojo extends AbstractMojo {
    /**
     * @parameter expression="${project}"
     * @required
     * @readonly
     */
    protected MavenProject project;
    /**
     * @parameter expression="${session}"
     * @required
     * @readonly
     */
    protected MavenSession session;
    /**
     * @component
     * @required
     */
    protected PluginManager pluginManager;

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        ExecutionEnvironment environment = executionEnvironment(project, session, pluginManager);

        // Attach script as a build artifact
        executeMojo(
            plugin(
                groupId("org.codehaus.mojo"),
                artifactId("build-helper-maven-plugin"),
                version("1.7")
            ),
            goal("attach-artifact"),
            configuration(
                element("artifacts",
                    element("artifact",
                        element("file", "${project.build.directory}/script.shl"),
                        element("type", "shl")
                    )
                )
            ),
            environment
        );

        // Zip up the jar and script as another build artifact
        executeMojo(
            plugin(
                groupId("org.apache.maven.plugins"),
                artifactId("maven-assembly-plugin"),
                version("2.3")
            ),
            goal("single"),
            configuration(
                element("descriptors",
                    element("descriptor", "${project.build.directory}/job/descriptor.xml")
                )
            ),
            environment
        );
    }
}

次に、子プロジェクトでは、プラグインを1回参照するだけです。私の意見では、これは、すべての子プロジェクトの舞台裏のプラグインのそれぞれを繰り返すよりも非常に望ましいです(これにより、pom間の結合が許容できないほど増加します)。将来、ビルドプロシージャにmojo実行を追加したい場合は、1つの場所を変更して、バージョン番号を上げるだけで済みます。子プロジェクトのpomは次のようになります。

<project ...>
    <parent>
        <groupId> ... </groupId>
        <artifactId>job-template</artifactId>
        <version> ... </version>
        <relativePath>../job-template</relativePath>
    </parent>
    <artifactId>job-testjob</artifactId>
    <name>test job</name>
    <build>
        <plugins>
            <plugin>
                <groupId> ... </groupId>
                <artifactId>job-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

また、マルチモジュールディレクトリ構造全体は次のようになります。

+- job
  +- job-core
  +- job-maven-plugin
  +- job-template
  +- job-testjob1               (inherits from job-template)
  +- job-testjob2               (inherits from job-template)

私の意見では、プラグイン構成がpomではなく一連のmojoに埋め込まれているため、このソリューションは完全に最適ではありませんが、構成を一元化し、子プロジェクトpom間の重複を最小限に抑えるという私の目標を満たしています。

(最後の注意: pomで複数のプラグインの実行をグループ化できるように見えるmaven-aggregate-pluginを発見しました。これにより、問題が少し望ましい方法で解決された可能性がありますが、最後のプラグインをやり直す気にはなりません。数時間の作業ですが、他の人にとっては有益かもしれません。)

于 2012-10-17T23:52:54.370 に答える
5

個人的には解決策2を選びます。繰り返しは最小限であり、可能であれば、どのプロジェクトでどのプロファイルをアクティブ化する必要があるかを文書化する必要がないように、プロファイルを避けるようにしてください。

を実行するだけで、プロジェクトを正しくビルドできるはずmvn (clean) installです。

于 2012-10-17T15:11:53.197 に答える
1

もう 1 つのオプション: 「スキップ」プロパティを使用する代わりに、実行が のような存在しない値にバインドされるフェーズを変更できますnever

<inherited>false</inherited>これは、@Timiによって提案されたアプローチと一緒に非常にうまく機能します

于 2017-10-05T12:55:44.613 に答える