Как переместить мультимодульные проекты в maven

Мы пытаемся переместить несколько мультимодульных приложений на maven и иметь некоторые проблемы.

Каждый модуль хранится независимо в cvs. У нас есть файлы манифеста для каждого приложения, в которых перечислены модули, необходимые для этого приложения (и, возможно, версия). Не все модули находятся в форме maven.

Итак, приложение customer_care имеет следующий манифест:

 <manifest>
 <module id="MY_api"/>
 <module id="custcare_webapp"/>
 </manifest>

Аналогично, приложение "core batch" имеет такой манифест:

 <manifest>
 <module id="MY_api"/>
 <module id="core"/>
 <module id="batch"/><!--NB this is a non-maven module -->
 </manifest>

Я начал "mavenising" наш код, поэтому проект MY_api имеет pom.xml с определенными зависимостями, в том числе один на другом внутреннем модуле кода "central_config". Я указал версию RELEASE.

Проблема

Все это работает отлично, пока мне не нужно создать замороженный манифест. Я могу указать версию для каждого модуля:

 <manifest>
 <module id="MY_api" version="0.123.0"/>
 <module id="core" version="0.456.0"/>
 <module id="batch" version="0.789.0"/><!--NB this is a non-maven module -->
 </manifest>

НО эта сборка не воспроизводится, потому что версия зависимости "centralconfig" в MY_api - "RELEASE". Поэтому, если кто-то выпускает новую версию "centralconfig", то в следующий раз мы создадим этот замороженный манифест, он отличается.

Итак, почему мы не используем жестко кодированные версии зависимостей, такие как central-config? Потому что тогда нам придется обновлять, возможно, 10 или 20 файлов pom каждый раз, когда кто-то обновляет centralconfig до новой версии. Все, что зависит от центральной конфигурации и всего, что от этого зависит, нуждается в обновлении pom.xml и будет повторно выпущено. Мало того, что это много работы, я не знаю, как я мог программно и надежно идентифицировать каждый модуль, который объявляет зависимость от центральной конфигурации.

Возможное решение?

Можно ли определить "centralconfig.version" в одном месте, а затем обратиться к нему во всех моих модулях? Если да, где я должен это делать? Я не очень разбираюсь в родительских позах, но я чувствую, что они могут предоставить решение.

Update

Кажется, что использование родительского помпа - путь. Но в соответствии с этим вопросом: Могут ли проекты maven иметь несколько родителей?, невозможно, чтобы у дочернего проекта maven было несколько родителей.

Итак, как может MY_api-модуль быть дочерним и custcare_webapp и core_batch?

Update

Я пришел к выводу, что maven не отвечает моим требованиям, и мы вернулись к использованию нашего 12-летнего домашнего решения с использованием ant и CVS.

Ответ 1

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

Чтобы проиллюстрировать, как это работает, вы создаете один проект, содержащий только pom, определяющий версии для всех ваших модулей:

<project>
 <modelVersion>4.0.0</modelVersion>
 <groupId>test</groupId>
 <artifactId>module-versions</artifactId>
 <packaging>pom</packaging>
 <version>1.0</version>
 <dependencyManagement>
   <dependencies>
     <dependency>
       <groupId>test</groupId>
       <artifactId>a</artifactId>
       <version>1.1</version>
     </dependency>
     <dependency>
       <groupId>foo</groupId>
       <artifactId>bar</artifactId>
       <version>2</version>
     </dependency>
   </dependencies>
 </dependencyManagement>
</project>

Затем во всех ваших проектах, которые должны иметь зависимости от anyhing, которые у вас есть жестко закодированные версии, вы импортируете этот проект следующим образом:

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>test</groupId>
        <artifactId>module-versions</artifactId>
        <version>1.0</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

Таким образом вам остается только изменить проект module-versions в любое время, когда вы выпускаете новую версию чего-либо, к чему у вас есть зависимость.

Таким образом, вы можете иметь несколько "модулей-версий" -проектов, чтобы разбить вещи немного.

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

Ответ 2

Я думаю, вам нужен родительский POM. Это топ-уровень pom.xml, который является исключительно модулем POM и не имеет связанного кода. Вы строите весь проект, запустив команду mvn на этом pom.xml.

POM должен находиться в каталоге выше всех каталогов модулей. То есть каждый из ваших модулей будет находиться в подкаталоге каталога, в котором находится мастер pom.xml

Этот тип POM <packaging> будет pom. Это означает, что это проект только для POM без собственного кода. Он также будет иметь тег <modules>, содержащий один элемент <module> для каждого из ваших модулей. Таким образом, когда вы запускаете команду mvn, Maven будет знать, как построить каждый из этих модулей. Здесь находится достойный образец родительского ПОМ .

Задайте все ваши зависимости в этом POM, используя стандартный тег <dependencies>. Модули POM наследуют их. ( Обновить: см. комментарии ниже, определенно стоит изучить тег <dependencyManagement> вместо родительского POM.)

Наконец, каждый из POM-модулей модуля должен вернуться к главному POM. Таким образом, если вы запустите mvn в одном из каталогов модулей (т.е. Вы просто строите один модуль), он будет искать родителя для зависимостей. Вы делаете это с тегом <parent>, который будет содержать <groupid> и <artifactid> главного ПОМ. Хороший пример тега <parent>, а также хороший общий обзор многомодульных проектов здесь.