Как указать Maven DistributionManagement в масштабах всей организации?

110

Я пытаюсь понять, как организовать множество (около 50+) проектов maven2, чтобы их можно было развернуть в центральном репозитории nexus. При использовании mvn deployцели необходимо указать цель в теге distributionManagement следующим образом:

<distributionManagement>
   <repository>
      <id>nexus-site</id>
        <url>http://central_nexus/server</url>
   </repository>
</distributionManagement>

Теперь я не хочу, чтобы каждый pom.xml (из этих 50+) снова и снова содержал этот блок. Моим первым хоть и был бы settings.xmlфайл, но мне кажется, что невозможно (по замыслу) определить его там. Итак, первый вопрос: почему это так? Если бы это было возможно, я мог бы указать его в settings.xml в дистрибутиве maven2, который можно было бы распространить среди всех разработчиков.

Единственное возможное решение, которое я нашел, - это создать проект master-pom для всей организации, который действительно содержит эти настройки, и сделать все остальные pom.xml зависимыми от этого master-pom через <parent>тег. Но в многомодульных сборках это выглядит странно:

- master configuration POM (pm)
- Project 1 parent pom (p1 with module 1 and module 2 as modules)
    - Project 1 module pom (with pm as parent)
    - Project 2 module pom (with pm as parent)

Обычно я читаю во всей документации, что модули poms должны использовать родительский pom, а не какой-то другой. Но после прочтения сайта maven о наследовании против агрегирования написано, что это действительно возможно.

Одна проблема, которую я обнаружил, связана с генерацией сайта maven, которая, похоже, имеет проблемы с этой настройкой (модули не связываются правильно, если у них нет прямой обратной ссылки)

Итак, это правильный подход? Есть ли другое, более очевидное и простое решение проблемы?

mglauche
источник
5
@OhadR: Пишут только как написать в одном проекте. Дело в том, что я не хотел дублировать его примерно 500 раз ...
mglauche
1
Понимаю. Дело принято. так что, как сказал тот, кто ответил, у вас может быть главный pom для проекта, который будет содержать 'distribMngmnt' ...
OhadR

Ответы:

144

Лучшее решение для этого - создать простой проект родительского файла pom (с упаковкой pom) в общем для всех проектов вашей организации.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>your.company</groupId>
    <artifactId>company-parent</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <distributionManagement>
        <repository>
            <id>nexus-site</id>
            <url>http://central_nexus/server</url>
        </repository>
    </distributionManagement>

</project>

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

Теперь для всех проектов, которые вы хотите использовать, просто включите этот раздел:

<parent>
  <groupId>your.company</groupId>
  <artifactId>company-parent</artifactId>
  <version>1.0.0</version>
</parent>

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

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

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

- pom.xml (aggregator)
    - project-parent
    - project-module1
    - project-module2

Что вы делаете с этой структурой, так это включаете свой родительский модуль в агрегатор и строите все с помощью mvn installиз корневого каталога.

Мы используем именно это решение в моей организации, оно выдержало испытание временем и хорошо сработало для нас.

Джесси Уэбб
источник
Вот еще один ответ, в котором я более подробно описываю наследование проекта и способы управления его сложностью наследования, простите за каламбур. ;) stackoverflow.com/questions/6347913
Джесси Уэбб
7
Небольшое примечание: по причинам, по которым компания-родитель является лучшим решением, см. Обсуждение Невозможно указать distributionManagement в settings.xml из списка пользователей Maven.
Premek Brada
В классической модели консалтинга, в которой «клиент владеет кодом», моей команде разработчиков нужно будет работать над проектом вне офиса, а затем перенести последний код на сайт клиента и построить его заново. В моей ситуации, работая с многомодульным проектом, если я ссылаюсь на POM компании в родительском POM проекта, мне придется обновить эту ссылку, чтобы указать на POM компании клиента. Я бы предпочел сохранить все настройки для конкретной среды в settings.xml, если я могу помочь. Какой подход рекомендуется для моей ситуации?
Веб-пользователь
2
@WebUser. Ваша проблема больше похожа на ситуацию, когда вам нужны разные значения в ваших файлах POM, а не то, на что отвечает этот ответ: избегание дублирования настроек в нескольких модулях. Я думаю, вам стоит попробовать ввести свойства через файл settings.xml . Если это вам не поможет, задайте новый вопрос здесь, в SO, дайте ссылку на него здесь, и я постараюсь вам помочь.
Джесси Уэбб
Спасибо @JesseWebb. В конце концов, я попробовал это, и полезно абстрагировать эти значения от POM для ситуации, которую я описал. Для своих нужд я добавил соответствующие свойства в активный профиль и те, которые были разрешены в POM.
Web User
36

В родительском POM нет необходимости.

Вы можете полностью опустить часть distributionManagement в своих poms и установить ее либо на сервере сборки, либо в settings.xml.

Чтобы сделать это на сервере сборки, достаточно перейти к mvnкоманде:

-DaltSnapshotDeploymentRepository=snapshots::default::https://YOUR_NEXUS_URL/snapshots
-DaltReleaseDeploymentRepository=releases::default::https://YOUR_NEXUS_URL/releases

См. Https://maven.apache.org/plugins/maven-deploy-plugin/deploy-mojo.html для получения подробной информации о том, какие параметры можно установить.

Также возможно установить это в вашем settings.xml.

Просто создайте там профиль, который включен и содержит свойство.

Пример settings.xml:

<settings>
[...]
  <profiles>
    <profile>
      <id>nexus</id>
      <properties>
        <altSnapshotDeploymentRepository>snapshots::default::https://YOUR_NEXUS_URL/snapshots</altSnapshotDeploymentRepository>
        <altReleaseDeploymentRepository>releases::default::https://YOUR_NEXUS_URL/releases</altReleaseDeploymentRepository>
      </properties>
    </profile>
  </profiles>

  <activeProfiles>
    <activeProfile>nexus</activeProfile>
  </activeProfiles>

</settings>

Убедитесь, что учетные данные для «снимков» и «выпусков» находятся в <servers>разделе вашего settings.xml.

Свойства altSnapshotDeploymentRepository и altReleaseDeploymentRepository представлены в maven-deploy-plugin версии 2.8. Более старые версии не будут отображаться с сообщением об ошибке

Deployment failed: repository element was not specified in the POM inside distributionManagement element or in -DaltDeploymentRepository=id::layout::url parameter

Чтобы исправить это, вы можете установить более новую версию плагина:

        <build>
          <pluginManagement>
            <plugins>
              <plugin>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>2.8</version>
              </plugin>
            </plugins>
          </pluginManagement>
        </build>
Майкл Вайраз
источник
Я постоянно пробую это решение, но работает только свойство altDeploymentRepository . altReleaseDeploymentRepository и altSnapshotDeploymentRepository не распознаются, и я получаю эту ошибку: Ошибка развертывания: элемент репозитория не был указан в POM внутри элемента distributionManagement или в параметре -DaltDeploymentRepository = id :: layout :: url. Любое предложение поможет. Спасибо
Shabirmean
@Shabirmean Причина в том, что установлена ​​слишком старая версия плагина развертывания. Я расширил свой ответ решением.
Майкл Вайраз
Да, я понял. Большое спасибо :)
Shabirmean