Вопрос по java, maven – Как реструктурировать мультимодульный проект Maven?

11

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

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

Пример:

<code>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
   -     ...
</code>

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

<code><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>
</code>

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

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

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

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

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

Everytime I need to make a version change to a property in the parent, I have to update the parent-pom version number, and all the child modules parent pom's version, and all the child modules version themselves (since the parent changed). Whenever I need to deploy a release cycle, mvn will throw an error if one of the modules has not changed since the last cycle and consequently cannot be redeployed to the same repo (the repo does not allow overwriting existing artifacts)

Поэтому я ищу лучший способ реструктуризации этого проекта, чтобы избежать этих проблем. Я знаю, что для родительского pom я могу использовать относительный путь, чтобы указать на родителя. Тем не менее, учитывая «плоский» Структура модулей, это рекомендуемый подход (то есть: относительный путь родительского pom будет ../parent-pom/pom.xml - мне кажется немного странным)? Кроме того, учитывая, что управление версиями родительского элемента не зависит от модулей, использование относительного пути не просто откроет дверь для дополнительной путаницы (т. Е. Не было бы способа узнать, какая версия родительского pom связана с какой версией субмодуля).

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

Ваш Ответ

3   ответа
12

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

  +-- 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 из этой папки, и все будет проще.

У меня проблемы с пониманием того, как это сделать с номером версии, который определен только в родительском файле. В моей текущей настройке я могу изменить интерфейс в модуле, не затрагивая остальную часть сборки, пока не наступит время реинтеграции новой версии. Если версия только в родительской версии, изменение интерфейса модуля нарушит остальную часть сборки, поскольку все модули будут полагаться на исходное дерево, а не на предварительно развернутый двоичный файл. Как мне избежать этой проблемы? Мне все еще нужно индивидуально настроить каждый модуль, не так л Eric B.
Если бы мы решили эту проблему, она должна выглядеть так, что я не могу порекомендовать - так что вы рекомендуете? Kalpesh Soni
К сожалению, реструктуризация, чтобы иметь древовидную структуру, не является опцией, учитывая способ, которым RTC и компоненты / модули были настроены для этого проекта. Таким образом, я должен жить с текущим strcuture / layout и вынести лучшее из ситуации. Помещение версии на родительский уровень для наследования всеми дочерними модулями, по сути, означает перестройку / повторное тестирование / повторное развертывание всех модулей (что может быть дорогостоящим), даже если в одном модуле было только изменение. По сути, я теряю способность самостоятельно устанавливать версии одного модуля. Хотя я согласен; это решило бы мою проблему развертывания. Eric B.
Если тебе нравится продолжать борьбу с Мейвеном, это твоя очередь, но я рекомендую изменить структуру, потому что это облегчит твою жизнь. Но если идея развертывания каждого модуля в отдельности не имеет смысла. Либо они связаны, то нет. Если это не так, вы должны разделить их и не использовать многомодульную сборку. khmarbaise
Если вам действительно нужны отдельные версии, что означает, другими словами, отдельные версии, вам нужно иметь отдельные модули, а не многомодульную сборку. khmarbaise
2

вам придется выпускать какие-либо обновления, но вам не нужно изменять версии 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.

Плагин версий должен иметь возможность обновлять зависимости для вас, тогда вы можете просто зафиксировать и развернуть новые артефакты. cvanes
Я давно не использовал релизный плагин, но я не понимаю, как он решит мою проблему, когда мне нужно перевести отдельный модуль в новую версию. Если требуется обновление модуля 3 (с версии 1.1 до 1.2-SNAPSHOT), а модуль 1 зависит от модуля 3, я обновляю pom module3, свойство parent-pom, версию parent-pom, родительскую версию module3 и, наконец, parent-версию module1 и версию module1. Как плагин релиза может сделать все это для меня? Обратите внимание, что на этом этапе module2 не требуется ничего менять. Eric B.
2

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

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

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

Похожие вопросы