Различное поведение в многомодульных проектах maven при запуске в TeamCity и локально

#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%.