在 Maven 构建过程中跳过子模块

204

我们需要在某些环境下跳过一个子模块。

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

是否可以通过配置文件进行设置?我已经做了一些搜索并查看了其他问题/答案,但没有找到好的解决方案。

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

有什么建议吗?


为什么不采用Maven方式呢?对我来说这是一个完全合理的主张。 - MaDa
嗯,现在我找不到人们似乎反对这个的地方了...所以我更新了我的原始问题,删除了我声称这似乎不是“Maven方式”的说法。 - denishaskin
6个回答

315

Maven 3.2.1版本新增了此功能,您可以使用-pl开关(--projects的缩写)加上!-参考)来排除特定的子模块。

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

在 Bash 中要注意感叹号(!)是一个特殊字符,所以你要么用单引号括起来(就像我做的一样),要么用反斜杠转义它。

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

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

编辑:Windows似乎不喜欢单引号,但在bash中是必需的;在Windows中,请使用双引号(感谢@awilkinson)。

mvn -pl "!submodule1,!submodule2" install

43
重要提示:如果您想排除一个嵌套子模块,您需要使用限定版本 mvn -pl !com.acme:nestedmodule1 - Leonard Brünings
4
-pl选项需要在artifactId之前添加'[groupId]:',因此我们应该使用mvn -pl '!:submodule-to-exclude' install。 - Honsen
6
你还可以使用mvn -pl '!path/to/submodule/directory'命令,而不需要使用groupId和artifactId。如果submodule1submodule2在当前目录中,我的答案就适用。 - Alexandre DuBreuil
值得注意的是,如果您在mvn install命令中使用了-pl选项,则很可能需要在mvn deploy命令中也使用它。 - chizou
以下命令适用于Windows机器。mvn -pl“!submodule1,!submodule2”clean install - Tarun Kumar
有没有通过个人资料的选项? - RamPrakash

160

当然,这可以通过配置文件(profiles)来完成。您可以在您的父级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


5
回答:非常好的回答!我不知道为什么在Maven文档中找到这个答案有这么多麻烦。我的建议是,因为我更喜欢默认运行集成测试,所以我在该配置文件中添加了 activeByDefault,然后又添加了另一个空配置文件(例如 skip-integration-tests)以便能够跳过它们。 - denishaskin
10
有没有不需要复制所有共享内容就可以完成这个任务的方法? - JonnyRaa
8
注意,如果你使用maven-release-plugin插件,似乎它不会更新隐藏在配置文件开关后面的子模块版本号。这可能导致你的子模块与项目其他部分具有不同的版本号。 - Ardesco
11
很遗憾,使用配置文件中的个人档案无法排除在pom主要<modules>部分中早先提到的模块。如果更加谨慎考虑,JIRA https://issues.apache.org/jira/browse/MNG-5230(以及整个pom结构)本可以实现得更好。 - Ed Randall
5
这个解决方案真的有效吗?至少我无法让它起作用。看起来我和@EdRandall遇到了相同的问题。 - Gerros
显示剩余2条评论

41

可以通过指定 -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开始,你可以使用一个新的-el标志来排除反应堆中的项目,类似于-pl的功能。

2
谢谢。这对我很有效。还要注意,您可以添加“-am”(又称“--also-make”)以构建所需的模块。 - GaZ
3
好的!我使用了mvn install -pl .命令,只安装父POM到本地仓库而不构建模块。 - Marcin
另外,请查看https://jira.codehaus.org/browse/MNG-5230。您现在可以从反应堆中排除项目。 - blackbuild
2
MNG-5230链接自Codehaus.org关闭:https://issues.apache.org/jira/browse/MNG-5230 - Ed Randall
不幸的是,它不具有传递性,即如果我有top/mod1/mod2,并从top构建,“-pl'!mod2'”会引发错误。 - zakmck

8

目前这里给出的命令行使用答案在较新版本的maven上(至少3.8)不起作用。你还需要添加 ':'。

mvn -pl '!:mymodule' install

我们有双重层次的反应器,但似乎无法排除其中一个中间级别的反应器模块。 - U.V.

4

多模块项目的概念是为了服务于项目的相互依存的部分需求。这样的客户端依赖于服务,而服务又依赖于例如EJBs或数据访问例程。你可以按此方式分组你的持续集成(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网站有一个详细解释了配置机制


2

现在(从1.1.1版本开始),Pit中有一个“skip”标志。

因此,您可以执行以下操作:

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

在您的模块中,Pit会跳过

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接