运行 在 TeamCity 与本地时 Maven 多模块项目中的不同行为

Differing behavior in maven multi-module projects when run in TeamCity vs locally

我在 TeamCity 上有一个 Maven 多模块项目。我正在使用 TeamCity 的内置 maven 3.5 工具。

在其中一个子项目的 pom.xml 部分中,我设置了“dev”。

稍后在 pom 中我使用 properties-maven-plugin 加载名称为“${target.env}.env.properties”的文件。env.properties

本地,如果我在父项目中 运行 "mvn package -Dtarget.env=prod",子项目会按预期加载 prod。env.properties。

如果我使用 param("system.target.env", "prod") 配置我的 teamcity 构建,我可以看到 "-Dtarget.env=prod" 传递给 maven 执行构建日志(其中 teamcity 调用 plexus-classworlds 启动器来执行此操作),子项目加载 dev.env.properties,破坏构建。

这是我的问题:

为什么行为不同? 我该如何协调?


更新包括@khmarbaise 要求的一些信息:

properties-maven-plugin 用于根据应用程序 运行 所在的环境加载一组特定于环境的属性。 它设置为根据系统选择加载哪个文件属性,并在属性块中设置默认值以避免必须不断地 在开发过程中添加 -Dtarget.env=dev 。子项目的properties-maven-plugin配置如下:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>properties-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>load-environment-properties</id>
            <phase>validate</phase> <!-- Bound to validate phase to ensure it comes before loading of local.build.properties -->   # No local.build.properties on TeamCity, so nothing clobbers this in practice
            <goals>
                <goal>read-project-properties</goal>
            </goals>
            <configuration>
                <files>
                    <file>src/main/targetEnvironment/default.env.properties</file>
                    <file>src/main/targetEnvironment/${target.env}.env.properties</file>
                </files>
            </configuration>
        </execution>

        <execution>
            <id>write-properties</id>
            <phase>generate-resources</phase>
            <goals>
                <goal>write-project-properties</goal>
            </goals>
            <configuration>
                <outputFile>${project.build.directory}/effective.build.properties</outputFile>
            </configuration>
        </execution>
    </executions>
</plugin>

版本信息:

Teamcity version: 2020.2.1 (build 85633)
Maven version: 3.3.9
Java version:
    openjdk version "1.8.0_272"
    OpenJDK Runtime Environment Corretto-8.272.10.3 (build 1.8.0_272-b10)
    OpenJDK 64-Bit Server VM Corretto-8.272.10.3 (build 25.272-b10, mixed mode)

这是 TeamCity 用来调用 maven 的行,我只包含了 属性 看起来相关的定义,因为有太多绝对不相关的定义(内部版本号、名称、时间戳和其他 TC具体的,maven 不可知论者,配置)

/usr/lib/jvm/java-1.8.0-amazon-corretto.x86_64/bin/java 
-Dclassworlds.conf=/home/ec2-user/BuildAgent/temp/buildTmp/teamcity.m2.conf 
-Dmaven.home=/home/ec2-user/BuildAgent/tools/maven3_3 
-DskipTests=true 
-Dteamcity.build.properties.file=/home/ec2-user/BuildAgent/temp/buildTmp/teamcity.build4380238471360533686.properties 
-Dtarget.env=prod 
-classpath /home/ec2-user/BuildAgent/tools/maven3_3/boot/plexus-classworlds-2.5.2.jar: org.codehaus.plexus.classworlds.launcher.Launcher -f /home/ec2-user/BuildAgent/work/4508a7116faa21f3/pom.xml -B clean package

teamcity.m2.conf内容如下:

main is org.apache.maven.cli.MavenCli from plexus.core

set maven.home default ${user.home}/m2

[plexus.core]
load ${teamcity.maven.watcher.home}/*.jar
optionally ${maven.home}/lib/ext/*.jar
load       ${maven.home}/lib/*.jar
load       ${maven.home}/conf/logging

teamcity.build4380238471360533686.properties 包含许多属性,该文件中 target.env 的值是预期的 'prod'

这最终成为 known bug in TeamCity

潜在的问题似乎是 TeamCity 默认使用 MAVEN_OPTS 环境变量将系统属性传递给 maven,但 MAVEN_OPTS 中的属性与作为参数传递给 maven 的属性的处理方式不同命令本身。

解决方法是,对于在 POM 部分中设置的任何 属性“foo”,如果您想在 TeamCity 构建中覆盖,您必须在“其他 Maven 命令行参数”中指定它" 使用 -Dfoo=value,或者,如果您在系统中设置值或在 TeamCity 构建中构建 属性 -Dfoo=%system.foo%.