运行 在 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%.
我在 TeamCity 上有一个 Maven 多模块项目。我正在使用 TeamCity 的内置 maven 3.5 工具。
在其中一个子项目的 pom.xml 部分中,我设置了“
稍后在 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%.