Maven родительский pom vs modules pom

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

Самый простой способ иметь родительский pom должен помещать его в корень проекта i.e.

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-жильный

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

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

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

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

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

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

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

Ответ 1

На мой взгляд, чтобы ответить на этот вопрос, вам нужно подумать о жизненном цикле проекта и управлении версиями. Другими словами, имеет ли родительский 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 является своего рода "поддельным" pom: он никогда не выпускается, он не содержит реальной версии, так как этот файл никогда не выпускается, он содержит только список модулей. С этим файлом проверка приведет к этой структуре (шаблон # 3):

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

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

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

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

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

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

  • Как сделать Maven-релиз плагин, Гудзон и нексуса дело с тем, как вы создали свои мульти-проекты (возможно, гигантский вопрос, больше, если кто-то был пойман, когда от того, как построить мульти-проект был создан )?

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

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

Ответ 2

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

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

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

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

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

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

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

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

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

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

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

  • Как сделать Maven-релиз плагин, Гудзон и нексуса дело с тем, как вы создали свои мульти-проекты (возможно, гигантский вопрос, больше, если кто-то был пойман, когда от того, как построить мульти-проект был создан )?

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

Ответ 3

  • Независимый родитель является наилучшей практикой для совместного использования конфигурации и опций в других несвязанных компонентах. Apache имеет проект родительского pom для обмена юридическими уведомлениями и некоторыми общими вариантами упаковки.

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

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

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

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

Ответ 4

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

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

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

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