如何从Maven反应堆构建中排除模块?


98

我们有一个Maven 2项目,其中包含许多模块。例:

<modules>
  <module>common</module>
  <module>foo</module>
  <module>data</module>
  <module>bar</module>
  ... more ...
</module>

假设“数据”模块的构建很耗时,并且我们希望在CI服务器构建项目时将其排除在外。当前,我们使用两个pom.xml文件来实现此目的。一个模块中包含所有模块,而另一个模块中所有模块都可以被CI忽略。但这很烦人,因为有时我们忘记将新模块放入两个文件中。

是否有不需要两个单独的模块列表的解决方案?

Answers:


73

最简单的方法是这样使用profiles

<project>
  ...
  <modules>
    <module>common</module>
    <module>foo</module>
    <module>bar</module>
  <modules>
  ...
  <profiles>
    <profile>
      <id>expensive-modules-to-build</id>
      <modules>
        <module>data</module>
      </modules>
    </profile>
  </profiles>
</project>

然后,您应该查看激活个人资料的方式


如果您需要先于普通数据进行数据处理,您会做什么?在这种情况下,概要文件模块将按反应堆顺序放置在默认模块之后。有强制执行命令的模式吗?
彼得·卡恩

9
模块的顺序不是它们在反应堆中出现的顺序。影响顺序的唯一方法是在模块之间创建依赖关系,即使用<dependency>标记。您不能为此依赖声明顺序。
SaM 2012年

7
@SaM实际上,从Maven 3.0.5开始,Reactor 将考虑“模块”中的顺序,尽管依赖关系所指定的顺序具有更高的优先级。
hellodanylo

这将破坏其他一些即使启用了概要文件也无法在概要文件中检测模块的插件
tribbloid

143

使用Maven 3.2.1,您现在可以使用-pl !<module_name>,!<module_name>从反应堆构建中排除某些模块。

请参阅此功能请求:https : //issues.apache.org/jira/browse/MNG-5230


从3.0.4切换到3.2.1是安全的还是有较大的更改?
2014年1

我从3.1升级到3.2.1,没有任何问题。但老实说,您必须进行构建才能解决。
Yogesh_D

30
不要忘记在shell命令行中转义感叹号。它具有非常特殊的含义,请参见unix.stackexchange.com/questions/3747/…–
Pavel

5
不幸的是,Jenkins maven-project插件中当前存在一个不支持反应堆模块排除的未解决问题:issue.jenkins-ci.org/browse/JENKINS-26472
Nick Vanderhoven

@Pavel:或仅使用-代替!,即-pl -<module_name>
msa

45

也可以在mvn命令行上指定要生成的项目。这将消除对单独的pom的需求,但是相反,每次有新模块时,您都必须更改CI配置。

-pl,--projects <arg>                Comma-delimited list of specified
                                    reactor projects to build instead
                                    of all projects. A project can be
                                    specified by [groupId]:artifactId
                                    or by its relative path.

可能是此标志的组合,--also-make-dependents或者--also-make将再次减轻此维护负担。

-am,--also-make                     If project list is specified, also
                                    build projects required by the
                                    list
-amd,--also-make-dependents         If project list is specified, also
                                    build projects that depend on
                                    projects on the list

这与使用两个单独的pom具有相同的问题。我们必须在定义模块的地方。这就是我要避免的事情。
kayahr 2011年

这是一个很好的解决方案。不必更新pom。mvn clean install -pl mysubproject
nicolas-f 2015年

22

我假设您希望默认构建始终构建所有内容,而不管速度如何,以便新开发人员可以快速入门,而不必了解很多有关POM的知识。您可以使用如下配置文件:

<modules>
    <module>common</module>
    <module>foo</module>
    <module>bar</module>
  </modules>
  ...
  <profiles>
    <profile>
      <id>expensive-modules-to-build</id>
      <activation>
         <activeByDefault>true</activeByDefault>
      </activation>
      <modules>
        <module>data</module>
      </modules>
    </profile>
  </profiles>
</project>

这样做的问题是,如果开发人员在命令行上指定了另一个配置文件,expensive-modules-to-build则不包含该配置文件(除非开发人员也指定了它)。这使得记住需要包含哪些配置文件变得很复杂。

这是一种解决方法。由于pom.xml文件始终存在,因此始终包含两个配置文件。因此,要排除昂贵的模块,可以-P!full-build在命令行上使用。

<profiles>
    <profile>
        <id>full-build</id>
        <activation>
            <file>
                <exists>pom.xml</exists>
            </file>
        </activation>
        <modules>
            <module>data</module>
        </modules>
    </profile>
    <profile>
        <id>short-build</id>
        <activation>
            <file>
                <exists>pom.xml</exists>
            </file>
        </activation>
        <modules>
           <module>common</module>
           <module>foo</module>
           <module>bar</module>
        </modules>
    </profile>
</profiles>

好答案。但是在第二个代码示例中,您真的需要两个配置文件吗?更改了激活元素的第一个代码示例中的单个配置文件不起作用吗?
Arend诉Reinersdorff,2015年

@ Arendv.Reinersdorff是的,但是此答案还可以与您可能希望默认包含的其他配置文件一起使用。总体而言,我认为另一个答案-pl !<module_name>,!<module_name>要比这个老答案 更好
artbristol

1
良好的激活技巧。它为我解决了<activeByDefault>并不总是有效的问题!
加布

7

另一个想法:Reactor模块可以嵌套,因此应该可以将快速构建模块和慢速构建模块分组为单独的pom,然后添加另一个包含这两个模块的聚合pom。这样,您的CI服务器只能引用包含快速构建模块的pom。

<artifactId>fast</artifactId>
<modules>
    <module>fast-a</module>
    <module>fast-b</module>
    <module>fast-c</module>
</module>

<artifactId>all</artifactId>
<modules>
    <module>fast</module>
    <module>slow</module>
</module>

1

您可能会使用Maven 配置文件。在构建环境中,我们创建了一个配置文件quick,该配置文件禁用了许多插件和测试执行。

这是通过

    <profile>
        <id>quick</id>
        <properties>
            <skipTests>true</skipTests>
            <!-- others... -->
        </properties>   
        <build>
            <plugins>
                 <!-- configuration... -->
            </plugins>
        </build>
    </profile>

然后我们通过以下方式调用maven

mvn groupId:artifactId:goal -P quick

您可以在模块的pom中禁用编译和其他标准插件以加快速度。


2
是的,对于禁用测试,这很好。但是,如何使用配置文件排除在pom中没有两个单独模块列表的模块?据我所知,我需要将完整的模块列表放入一个概要文件部分,并将快速构建模块列表放入另一个概要文件部分。因此,这与使用两个单独的poms具有相同的问题:我需要维护两个模块列表。
kayahr 2011年

排除模块并不是在maven中做事的真正方法,而我对maven的经验是最好坚持做事的方式,否则您会遇到很多问题...所以我真正建议的是卸下模块,但要减少此模块的耗时。
2011年

Maven的问题在于,“做事方式”通常与“在现实世界中做事的方式”不一致,这使Maven的体验很差很痛苦。开发人员最好接受大量的UX培训。
Ed Randall '18

0

这些人所要求的答案不完全是。我的情况是我只想部署父pom。我spring-boot-thin-layout在子模块中使用。这要求将父模块部署到工件中。我将以下内容添加到我的项目中。它可以跳过install和/或deploy相位。

在我的父母pom中:

<properties>
    <disable.install>true</disable.install>
    <disable.deploy>true</disable.deploy>
    <enable.deployAtEnd>true</enable.deployAtEnd>
</properties>

<profiles>
    <profile>
        <id>deploy-parent</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <disable.install>true</disable.install>
            <disable.deploy>true</disable.deploy>
            <deployAtEnd>${enable.deployAtEnd}</deployAtEnd>
        </properties>
        <build>
            <finalName>${project.version}</finalName>
        </build>
    </profile>
</profiles>

并且在我的子pom中,或您不想与父一起部署的任何模块中:

<properties>
    <maven.install.skip>${disable.install}</maven.install.skip>
    <maven.deploy.skip>${disable.deploy}</maven.deploy.skip>
    <deployAtEnd>${enable.deployAtEnd}</deployAtEnd>
</properties>

因此,当我mvn deploy在父pom上运行时,它将有效地编译所有模块,而不对任何模块运行install,然后最后部署<maven.deploy.skip>${disable.deploy}</maven.deploy.skip>其属性中没有的任何模块。因此,就我而言,仅部署父级。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.