Как исключить модуль из сборки реактора Maven?

98

У нас есть проект Maven 2 с большим количеством модулей. Пример:

<modules>
  <module>common</module>
  <module>foo</module>
  <module>data</module>
  <module>bar</module>
  ... more ...
</module>

Допустим, создание модуля «данных» занимает много времени, и мы хотим исключить его, когда проект создается сервером CI. В настоящее время для этого мы используем два файла pom.xml. В одном есть все модули, а в другом - все модули, кроме тех, которые можно не использовать для CI. Но это довольно неприятно, потому что иногда мы забываем поместить новый модуль в оба файла.

Есть ли решение, которое не требует двух отдельных списков модулей?

каяхр
источник

Ответы:

73

Проще всего использовать profilesвот так:

<project>
  ...
  <modules>
    <module>common</module>
    <module>foo</module>
    <module>bar</module>
  <modules>
  ...
  <profiles>
    <profile>
      <id>expensive-modules-to-build</id>
      <modules>
        <module>data</module>
      </modules>
    </profile>
  </profiles>
</project>

Затем вам следует изучить способы активации профилей.

Сэм
источник
Что бы вы сделали, если вам нужно, чтобы данные произошли раньше, чем обычные? В этом случае модули профиля будут размещены после модулей по умолчанию в порядке реактора. Есть ли шаблон для принуждения к порядку?
Peter Kahn
9
Порядок модулей НЕ является порядком, в котором они появятся в реакторе. Единственный способ повлиять на порядок - это создать зависимости между модулями, то есть с помощью тега <dependency>. Вы не можете полагаться в этом на порядок декларирования.
SaM
7
@SaM Фактически, начиная с Maven 3.0.5 Reactor будет учитывать порядок в «модулях» , хотя порядок, продиктованный зависимостями, имеет более высокий приоритет.
hellodanylo
Это сломает некоторые другие плагины, которые не могут обнаружить модуль в профиле, даже если этот профиль включен
tribbloid
143

С Maven 3.2.1 теперь вы можете использовать -pl !<module_name>,!<module_name>для исключения определенных модулей из сборки реактора.

См. Этот запрос функции: https://issues.apache.org/jira/browse/MNG-5230

Йогеш_Д
источник
Безопасно ли переходить с 3.0.4 на 3.2.1 или есть большие изменения?
янв.
Я без проблем перешел с 3.1 на 3.2.1. Но если честно, вам нужно будет сделать сборку, чтобы понять это.
Yogesh_D
30
Не забудьте убрать восклицательный знак в командной строке оболочки. Это имеет особое значение, см., Например, unix.stackexchange.com/questions/3747/…
Павел
5
К сожалению, в настоящее время в плагине Jenkins maven-project есть открытая проблема, которая не поддерживает исключение модуля реактора: issues.jenkins-ci.org/browse/JENKINS-26472
Ник Вандерховен,
@Pavel: или просто используйте -вместо !, т.е.-pl -<module_name>
msa
45

Проекты для сборки также можно указать в командной строке mvn. Это устранит необходимость в отдельном помпе, но вместо этого вам придется изменять конфигурацию CI каждый раз, когда появляется новый модуль.

-pl,--projects <arg>                Comma-delimited list of specified
                                    reactor projects to build instead
                                    of all projects. A project can be
                                    specified by [groupId]:artifactId
                                    or by its relative path.

Возможно, сочетание этого флага и / --also-make-dependentsили --also-makeснова уменьшит эту нагрузку на обслуживание.

-am,--also-make                     If project list is specified, also
                                    build projects required by the
                                    list
-amd,--also-make-dependents         If project list is specified, also
                                    build projects that depend on
                                    projects on the list
Йорн Хорстманн
источник
Это имеет те же проблемы, что и при использовании двух отдельных помп. У нас есть места, где мы определяем модули. Этого я пытаюсь избежать.
kayahr
Это хорошее решение. Не нужно обновлять пом. mvn clean install -pl mysubproject
nicolas-f
22

Я предполагаю, что вы хотите, чтобы стандартная сборка всегда создавала все, независимо от скорости, чтобы новые разработчики могли быстро начать работу, не разбираясь в POM. Вы можете использовать такие профили:

<modules>
    <module>common</module>
    <module>foo</module>
    <module>bar</module>
  </modules>
  ...
  <profiles>
    <profile>
      <id>expensive-modules-to-build</id>
      <activation>
         <activeByDefault>true</activeByDefault>
      </activation>
      <modules>
        <module>data</module>
      </modules>
    </profile>
  </profiles>
</project>

Проблема в том, что если разработчик указывает другой профиль в командной строке, он expensive-modules-to-buildне включается (если разработчик также не указывает его). Из-за этого сложно запомнить, какие профили необходимо включить.

Вот способ обойти это. Оба профиля всегда включены, потому что файл pom.xml существует всегда. Таким образом, чтобы исключить дорогостоящие модули, вы можете использовать их -P!full-buildв командной строке.

<profiles>
    <profile>
        <id>full-build</id>
        <activation>
            <file>
                <exists>pom.xml</exists>
            </file>
        </activation>
        <modules>
            <module>data</module>
        </modules>
    </profile>
    <profile>
        <id>short-build</id>
        <activation>
            <file>
                <exists>pom.xml</exists>
            </file>
        </activation>
        <modules>
           <module>common</module>
           <module>foo</module>
           <module>bar</module>
        </modules>
    </profile>
</profiles>
artbristol
источник
Хороший ответ. Но действительно ли вам нужны два профиля во втором примере кода? Не будет ли работать единый профиль из 1-го примера кода с измененным элементом активации?
Аренд против Райнерсдорфф
@ Arendv.Reinersdorff да, но этот ответ также работает с другими профилями в сборке, которые вы можете захотеть включить по умолчанию. В целом, я думаю, что другой ответ -pl !<module_name>,!<module_name>лучше, чем этот старый
artbristol
1
Хороший трюк с активацией. Это решило мне проблемы с <activeByDefault>, который не всегда активен!
Габ
7

Еще одна идея: модули Reactor могут быть вложенными, поэтому должна быть возможность сгруппировать ваши быстрые и медленные модули в отдельные помы, а затем добавить другой помп агрегатора, содержащий эти два как модули. Тогда ваш CI-сервер мог ссылаться только на pom, содержащий модули быстрой сборки.

<artifactId>fast</artifactId>
<modules>
    <module>fast-a</module>
    <module>fast-b</module>
    <module>fast-c</module>
</module>

<artifactId>all</artifactId>
<modules>
    <module>fast</module>
    <module>slow</module>
</module>
Йорн Хорстманн
источник
1

Вы можете использовать профили maven . В нашей среде сборки мы создали профиль, quickкоторый отключает многие плагины и выполнение тестов.

Это делается

    <profile>
        <id>quick</id>
        <properties>
            <skipTests>true</skipTests>
            <!-- others... -->
        </properties>   
        <build>
            <plugins>
                 <!-- configuration... -->
            </plugins>
        </build>
    </profile>

Затем мы вызываем maven следующим образом

mvn groupId:artifactId:goal -P quick

Возможно, вы можете отключить компиляцию и другие стандартные плагины в pom вашего модуля, чтобы ускорить его.

№9
источник
2
Да, для отключения тестов это отлично работает. Но как я могу использовать профили для исключения модулей БЕЗ двух отдельных списков модулей в pom? Насколько я знаю, мне нужно поместить полный список модулей в один раздел профиля, а список модулей быстрой сборки - в другой раздел профиля. Таким образом, здесь возникает та же проблема, что и при использовании двух отдельных помпов: мне нужно поддерживать два списка модулей.
kayahr
Исключение модуля - это не способ делать что-то в maven, и мой опыт работы с maven показывает, что лучше придерживаться того, как все делается, иначе вы столкнетесь с таким количеством проблем ... Так что на самом деле я предлагаю не удалить модуль, но сделать этот модуль менее затратным по времени.
Nr9,
Проблема с maven заключается в том, что «способ работы» часто не согласуется с «способом, которым все делается в реальном мире», что делает опыт maven плохим и болезненным. Разработчикам не мешало бы пройти курс обучения UX.
Эд Рэндалл
0

Не совсем тот ответ, которого просили эти люди. Моя ситуация заключалась в том, что я хотел развернуть только родительский пом. Я использую spring-boot-thin-layoutв дочернем модуле. Для этого требуется, чтобы родительский модуль был развернут в артефакте. Я добавил в свой проект следующее. Это позволяет пропускать installи / или deployфазу.

В моем родительском помпе:

<properties>
    <disable.install>true</disable.install>
    <disable.deploy>true</disable.deploy>
    <enable.deployAtEnd>true</enable.deployAtEnd>
</properties>

<profiles>
    <profile>
        <id>deploy-parent</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <disable.install>true</disable.install>
            <disable.deploy>true</disable.deploy>
            <deployAtEnd>${enable.deployAtEnd}</deployAtEnd>
        </properties>
        <build>
            <finalName>${project.version}</finalName>
        </build>
    </profile>
</profiles>

И в моем дочернем pom (s) или любом модуле, который вы не хотите развертывать с родительским:

<properties>
    <maven.install.skip>${disable.install}</maven.install.skip>
    <maven.deploy.skip>${disable.deploy}</maven.deploy.skip>
    <deployAtEnd>${enable.deployAtEnd}</deployAtEnd>
</properties>

Так эффективно, когда я запускаю mvn deployродительский pom, он компилирует все модули, а не запускает установку на что-либо, а затем в конце развертывает любой модуль, не имеющий <maven.deploy.skip>${disable.deploy}</maven.deploy.skip>в нем свойств. Итак, в моем случае развертывание только родителя.

ранма2913
источник