#maven #teamcity
#мавен #командный город
Вопрос:
У меня есть многомодульный проект maven в TeamCity. Я использую встроенный в maven 3.5 инструментарий TeamCity.
В одном из дочерних проектов, в разделе его pom.xml Я установил «<target.env>dev</target.env>».
Позже в pom я использую properties-maven-plugin для загрузки файла с именем «${target.env}.env.properties»
Локально, если я запускаю «mvn package -Dtarget.env=prod» в родительском проекте, дочерний проект загружает prod.env.properties, как и ожидалось.
Если я настрою свою сборку teamcity с помощью параметра («system.target.env», «prod»), я вижу, что «-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, config)
/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’, как и ожидалось
Комментарии:
1. Откуда мне знать? Я ничего не знаю ни о вашем проекте, ни о том, как он выглядит, как выглядит файл pom, какая версия JDK, версии Maven и т.д. вы используете? Пожалуйста, покажите pom-файл или, что еще лучше, ссылку на проект… Зачем нужен properties-maven-plugin? также был бы очень полезен файл журнала….
2. Что делает teamcity:
where teamcity invokes the plexus-classworlds launcher to do so
?3. @khmarbaise Нет необходимости в язвительности. Кто-то, более знакомый с инструментами, чем я, возможно, смог бы определить распространенную ошибку из того, что я предоставил. В любом случае я добавил некоторые детали, о которых вы просили. Я не собираюсь публиковать конфигурацию сборки для коммерческого проекта в открытом доступе.
4. Во-первых, я не понимаю, почему ваша сборка зависит от среды (как вы написали) … во-вторых, почему TeamCity просто не вызывает maven (mvn / mvn.cmd) напрямую вместо того, чтобы создавать что-то самостоятельно? Кроме того, мне не хватает нескольких настроек деталей, как это было сделано в оригинале
mvn
/mvn.cmd
file, что может вызвать проблемы… Но я не знаю, потому что то, что запускается, — это не «Apache Maven», это своего рода Maven… и вопрос в том, зачем использовать такую старую версию Maven? У вас есть пример проекта на github или похожий?5. @khmarbaise Я недостаточно хорошо знаю внутренности TeamCity, чтобы объяснить его дизайнерские решения о том, как он вызывает встроенный инструментарий maven. Выбранная версия является произвольной, но соответствует тому, что я в настоящее время использую локально. Похоже, я могу переключиться на 3.6.3, хотя я хотел бы понять, как это может повлиять на эту конкретную проблему, прежде чем я это сделаю. В настоящее время у меня нет доступного примера проекта, но я готов отправить вам копию моего пом (ов) по личному каналу по вашему выбору, если вы хотите.
Ответ №1:
В итоге это стало известной ошибкой в TeamCity
Основная проблема, по-видимому, заключается в том, что TeamCity использует переменную среды MAVEN_OPTS для передачи системных свойств в maven по умолчанию, но свойства в MAVEN_OPTS обрабатываются иначе, чем свойства, передаваемые в качестве аргументов самой команде maven.
Обходной путь заключается в том, что для любого свойства «foo», которое устанавливается в разделе POM, которое вы хотите переопределить в сборке TeamCity, вы должны указать его в «Дополнительных параметрах командной строки Maven» с помощью -Dfoo=value , или, если вы устанавливаете значение в системе или свойство сборки в сборке TeamCity -Dfoo=%system.foo%.