Maven родитель пом против модулей пом

Кажется, есть несколько способов структурировать родительские помпы в многопроектной сборке, и мне интересно, есть ли у кого-нибудь мысли о преимуществах / недостатках каждого из них.

Самый простой способ иметь родительский pom - это поместить его в корень проекта, т.е.

myproject/
  myproject-core/
  myproject-api/
  myproject-app/
  pom.xml

где pom.xml является как родительским проектом, так и описывает модули -core -api и -app

Следующий метод состоит в том, чтобы выделить родителя в его собственный подкаталог, как в

myproject/
  mypoject-parent/
    pom.xml
  myproject-core/
  myproject-api/
  myproject-app/

Где родительский pom все еще содержит модули, но они являются относительными, например../myproject-core

Наконец, есть опция, где определение модуля и родительский элемент разделены, как в

myproject/
  mypoject-parent/
    pom.xml
  myproject-core/
  myproject-api/
  myproject-app/
  pom.xml

Где родительский pom содержит любую "общую" конфигурацию (dependencyManagement, свойства и т. Д.), А myproject / pom.xml содержит список модулей.

Намерение состоит в том, чтобы быть масштабируемым для крупномасштабной сборки, поэтому должно быть масштабируемым для большого количества проектов и артефактов.

Несколько бонусных вопросов:

  • Где лучше всего определить различные общие конфигурации, такие как управление исходным кодом, каталоги развертывания, общие плагины и т. Д. (Я предполагаю, что родительский, но меня это часто кусает, и они оказываются в каждом проекте, а не обычный).
  • Как плагин maven-release, hudson и nexus справляется с тем, как вы настраиваете свои мульти-проекты (возможно, гигантский вопрос, более важно, если кто-нибудь узнает, когда была настроена многопроектная сборка)?

Редактировать: Каждый из подпроектов имеет свой собственный pom.xml, я оставил его для краткости.

4 ответа

Решение

На мой взгляд, чтобы ответить на этот вопрос, нужно мыслить с точки зрения жизненного цикла проекта и контроля версий. Другими словами, имеет ли родительский pom свой жизненный цикл, т. Е. Может ли он быть выпущен отдельно от других модулей или нет?

Если ответ " да" (а это относится к большинству проектов, которые были упомянуты в вопросе или в комментариях), тогда родительский pom нуждается в своем собственном модуле из VCS и с точки зрения Maven, и в итоге вы получите с чем-то вроде этого на уровне VCS:

root
|-- parent-pom
|   |-- branches
|   |-- tags
|   `-- trunk
|       `-- pom.xml
`-- projectA
    |-- branches
    |-- tags
    `-- trunk
        |-- module1
        |   `-- pom.xml
        |-- moduleN
        |   `-- pom.xml
        `-- pom.xml

Это делает оформление заказа немного болезненным и распространенным способом борьбы с этим является использование svn:externals, Например, добавить trunks каталог:

root
|-- parent-pom
|   |-- branches
|   |-- tags
|   `-- trunk
|       `-- pom.xml
|-- projectA
|   |-- branches
|   |-- tags
|   `-- trunk
|       |-- module1
|       |   `-- pom.xml
|       |-- moduleN
|       |   `-- pom.xml
|       `-- pom.xml
`-- trunks

Со следующим внешним определением:

parent-pom http://host/svn/parent-pom/trunk
projectA http://host/svn/projectA/trunk

Оформление заказа trunks в результате получится следующая локальная структура (шаблон № 2):

root/
  parent-pom/
    pom.xml
  projectA/

По желанию, вы можете даже добавить pom.xml в trunks каталог:

root
|-- parent-pom
|   |-- branches
|   |-- tags
|   `-- trunk
|       `-- pom.xml
|-- projectA
|   |-- branches
|   |-- tags
|   `-- trunk
|       |-- module1
|       |   `-- pom.xml
|       |-- moduleN
|       |   `-- pom.xml
|       `-- pom.xml
`-- trunks
    `-- pom.xml

это pom.xml это своего рода "фальшивый" пом: он никогда не выпускается, он не содержит реальной версии, поскольку этот файл никогда не выпускается, он содержит только список модулей. С этим файлом извлечение привело бы к этой структуре (образец #3):

root/
  parent-pom/
    pom.xml
  projectA/
  pom.xml

Этот "хак" позволяет запустить сборку реактора из корня после проверки и сделать вещи еще более удобными. На самом деле, именно так мне нравится настраивать maven проекты и VCS-репозиторий для больших сборок: он просто работает, хорошо масштабируется, дает всю гибкость, которая может вам понадобиться.

Если ответ " нет" (вернемся к первоначальному вопросу), то я думаю, что вы можете жить по шаблону № 1 (сделать самое простое, что могло бы сработать).

Теперь о бонусных вопросах:

  • Где лучше всего определить различные общие конфигурации, такие как управление исходным кодом, каталоги развертывания, общие плагины и т. Д. (Я предполагаю, что родительский, но меня это часто кусает, и они оказываются в каждом проекте, а не обычный).

Честно говоря, я не знаю, как не дать здесь общий ответ (например, "используйте уровень, на котором, по вашему мнению, имеет смысл взаимопонимание"). И вообще, дочерние помпы всегда могут переопределить унаследованные настройки.

  • Как плагин maven-release, hudson и nexus справляется с тем, как вы настраиваете свои мульти-проекты (возможно, гигантский вопрос, более важно, если кто-нибудь узнает, когда была настроена многопроектная сборка)?

Настройка, которую я использую, работает хорошо, ничего особенного упоминать.

На самом деле, мне интересно, как плагин maven-release-plugin работает с шаблоном № 1 (особенно с <parent> раздел, поскольку у вас не может быть зависимостей SNAPSHOT во время выпуска). Это похоже на проблему с курицей или яйцом, но я просто не могу вспомнить, работает ли она, и мне было лень это проверять.

Исходя из моего опыта и лучших практик Maven, есть два вида "родительских помп"

  • "pom" родительский pom - этот pom содержит информацию и конфигурацию вашей компании, которые наследуют каждый pom и его не нужно копировать. Эти данные:

    • хранилища
    • разделы управления распределением
    • общие конфигурации плагинов (например, исходные и целевые версии maven-compiler-plugin)
    • организация, разработчики и т. д.

    Подготовку этого родительского pom следует проводить с осторожностью, поскольку все pom вашей компании будут наследоваться от него, поэтому этот pom должен быть зрелым и стабильным (выпуск версии pom-родительского пакета не должен влиять на выпуск всех проектов вашей компании!)

  • Второй вид родительского пом - это многомодульный родитель. Я предпочитаю ваше первое решение - это стандартное соглашение maven для многомодульных проектов, очень часто представляющее структуру кода VCS

Намерение состоит в том, чтобы быть масштабируемым для крупномасштабной сборки, поэтому должно быть масштабируемым для большого количества проектов и артефактов.

Мутлипроекты имеют структуру деревьев, поэтому вы не ограничены одним уровнем родительского помпа. Постарайтесь найти подходящую структуру проекта для ваших нужд - классический пример - как распределять многомодульные проекты

distibution/
documentation/
myproject/
  myproject-core/
  myproject-api/
  myproject-app/
  pom.xml
pom.xml

Несколько бонусных вопросов:

  • Где лучше всего определить различные общие конфигурации, такие как управление исходным кодом, каталоги развертывания, общие плагины и т. Д. (Я предполагаю, что родительский, но меня это часто кусает, и они оказываются в каждом проекте, а не обычный).

Эта конфигурация должна быть разумно разделена на родительский pom "компании" и родительский pom проекта. Вещи, относящиеся ко всему вашему проекту, переходят к "родительскому" предприятию, а это относится к текущему проекту - к одному.

  • Как плагин maven-release, hudson и nexus справляется с тем, как вы настраиваете свои мульти-проекты (возможно, гигантский вопрос, более важно, если кто-нибудь узнает, когда была настроена многопроектная сборка)?

Родительский помп компании должен быть выпущен первым. Для мультипроектов применяются стандартные правила. CI серверу нужно знать все, чтобы правильно построить проект.

  1. Независимый родительский узел - это лучшая практика для совместного использования конфигурации и параметров между несвязанными компонентами. У Apache есть родительский проект pom, чтобы поделиться юридическими уведомлениями и некоторыми распространенными вариантами упаковки.

  2. Если в вашем проекте верхнего уровня есть реальная работа, такая как агрегация javadoc или упаковка релиза, то у вас будут конфликты между настройками, необходимыми для этой работы, и настройками, которые вы хотите передать через родительский. Проект только для родителей избегает этого.

  3. Распространенный шаблон (на данный момент игнорирующий № 1) - проекты с кодом используют родительский проект в качестве родителя, а верхний уровень - как родительский. Это позволяет всем совместно использовать основные вещи, но позволяет избежать проблемы, описанной в #2.

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

  5. Apache CXF является примером шаблона в #2.

Есть один маленький улов с третьим подходом. Поскольку совокупные POM (myproject/pom.xml) обычно вообще не имеют родителя, они не разделяют конфигурацию. Это означает, что все эти агрегированные POM будут иметь только репозитории по умолчанию.

Это не проблема, если вы используете только плагины из Central, однако это не удастся, если вы запустите плагин, используя формат plugin: goal из вашего внутреннего репозитория. Например, вы можете иметь foo-maven-plugin с идентификатором группы из org.example обеспечение цели generate-foo, Если вы попытаетесь запустить его из корня проекта с помощью команды вроде mvn org.example:foo-maven-plugin:generate-foo, он не будет работать на агрегатных модулях (см. примечание о совместимости).

Возможны несколько решений:

  1. Разверните плагин в Maven Central (не всегда возможно).
  2. Укажите раздел репозитория во всех ваших агрегатных POM (нарушает принцип DRY).
  3. Настройте этот внутренний репозиторий в файле settings.xml (либо в локальных настройках в ~/.m2/settings.xml, либо в глобальных настройках в /conf/settings.xml). Сборка не удастся без этих settings.xml (может подойти для больших внутренних проектов, которые никогда не должны создаваться за пределами компании).
  4. Используйте родительский с настройками репозиториев в ваших совокупных POM (может быть слишком много родительских POM?).
Другие вопросы по тегам