在父pom中定义Maven插件,但仅在子项目中调用插件

在父pom中定义Maven插件,但仅在子项目中调用插件,maven,build-process,Maven,Build Process,我有一组项目,它们都需要在构建过程中运行相同系列的Maven插件执行。我希望避免在每个项目中重新声明所有这些配置,所以我让它们都继承自父pom“模板”项目,该项目只包含那些插件执行(8种不同的MOJO)。但是我希望在Maven构建期间,这些插件执行只在子项目上运行,而不是在父项目上运行 我尝试了四种不同的方法来实现这一点,每种方法都有我不喜欢的副作用 在父pom的build/plugins元素中声明插件执行,并在父项目中使用属性maven-plugin。这不起作用,因为其中一个插件目标(mave

我有一组项目,它们都需要在构建过程中运行相同系列的Maven插件执行。我希望避免在每个项目中重新声明所有这些配置,所以我让它们都继承自父pom“模板”项目,该项目只包含那些插件执行(8种不同的MOJO)。但是我希望在Maven构建期间,这些插件执行只在子项目上运行,而不是在父项目上运行

我尝试了四种不同的方法来实现这一点,每种方法都有我不喜欢的副作用

  • 在父pom的
    build/plugins
    元素中声明插件执行,并在父项目中使用属性maven-plugin。这不起作用,因为其中一个插件目标(maven dependency plugin:build classpath)没有
    skip
    属性

  • 在父pom的
    build/pluginManagement
    元素中声明插件执行。不幸的是,这需要我重新声明每个子项目pom的
    build/plugins
    元素中的八个插件,如:

    <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
    </plugin>
    ...
    
    除了
    missing
    元素中的文件路径似乎基于当前工作目录而不是项目basedir之外,这在大多数情况下都有效。这打破了我希望能够完成的一些多模块构建编辑:为了澄清,父“模板”项目本身实际上是多模块项目中的一个模块,当我尝试(例如)在根目录上执行
    mvn安装时,构建中断。项目结构如下所示:

    + job
    |- job-core
    |- job-template
    |- job1                   inherits from job-template
    |- job2                   inherits from job-template
    
    <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>
    
    <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>
    
  • 设置自定义生命周期和打包。这似乎允许我将插件绑定到生命周期阶段


  • 那么,有没有另一种方法来指定一组Maven插件执行,这些执行可以跨多个项目重用(在每个项目的POM中重复最少)?

    我个人会选择解决方案2。重复是最小的,如果可能的话,你应该尽量避免配置文件,以避免必须开始记录哪些项目需要激活哪些配置文件


    一个项目应该能够通过简单的
    mvn(clean)安装来正确构建

    我最终编写了自己的插件,利用它来调用其他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>
    
    然后,在子项目中,我只需要引用插件一次。在我看来,这比在每个子项目中重复每个幕后插件要好得多(这不可接受地增加了POM之间的耦合)。如果我想在将来将mojo执行添加到构建过程中,我只需要修改一个位置并修改一个版本号。子项目的pom看起来像:

    + job
    |- job-core
    |- job-template
    |- job1                   inherits from job-template
    |- job2                   inherits from job-template
    
    <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>
    
    <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>
    
    在我看来,这个解决方案并不是完全最优的,因为我现在在一系列mojo中嵌入了插件配置,而不是pom,但它满足了我集中配置和最小化子项目pom之间重复的目标


    (最后一点注意:我刚刚发现,这似乎允许在pom中对多个插件执行进行分组。这可能会以更理想的方式解决问题,但我没有心情重做最后几个小时的工作。不过,这可能对其他人有益。)

    我在寻找同一问题的解决方案时发现了另一个选择。我之所以将其发布在这里,是因为这已经是一个很好的选项集合-希望它可以帮助其他人不必花费数小时来解决此问题:

    如果插件有跳过执行的选项,则可以在父pom(部分)中打开该选项,并将“继承”标志设置为false,以便它不会传播到子级:

    <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <executions>
            <execution>
                <id>make-assembly</id>
                <phase>package</phase>
                <goals>
                    <goal>single</goal>
                </goals>
                <inherited>true</inherited>
                <configuration>
                   ...
                </configuration>
            </execution>
        </executions>
        <!-- Skip plugin execution for parent pom but enable it for all children -->
        <configuration>
            <skipAssembly>true</skipAssembly>
        </configuration>
        <inherited>false</inherited>
    </plugin>
    
    
    maven汇编插件
    组装
    包裹
    单一的
    真的
    ...
    真的
    假的
    

    当我第一次读到这个解决方案时,我对它非常怀疑,但它对我来说是有效的——至少对汇编插件是如此。

    还有一个选择:你可以不使用“跳过”属性,而改为将执行绑定到一个不存在的值,如
    never


    这与@Timi

    建议的
    false
    方法配合使用非常好。这里是第五种方法。我认为它有最小的缺点:没有概要文件,没有定制的生命周期,在子POM中没有声明,对插件没有“跳过”要求

    抄袭自——非常感谢

    
    org.apache.maven.plugins
    maven checkstyle插件
    2.9.1
    代码检查
    编译
    检查
    org.apache.maven.plugins
    maven checkstyle插件
    假的
    代码检查
    没有一个
    
    您的pare的
    是什么
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <!-- Main declaration and configuration of the plugin -->
                    <!-- Will be inherited by children -->
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-checkstyle-plugin</artifactId>
                    <version>2.9.1</version>
                    <executions>
                        <execution>
                            <!--This must be named-->
                            <id>checkstyle</id>
                            <phase>compile</phase>
                            <goals>
                                <goal>check</goal>
                            </goals>
                        </execution>
                    </executions>
                    <!-- You may also use per-execution configuration block -->
                    <configuration...>
                </plugin>
            </plugins>
        </pluginManagement>
        <plugins>
            <plugin>
                <!-- This declaration makes sure children get plugin in their lifecycle -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-checkstyle-plugin</artifactId>
                <!-- Configuration won't be propagated to children -->
                <inherited>false</inherited>
                <executions>
                    <execution>
                        <!--This matches and thus overrides execution defined above -->
                        <id>checkstyle</id>
                        <!-- Unbind from lifecycle for this POM -->
                        <phase>none</phase>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>