Як виключити модуль зі збірки реактора 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>

Потім слід перевірити способи активації профілів


Що ви зробите, якщо вам потрібні дані до загальних? У цьому випадку профільні модулі будуть розміщені після модулів за замовчуванням у порядку реактора. Чи існує схема для примусового замовлення?
Пітер Кан

9
Порядок модуля НЕ є порядком, в якому вони з'являться в реакторі. Єдиний спосіб вплинути на порядок - це створити залежності між модулями, тобто, використовуючи тег <dependency>. Ви не можете покластися на це деклараційне замовлення.
СМ

7
@SaM Насправді, з Maven 3.0.5, реактор враховує порядок у «модулях» , хоча порядок, продиктований залежностями, є більш важливим пріоритетом.
hellodanylo

Це порушить деякі інші плагіни, які не зможуть виявити модуль у профілі, навіть профіль увімкнено
tribbloid

143

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

Дивіться запит на цю функцію: https://isissue.apache.org/jira/browse/MNG-5230


Чи безпечно переходити з 3.0.4 на 3.2.1 чи є більші зміни?
січня

Я перейшов з 3.1 до 3.2.1 без жодних питань. Але якщо чесно, вам доведеться зробити конструкцію, щоб це зрозуміти.
Йогеш_Д

30
Не забувайте уникати знака оклику в командному рядку оболонки. Він має дуже особливе значення, див., Наприклад, unix.stackexchange.com/questions/3747/…
Павел,

5
На жаль, наразі відкритий випуск у плагіні проекту Jenkins Maven, який не підтримує виключення модуля реактора: 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>

Гарна відповідь. Але чи справді вам потрібні два профілі у другому прикладі коду? Чи не працюватиме єдиний профіль із прикладу першого коду зі зміненим елементом активації?
Arend v. Reinersdorff

@ Arendv.Reinersdorff так, але так, однак ця відповідь також працює з іншими профілями в збірці, які ви можете включити за замовчуванням. В цілому, я думаю, що інша відповідь -pl !<module_name>,!<module_name>краща за цю стару
artbristol

1
Хороший трюк активації. Це вирішило мені проблеми з <activeByDefault>, який не завжди активний!
Габ

7

Інша ідея: Модулі реактора можуть бути вкладені, тому слід мати можливість групувати свої швидкі та повільні модулі в окремі піни, а потім додати ще один помповий агрегатор, що містить ці два як модулі. Тоді ваш сервер CI міг посилатися лише на пом, що містить модулі швидкого збирання.

<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

Ви можете відключити компіляцію та інші стандартні плагіни в пам’яті свого модуля, щоб пришвидшити його.


2
Так, для відключення тестів це чудово працює. Але як я можу використовувати профілі для виключення модулів БЕЗ наявності двох окремих списків модулів у пам’яті? Наскільки я знаю, мені потрібно перекласти повний список модулів в один розділ профілю, а список модулів для швидкого збирання - в інший розділ профілю. Отже, ця проблема має таку ж проблему, як і використання двох окремих пім: у мене є два списки модулів для підтримки.
kayahr

Виключення модуля насправді не є способом робити справи в Maven, і мій досвід роботи з Maven полягає в тому, що краще дотримуватися того, як це робиться, в іншому випадку ти маєш стільки проблем ... Тож дійсно те, що я пропоную, - це не видаліть модуль, але щоб зробити цей модуль менш трудомістким.
Nr9

Проблема з 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>

І пам’яті в моїй дитині або будь-який модуль, який ви не хочете розгортати з батьком:

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.