Как реструктурировать многомодовый проект Maven?

Я приговариваю к длине этого сообщения, но мне было трудно сделать его более кратким, не представляя картинку. Недавно я унаследовал работу мастера сборки для мультимодульного проекта maven 3.0. Проблема в том, что структура проекта/модулей является катастрофой. Из того, как вещи хранятся в Source Control (мы используем RTC) для структуры pom модулей, я разрываю волосы, пытаясь получить полный цикл сборки, завершенный каждый раз.

В качестве иерархии проекта все модули сохраняются "плоскими"; т.е.: все находится на одном уровне. У меня родительский pom, и все модули зависят от родителя. Однако родительский элемент находится на том же уровне, что и все мои другие модули.

Пример:

c:\dev\MyEarProject
 + parent-pom
   - pom.xml
 + module1
   - pom.xml (depends on parent-pom)
   - src
   -   main
   -     ...
 + module2
   - pom.xml (depends on parent-pom)
   - src
   -   main
   -     ...
 + module3
   - pom.xml (depends on parent-pom)
   - src
   -   main
   -     ...

Родительский pom определяет все модули, необходимые для создания проекта, а также набор свойств для номеров версий артефакта, используемых во всех подмодулях:

<modules>
  <module>../module1</module>
  <module>../module2</module>
  <module>../module3</module>
</modules>

<properties>
    <org.springframework.version>3.0.5.RELEASE</org.springframework.version>
    <slf4j.version>1.6.4</slf4j.version>
    <repositoryAddress>${snapshots.repo.url}</repositoryAddress>
    <my.hibernate-module.dao.impl>1.2.3</my.hibernate-module.dao.impl>
    <my.hibernate-module.dao.api>1.2.3</my.hibernate-module.dao.api>
</properties>

Каждый модуль pom, в свою очередь, зависит от родительского pom через номер артефакта pom:

<parent>
    <groupId>com.cws.cs.lendingsimulationservice</groupId>
    <artifactId>parent-pom</artifactId>
    <version>1.0.6</version>
</parent>

Чтобы сделать вещи еще более запутанными, фактическое имя артефакта может или не может (в зависимости от модуля) соответствовать пути к модулю. Например, модуль 1 может быть расположен в пути c:\dev\MyEarProject\module1, но имеет имя артефакта hibernate-module. Однако из-за того, что он хранится в RTC, каталог вызывается module1, когда он выгружен.

Самый простой способ построить все, конечно, - это войти в c:\dev\MyEarProject\parent-pom\ и запустить mvn clean deploy. Это отлично работает в режиме SNAPSHOT, так как репозиторий SNAPSHOT допускает множественное развертывание одной и той же версии артефакта. Но в режиме выпуска это не удается.

Эта структура вызывает для меня 2 проблемы.

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

Итак, я ищу лучший способ реструктурировать этот проект, чтобы избежать этих проблем. Для родительского pom я знаю, что я могу использовать относительный путь, чтобы вместо этого указывать на родителя. Однако, учитывая "плоскую" структуру модулей, это рекомендуемый подход (то есть: относительный путь родительского пома был бы.. /parent -pom/pom.xml - кажется немного странным для меня)? Кроме того, учитывая, что управление версиями родителя не зависит от модулей, использование относительного пути не только откроет дверь для дополнительной путаницы (т.е. Не будет никакого способа узнать, какая версия родительского помпа связана с какой версией подмодуля).

Во-вторых, как я могу построить все ухо, не сталкиваясь с ошибками развертывания, которые у меня есть? Поскольку артефакт уже существует в репо, мне не нужно его перестраивать и переустанавливать. Я попытался использовать --projects, но с количеством задействованных модулей, с ним очень сложно справиться.

Ответ 1

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

  +-- parent-pom (pom.xml)
       +--- module1 (pom.xml)
       +--- module2 (pom.xml)
       +--- module3 (pom.xml)

В результате этого раздел модулей ваш родитель будет упрощен следующим образом:

<modules>
  <module>module1</module>
  <module>module2</module>
  <module>module3</module>
</modules>

Кроме того, можно упростить и родительские записи в ваших модулях:

<parent>
  <groupId>com.cws.cs.lendingsimulationservice</groupId>
  <artifactId>parent-pom</artifactId>
  <version>1.0.6</version>
</parent>

..., что приводит меня к следующему пункту:

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

Если мы исправим эту проблему, это должно выглядеть так, что я не могу рекомендовать:

<parent>
  <groupId>com.cws.cs.lendingsimulationservice</groupId>
  <artifactId>parent-pom</artifactId>
  <version>1.0.6</version>
  <relativePath>../parent-pom/pom.xml</relativePath>
</parent>

Другая вещь, которую я наблюдаю, заключается в том, что вы не используете SNAPTSHOT, который будет заменен плагином выпуска во время фазы выпуска. И в связи с этим он автоматически изменит все версии в соответствующих родителях и т.д.

В идеальном случае ваши модули должны выглядеть так:

<parent>
  <groupId>com.cws.cs.lendingsimulationservice</groupId>
  <artifactId>parent-pom</artifactId>
  <version>1.0.6</version>
</parent>

<artifactId>module-1</artifactId>
<!-- No Version or groupId -->

Потому что все модули наследуют версию и groupId от своего родителя. Иногда это полезно или необходимо для изменения модулей groupId, но это исключение.

В том, что я перечитываю, речь идет о отдельном версировании родителя. Это просто не имеет смысла, потому что он является родителем своих модулей, поэтому ставит его в ту же структуру и, конечно же, тот же VCS.

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

После того, как вы закончили изменения структуры, вы можете просто перейти в каталог parent-pom и сделать mvn clean package или mvn release:prepare release:perform из этой папки, и все будет проще.

Ответ 2

Если вы публикуете свой POM, вам придется выпускать любые обновления, но вам не нужно вручную изменять версии POM - вы можете обновлять версии автоматически, используя плагин версий или плагин выпуска. Я предпочитаю плагин релиза, так как он также передаст вам SCM.

mvn versions:set 

http://mojo.codehaus.org/versions-maven-plugin/

mvn release:prepare release:perform

http://maven.apache.org/plugins/maven-release-plugin/

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

Я предпочитаю структуру плоского модуля, поскольку он позволяет использовать родительскую папку для хранения общих файлов, например. Конфигурация контрольного образца. Я также считаю полезным делиться идентификатором группы между модулями, а затемменовать каталог модулей так же, как и файл artifactId.

Ответ 3

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

Учитывая, что изменения в одном модуле неизбежно повлияют на все зависимые модули, я бы использовал схему простой версии, где все подмодули наследуют родительскую версию. maven release: подготовка и выпуск циклов становятся простыми. Используйте примечания к выпуску, чтобы отслеживать изменения и оправдывать пропуски ненужного тестирования неизмененных модулей (изменения в версии не изменяют сборку/двоичный вывод процесса сборки, поэтому вы можете использовать это как основной аргумент).

Удачи вам в вашем проекте.