Вопрос

Я знаю, что это моветон спросить дважды за один день, но вот еще одна головоломка Maven:

У меня есть родительский POM, который определяет 5 модулей (5 подпроектов).Поскольку каждый модуль выполняется абсолютно одинаково, я тяну <profile><build> раздел в родительский POM, чтобы избавиться от дублирующегося кода.Теперь - если я выполняю сборку отдельно из каждого модуля, это работает, однако, если я хочу собрать все модули одновременно и перейти в родительский каталог, я получаю ошибку, поскольку самое первое, что пытается выполнить Maven, - это сам родительский проект:

mvn package -P release
[INFO] Scanning for projects...
[INFO] Reactor build order:
[INFO]   DWD Parent project
[INFO]   Projects

После этого сборка завершается неудачей, потому что плагин exec пытается выполнить что-то, чего нет.Глядя на выходные данные, совершенно очевидно, что плагин реактора управляет сборкой, но как я могу настроить реактор, чтобы он пропускал родительский элемент?

P.S.Чтобы избежать путаницы, я пытаюсь подавить выполнение профиля на родителе и включить его на дочернем уровне во время same строить

Это было полезно?

Решение

Что плохого в создании родителя?

Фактически в Maven есть две разные концепции (которые обычно используются одновременно):

  • Родительский POM
  • Агрегация модулей

Первое – это определение всего, что общего у всех детей.Вы определяете родительский элемент как проект, упакованный pom, и можете установить его в свой репозиторий.

Когда вы создаете дочерний элемент этого родителя, Maven2 извлечет этого родителя, чтобы объединить родительский pom с дочерним pom.Вы можете просмотреть весь pom.xml, выполнив команду mvn help:effective-pom.

В этом случае родительский pom не будет создан, а будет просто получен из репозитория.

Второй случай — это проект, содержащий modules список подпроектов.Принцип заключается в том, что каждая команда, которую вы запускаете в этом проекте, также будет выполняться во всех подмодулях.Порядок модулей будет определяться Reactor, который будет проверять зависимости между модулями, чтобы определить, какой модуль должен быть построен раньше остальных.Если зависимостей нет, он возьмет список модулей, как они определены в родительском pom.xml.

В этом случае, если вы запустите команду в корневом проекте, Maven2 сначала создаст корневой проект, а затем подмодули.Ты не могу пропустить создание корневого проекта.


Изменить, благодаря комментарию RichSeller

Полное объяснение различий между мультимодулями (проектом агрегации) и наследованием (родительским проектом) можно найти в книге Maven, здесь.

Другие советы

Вы не можете пропустить родительскую сборку, но можете настроить профиль так, чтобы он не активировался, применив небольшой хак. Этот ответ показано, как контролировать активацию профиля по наличию или отсутствию файлового <activation> элемент.Таким образом, вы можете определить профиль в родительском файле, но деактивировать его в этом проекте, поскольку в родительском файле присутствует файл маркера.Дочерние проекты не будут иметь файл маркера в своем источнике, поэтому профиль будет активирован для этих проектов.

Обновление, чтобы уточнить:В моем тестовом проекте эта конфигурация означает, что профиль деактивирован в родительском проекте (файл которого находится в src/main/resources), но активирован во всех дочерних проектах, в каталогах ресурсов которых нет этого файла.

<profile>
  <id>test</id>
  <activation>
    <file>
      <missing>src/main/resources/test.marker</missing>
    </file>
  </activation>
  ...
</profile>

Я хочу задокументировать, что в моей ситуации есть частичный компромисс (спасибо ребятам из списка рассылки пользователей maven за предложения).По сути, вам нужно разрезать профиль на две части.Многоразовый configuration раздел плагина переходит в родительский POM, и executions остается в дочернем POM.Тогда плагин профиля в дочернем помечается как inherited и вуаля - во время выполнения родительский профиль не выполняется, поскольку он отсутствует executions раздел.Это далеко от идеала, но это работает.Ссылаться по этой ссылке например

Мне не удалось реализовать «отсутствующее» файловое решение, предложенное Риком Селлером выше.Кажется, что после установки активного/неактивного состояния профиля он не будет изменен, даже если в модуле(ах) отсутствует файл маркера.Однако вот точное решение моей проблемы.Предупреждение:это доступно только начиная с Maven 2.1+.

Если у меня есть родительский POM с двумя определенными модулями:foo и boo, тогда в обычных обстоятельствах порядок выполнения будет таким:

  1. родитель
  2. фу
  3. бу

Все, что мне нужно сделать, чтобы пропустить родительскую сборку, — это добавить этот переключатель командной строки

mvn install –rf foo

В качестве альтернативы вы можете использовать --resume-from Что он сделает, так это пропустит родительский элемент и продолжит работу с модуля foo вниз.Сейчас я исследую, можно ли этого добиться, настроив плагин Reactor. (П.С.- нет, не может) но даже с переключателем у меня описанный выше сценарий работает нормально

Это подразумевается в ответе @romaintaz на тот же вопрос: Maven – пропустить сборку родительского проекта

но чтобы сделать это явным, в родительском pom обязательно укажите элемент упаковки как pom (а не jar или war).
Пример:

<packaging>pom</packaging>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top