在 Maven 构建期间跳过子模块

Posted

技术标签:

【中文标题】在 Maven 构建期间跳过子模块【英文标题】:Skip a submodule during a Maven build 【发布时间】:2012-01-08 09:36:09 【问题描述】:

我们需要能够在某些环境中跳过子模块。

有问题的模块包含集成测试,需要半小时才能运行。因此,我们希望在 CI 服务器上构建时包含它,但是当开发人员在本地构建(并运行测试)时,我们希望跳过该模块。

有没有办法通过配置文件设置来做到这一点?我进行了一些谷歌搜索并查看了此处的其他问题/答案,但没有找到好的解决方案。

我想一种选择是完全从父 pom.xml 中删除该子模块,然后在我们的 CI 服务器上添加另一个项目来构建该模块。

建议?

【问题讨论】:

为什么不用 Maven 方式?对我来说,这是一个完全有效的主张。 嗯。现在我找不到人们似乎反对这一点的地方......所以我更新了我原来的问题,以删除我声称这似乎不是“Maven 方式”的说法。 【参考方案1】:

Maven 3.2.1 版本增加了这个功能,你可以使用-pl 开关(shortcut 用于--projects 列表)和!-(source)来排除某些子模块。

mvn -pl '!submodule-to-exclude' install
mvn -pl -submodule-to-exclude install

在 bash 角色时要小心!是一个特殊字符,所以你要么必须单引号(就像我做的那样),要么用反斜杠字符转义它。

排除多个模块的语法与包含相同

mvn -pl '!submodule1,!submodule2' install
mvn -pl -submodule1,-submodule2 install

EDIT Windows 似乎不喜欢单引号,但在 bash 中是必须的;在 Windows 中,使用双引号(感谢 @awilkinson)

mvn -pl "!submodule1,!submodule2" install

【讨论】:

重要:如果要排除嵌套子模块,需要使用合格版本mvn -pl !com.acme:nestedmodule1 -pl 选项需要 '[groupId]:' 在 artifactId 之前,所以我们应该使用 mvn -pl '!:submodule-to-exclude' install 你也可以使用mvn -pl '!path/to/submodule/directory',不使用groupId和artifactId。如果submodule1submodule2 位于当前目录中,我的答案有效。 如果您在mvn install 中使用-pl,那么您可能还需要将它用于mvn deploy,这也是毫无价值的 以下适用于 Windows 机器。 mvn -pl "!submodule1,!submodule2" clean install【参考方案2】:

当然,这可以使用配置文件来完成。您可以在父 pom.xml 中执行以下操作。

  ...
   <modules>
      <module>module1</module>
      <module>module2</module>  
      ...
  </modules>
  ...
  <profiles>
     <profile>
       <id>ci</id>
          <modules>
            <module>module1</module>
            <module>module2</module>
            ...
            <module>module-integration-test</module>
          </modules> 
      </profile>
  </profiles>
 ...

在您的 CI 中,您将使用 ci 配置文件运行 maven,即 mvn -P ci clean install

【讨论】:

优秀的答案!我不知道为什么我很难从 Maven 文档中找到这个。我要提出的一个建议是,因为我更喜欢默认运行集成测试,所以我将activeByDefault 添加到该配置文件中,然后必须添加另一个空配置文件(例如skip-integration-tests)才能跳过它们。 有什么方法可以在不复制所有共享内容的情况下做到这一点? 请注意,如果您使用 maven-release-plugin,它似乎不会更新隐藏在配置文件开关后面的子模块的版本号。您可以拥有与项目的其余部分不同版本号的子模块... 不幸的是,使用配置文件您不能排除之前在 pom.xml 的主要 部分中提到的模块。 JIRA issues.apache.org/jira/browse/MNG-5230(和整个 pom 结构)可以通过更仔细的思考得到更好的完全实现。 这个解决方案真的有效吗?至少我不能让它工作。好像我有同样的问题像@EdRandall【参考方案3】:

可以通过指定-pl 命令行参数来决定要构建哪些反应器项目:

$ mvn --help
[...]
 -pl,--projects <arg>                   Build specified reactor projects
                                        instead of all projects
[...]

它接受以下形式之一的逗号分隔的参数列表:

包含 POM 的文件夹的相对路径 [groupId]:artifactId

因此,给定以下结构:

project-root [com.mycorp:parent]
  |
  + --- server [com.mycorp:server]
  |       |
  |       + --- orm [com.mycorp.server:orm]
  |
  + --- client [com.mycorp:client]

您可以指定以下命令行:

mvn -pl .,server,:client,com.mycorp.server:orm clean install

构建一切。删除列表中的元素以仅构建您喜欢的模块。


编辑:正如blackbuild 指出的那样,从 Maven 3.2.1 开始,您有 a new -el flag 将项目排除在反应堆之外,类似于 -pl 所做的:

【讨论】:

谢谢。这对我来说效果很好。另请注意,您可以添加“-am”(也称为“--also-make”)来构建您指定的模块所需的项目。 太棒了!我使用mvn install -pl . 仅在本地仓库中安装父 pom 而无需构建模块。 另外,看看jira.codehaus.org/browse/MNG-5230。您现在可以从反应器中排除项目。 MNG-5230 链接自 codehaus.org 关闭后:issues.apache.org/jira/browse/MNG-5230 不幸的是,它不能传递地工作,即,如果我有 top/mod1/mod2,并从顶部构建,-pl '!mod2' 会引发错误。【参考方案4】:

多模块项目的概念是为了满足项目中相互依赖的部分的需求。这样的客户端依赖于服务,而服务又依赖于 EJB 或数据访问例程。您可以以这种方式对您的持续集成 (CI) 测试进行分组。我会通过说 CI 测试需要与应用程序逻辑更改保持同步来合理化这一点。

假设您的项目结构如下:

project-root
  |
  + --- ci
  |
  + --- client
  |
  + --- server

project-root/pom.xml 定义模块

<modules>
  <module>ci</module>
  <module>client</module>
  <module>server</module>
</modules>

ci/pom.xml 定义配置文件,例如:

... 
<profiles>
  <profile>
    <id>default</id>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
    <plugin>
       <artifactId>maven-surefire-plugin</artifactId>
       <configuration>
         <skip>true</skip>
       </configuration>
     </plugin>
  </profile>
  <profile>
    <id>CI</id>
    <plugin>
       <artifactId>maven-surefire-plugin</artifactId>
       <configuration>
         <skip>false</skip>
       </configuration>
     </plugin>
  </profile>
</profiles>

这将导致 Maven 跳过此模块中的测试,除非名为 CI 的配置文件处于活动状态。 必须指示您的 CI 服务器执行mvn clean package -P CI。 Maven 网站有一个in-depth explanation of the profiling mechanism。

【讨论】:

【参考方案5】:

现在(从 1.1.1 版本开始)坑中有一个“跳过”标志。

所以你可以做这样的事情:

    <profile>
        <id>pit</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.pitest</groupId>
                    <artifactId>pitest-maven</artifactId>
                    <configuration>
                        <skip>true</skip>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>

在你的模块中,坑会跳过

[INFO] --- Pitest-maven:1.1.3:mutationCoverage (default-cli) @ module-selenium --- [INFO] 跳过项目

【讨论】:

【参考方案6】:

此处给出的命令行使用答案目前不适用于较新版本的 maven(至少 3.8)您还需要添加 ':'

mvn -pl '!:mymodule' install

【讨论】:

以上是关于在 Maven 构建期间跳过子模块的主要内容,如果未能解决你的问题,请参考以下文章

多模块项目构建期间模块之间的 Maven 依赖关系解析

Maven - 跳过父项目构建

在 Maven 中跳过某些模块中的测试

Jenkins构建Maven多模块项目时,单独编译子模块,并且不触发构建其它模块

maven maven项目构建ssh工程(父工程与子模块的拆分与聚合)

如何构建多个maven模块项目?