ChatGPT解决这个技术问题 Extra ChatGPT

如何指定maven的distributionManagement组织范围?

我试图弄清楚如何组织许多(大约 50 多个)maven2 项目,以便它们可以部署到一个中央关系存储库中。使用 mvn deploy 目标时,确实需要在 distributionManagement 标记中指定目标,如下所示:

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

现在,我不希望每个 pom.xml(超过 50 个)都一遍又一遍地包含这个块。我的第一个虽然是 settings.xml 文件,但似乎不可能(按设计)在那里定义它。所以,第一个问题是,为什么会这样?如果可能的话,我可以在 maven2 发行版的 settings.xml 中指定它,它可以分发给所有开发人员。

我发现的唯一可能的解决方案是创建一个组织范围的 master-pom 项目,它确实包含这些设置,并通过 <parent> 标记使所有其他 pom.xml 依赖于这个 master-pom。但这在多模块构建中看起来有点奇怪:

- 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)

通常我在所有文档中都读到模块 pom 应该使用父 pom,而不是其他的。但是在阅读了有关继承与聚合的 maven 网站后,它写道确实是可能的。

我发现的一个问题是 maven 站点生成,它似乎确实存在此设置的问题(如果模块没有直接反向引用,则无法正确链接)

那么,这是一种有效的方法吗?任何其他更明显,更简单的问题解决方案?

@OhadR:他们只在一个项目中编写如何编写它。关键是我不想复制它大约 500 次......
我知道了。采取的观点。所以正如回答的人所说,你可以有一个项目的主 pom,它将包含'distribMngmnt'......

N
Neeraj Singh

最好的解决方案是为您组织的所有项目创建一个简单的父 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
请注意:为什么母公司是最佳解决方案的原因,请参阅 Maven 用户列表中的讨论 Can't specify distributionManagement in settings.xml
在“客户拥有代码”的经典咨询模型中,我的开发团队需要在场外处理项目,然后将最新的代码带到客户站点并重新构建。在我的情况下,使用多模块项目,如果我在项目父 POM 中引用公司 POM,我将不得不更新该引用以指向客户的公司 POM。如果可以的话,我宁愿努力维护 settings.xml 中的所有环境特定设置。对于我的情况,推荐的方法是什么?
@WebUser您的问题听起来更像是您在POM文件中需要不同值的情况,而不是这个答案解决的问题:避免跨多个模块的重复设置。我认为你应该试试 injecting properties via a settings.xml file。如果这对您没有帮助,请在 SO 上提出一个新问题,在此处链接到它,我会尽力为您提供进一步的帮助。
谢谢@JesseWebb,我最终确实尝试了这一点,对于我描述的情况,将这些值从 POM 中抽象出来是很有用的。根据我的需要,我在活动配置文件下添加了相关属性,并在 POM 中解决了这些属性。
h
hjoeren

不需要父 POM。

您可以在 poms 中完全省略 distributionManagement 部分,并将其设置在构建服务器或 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>

确保“快照”和“发布”的凭据位于 settings.xml 的 <servers> 部分

属性 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 或 -DaltDeploymentRepository=id::layout::url 参数中指定存储库元素。任何建议都会有所帮助。谢谢
@Shabirmean 原因是部署插件的版本太旧。我已经用解决方案扩展了我的答案。
是的,我想通了。非常感谢 :)
我无法让该解决方案的 settings.xml 部分与任何值一起使用。是否有尊重属性的 maven-deploy-plugin 的最低版本?
R
Robert Newton

关于 Michael Wyraz 的 answer,您在 settings.xml 或命令中使用 alt*DeploymentRepository,如果您使用 maven-deploy-plugin 的 3.0.0-M1 版本(这是最新的编写时的版本),此版本中有一个 bug 可能会导致服务器身份验证问题。

解决方法如下。在值:

releases::default::https://YOUR_NEXUS_URL/releases

您需要删除 default 部分,使其:

releases::https://YOUR_NEXUS_URL/releases

之前的 2.8.2 版本没有这个 bug。


我总是收到“401 未授权”之类的消息,删除默认设置可以解决我的问题。谢谢