Maven батьків pom проти модулів pom


284

Здається, існує декілька способів структурування батьківських пісів у багатопроектній збірці, і мені цікаво, чи хтось міркував про те, які переваги / недоліки є у кожному напрямку.

Найпростіший метод мати батьківський пом - це введення його в корінь проекту, тобто

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/

Там, де батьківський пом все ще містить модулі, але вони відносні, наприклад ../myproject-core

Нарешті, є варіант, де визначення модуля та батьківський розділені як у

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

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

Намір полягає у масштабуванні масштабних конструкцій, тому він повинен бути масштабованим для великої кількості проектів та артефактів.

Кілька бонусних питань:

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

Редагувати: у кожного з підпроектів є свій pom.xml, я його не залишив, щоб тримати його коротко.


У кожного модуля також є своя помпон? Мій проект має батьківський пом, але кожен модуль також має пом. (можливо, четвертий шлях до того, що ви описуєте)
гарнітур

Ага, так, я редагую та оновлюю. Кожен з підмодулів також має свою помпону.
Джеймі МакКріндл

3
Як результат оновлення, я бачу перевагу другого варіанту в тому, що в Eclipse легше керувати, де корінь pom.xml у першому та третьому прикладі було б важко включити, якщо підмодулі - це окремі проекти Eclipse.
Джеймі МакКріндл

Відповіді:


166

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

Якщо відповідь " так" (і це стосується більшості проектів, про які згадувалося у запитанні чи коментарях), тоді батькові пом потрібен власний модуль з 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 (зробіть найпростішу річ, яка могла б працювати).

Тепер про питання про бонус:

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

Чесно кажучи, я не знаю, як тут не дати загальної відповіді (наприклад, "використовувати рівень, на якому ти думаєш, що має сенс думати речі"). І в будь-якому разі, дитячі пісні завжди можуть замінити успадковані настройки.

  • Як плагін, hudson та nexus Maven-релізи погоджуються з тим, як ви створюєте свої багатопроектні проекти (можливо, велике питання, це більше, якщо хтось виявився, коли, як було створено багатопроектну збірку)?

Установка, яку я використовую, працює добре, нічого особливого не потрібно згадувати.

Насправді мені цікаво, як плагін maven-release-плагін має справу з шаблоном №1 (особливо з <parent>розділом, оскільки ви не можете мати залежності SNAPSHOT під час випуску). Це звучить як проблема з куркою чи яйцями, але я просто не можу пригадати, чи працює вона, і було лінь, щоб перевірити це.


Це дуже добре, оскільки я бачу, як воно масштабується. Svn: externals відповідає на моє занепокоєння з приводу того, що він громіздкий.
Джеймі МакКріндл

@jamie Рада, вам здається корисною.
Паскаль Thivent

1
Не могли б ви детальніше розібратися, як зробити так, щоб "зламати" роботу? У мене є проект магістралей і передбачаю, що ви орієнтуєтесь на параметр -pl з "запуском збірки реактора", але це представляє проблему при виконанні випуску структури, оскільки ця опція не переходить від збірки на рівні кореня, чи можу я помістити його в параметр <аргументи /> випуску-плагін. Тому випуск: виконайте фейли, тому що він намагається працювати над кореневим рівнем пам’яті ...
січня

Хак svn: externals - це найкорисніший хак svn, який я бачив уже давно. Дуже корисно для проектів, які мають розгалуження за проектом в одному сховищі.
omerkudat

1
Привіт Паскаль, як би ви обробили версію #, якщо проекти, згадані в розділі модулів, не використовують батьківський пом як свій <прозорий>, а якийсь інший-проект-батьківський-пом? Які версії # ми отримаємо для артефакту таких проектів (версія # артефакту в розділі <прозорий> цих проектів АБО версія # проекту, в якій зазначені проекти є модулями)? stackoverflow.com/questions/25918593/…
AKS

34

З мого досвіду та найкращих практик Мейвена є два види "батьківських пім"

  • "компанія" батьківська пом - ця пом-ва містить конкретну інформацію та конфігурацію вашої компанії, яка успадковує кожен пом і не потребує копіювання. Ці відомості:

    • сховища
    • секції управління розподілом
    • загальні конфігурації плагінів (наприклад, Maven-compiler-source та цільові версії)
    • організація, розробники тощо

    Готувати цей батьківський пом потрібно з обережністю, тому що всі товариші вашої компанії успадковуватимуть його, тому ця помста повинна бути зрілою та стабільною (випуск версії батьківського пом не повинен впливати на звільнення всіх проектів вашої компанії!)

  • Другий вид батьківських пом - це багатомодульний батько. Я віддаю перевагу вашому першому рішенню - це умовна умова Maven для багатомодульних проектів, дуже часто являє собою структуру коду VCS

Намір полягає у масштабуванні масштабних конструкцій, тому він повинен бути масштабованим для великої кількості проектів та артефактів.

Mutliprojects мають структуру дерев - тому ви не обмежені до одного рівня батьківської пом. Спробуйте знайти відповідну структуру проекту для своїх потреб - класичний приклад - як десертирувати проекти мутімодулів

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

Кілька бонусних питань:

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

Цю конфігурацію треба розумно розділити на батьківську пам’ятку та батьківські пам’ятки проекту. Речі, пов'язані з усім проектом, переходять до материнської компанії, і це стосується поточного проекту.

  • Як плагін, hudson та nexus Maven-релізи погоджуються з тим, як ви створюєте свої багатопроектні проекти (можливо, велике питання, це більше, якщо хтось виявився, коли, як було створено багатопроектну збірку)?

Батьківську компанію Pom потрібно звільнити першою. Для багатопроектів застосовуються стандартні правила. Щоб правильно скласти проект, CI-серверу потрібно знати все.


1
Так що існують два типи батьківських проектів / партнерів. Один без <модулів> декларації. Це той, який використовується для спадкування. І батьківський проект з декларацією <multimodule>. Це той, від якого не успадковуються підмодулі, це просто керувати побудовою проекту hold. Маю рацію ?
lisak

22
  1. Незалежний батьків є найкращою практикою для спільного використання конфігурації та параметрів для інших нерозв’язаних компонентів. Apache має батьківський проект пом, щоб ділитися юридичними повідомленнями та деякими загальними варіантами упаковки.

  2. Якщо ваш проект вищого рівня в ньому справді працює, наприклад, агрегуючи javadoc або запакувавши випуск, то у вас виникнуть конфлікти між налаштуваннями, необхідними для цього, і налаштуваннями, якими ви хочете поділитися через батьків. Батьківський проект уникає цього.

  3. Поширений зразок (на даний момент ігноруючи №1) полягає в тому, щоб проекти з кодом використовували батьківський проект у якості батьків, і він повинен використовувати верхній рівень у якості батьків. Це дає змогу всім ділитися основними речами, але уникає проблеми, описаної у №2.

  4. Плагін сайту дуже заплутається, якщо батьківська структура не буде такою ж, як структура каталогів. Якщо ви хочете створити сукупний сайт, вам потрібно буде зробити кілька загадок, щоб обійти це.

  5. Apache CXF - приклад моделі в №2.


2
Я переглянув ibilio і, як видається, багато проектів віддають перевагу "незалежному" батьківському пом. Hibernate, ActiveMQ, Jetty, XStream тощо. Що говорить про те, що це механізм дефакто.
Джеймі МакКріндл

2
Ще одним недоліком незалежного батьків є те, що плагін випуску Maven, схоже, бажає, щоб батьків було прив’язано до версії, перш ніж він вийде. Можливо, це не велика проблема, оскільки батько не повинен занадто сильно змінюватися.
Джеймі МакКріндл

9

Є один маленький улов з третім підходом. Оскільки сукупні POM (myproject / pom.xml) зазвичай взагалі не мають батьківських налаштувань, вони не поділяють конфігурацію. Це означає, що всі ці сукупні POM матимуть лише сховища за замовчуванням.

Це не є проблемою, якщо ви використовуєте лише плагіни від центрального, однак це не вдасться, якщо ви запустите плагін у форматі plugin: target зі свого внутрішнього сховища. Наприклад, ви можете мати foo-maven-plugingroupId org.exampleзабезпечення мети generate-foo. Якщо ви спробуєте запустити його з кореня проекту за допомогою команди like 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?).
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.