【问题标题】:How do I properly setup a multi-module Maven project with sliding release cycles如何正确设置具有滑动发布周期的多模块 Maven 项目
【发布时间】:2010-11-15 15:52:42
【问题描述】:

我正在尝试找出最好的方法来设置我们的多模块 Apache Maven 项目,这种方式允许模块的不同发布周期,并且在调试项目时不会引入依赖问题。

我们目前的设置如下:

  • 大系统@1.2
    • parent-1.1-SNAPSHOT
    • 模块 a@1.4-SNAPSHOT
      • 以 parent@1.1-SNAPSHOT 为父
    • 模块 b@1.3-SNAPSHOT
      • 以 parent@1.1-SNAPSHOT 为父
      • 依赖于@1.1
    • 模块 c@1.1-SNAPSHOT
      • 以 parent@1.1-SNAPSHOT 为父
      • 依赖于@1.2
      • 取决于 b@1.1

模块 b 和 c 中声明的依赖项包含编译模块所需的最低版本,不一定是模块的当前版本,也不一定是正在部署的模块的版本。

从构建的角度来看,这很好用,每个模块都可以根据需要发布/更新,但是当尝试在打开顶层 pom 的 IntelliJ IDEA(版本 8 和 9 EAP)下调试部署的应用程序时,IDEA 决定,因为我们声明了对 a@1.2 的依赖,每当我们进入 a 的一个类时,它应该从 a-1.2-sources.jar 而不是项目中当前的 a@1.4 源打开它。步入 b 的任何类都会将我们带到 b@1.1 而不是 b@1.3,这一事实进一步混淆了这一点。

我最初尝试解决这个问题是在父 pom 的 dependencyManagement 部分中声明版本号,并让子模块继承该版本。这在一定程度上解决了 IDEA 调试问题,因为 dependencyManagement 部分可以将每个人指向当前的 -SNAPSHOT 版本。

不幸的是,由于在发布模块之前必须释放父 pom,因此在执行 maven 发布时会出现问题,但由于父级可能引用多个正在开发的 -SNAPSHOTS,因此无法发布它,我们最终添加版本引用回模块 pom 以满足发布。

似乎只有在我们同时发布所有捆绑包时,使用 maven 的依赖管理部分才能真正发挥作用,无论它们是否发生变化,但因为我们只想在需要时管理每个子模块的发布模型似乎不合适。

我怀疑我遗漏了一些东西,并且dependencyManagement 和版本范围的组合可能会满足要求,尽管我还没有看到版本范围正常工作。

有没有更好的方法?正确的方法?

【问题讨论】:

    标签: java maven-2 intellij-idea


    【解决方案1】:

    我建议不要让它们成为模块,而是让它们的 POM 独立。这样您就不必担心尝试满足父 POM 依赖项。由于它们是独立发布的,因此它们确实应该具有独立的项目对象模型。将 Apache Commons 视为模板。

    【讨论】:

    • 嗯,即使每个子项目的 POM 是独立的,我仍然会从顶级 pom 中引用它们,以便整个项目可以由 IDEA/Netbeans 构建或打开 - 这仍然给出调试问题或版本不匹配。我怀疑我遇到的问题有两个——虽然它们是独立发布的,但它们是作为一个系统部署在一起的,而不是单独的独立项目,更多的是在调试时,没有关于 WHAT 版本正在运行的版本信息。
    • 进一步思考,我怀疑我在这里面临的版本范围问题是,每当更改任何模块时,我们的 CI 工具都会构建/安装顶级模块,这将安装 -SNAPSHOT所有模块的版本,即使它们是新发布的,但未修改。如果按照您的建议,我删除了多模块构建并配置构建服务器以单独监视每个模块,这应该有助于解决发布问题。
    • 绝对将您的模块分解为它们自己的顶级项目。模块旨在一起构建和发布。此外,考虑利用像 Hudson 的自动重建(由 Maven 依赖项 (weblogs.java.net/blog/johnsmart/archive/2008/11/…) 确定)来确保低级别依赖项中的更改自动传播并与高级依赖项一起重建。
    【解决方案2】:

    它们当然看起来像是独立的模块。如果它们具有不同的依赖关系,即使在多模块项目中,将它们组合在一起有什么好处?

    【讨论】:

    • 在这种情况下,父 POM 定义了标准插件配置,例如包括 maven-felix-bundle 和 maven-felix-scr 插件。我不会称它们为“粉碎在一起”,每个模块都声明了自己的依赖项 - 外部依赖项可以在它们不经常更改的依赖管理中轻松处理,我遇到的问题是我自己模块的版本.
    【解决方案3】:

    我认为 IDEA 的问题是因为您在源结构中使用根 POM 来执行在 Maven 中通常互斥的两件事。您首先使用 POM 作为存储不相关(从构建角度)Maven 项目的通用配置信息的位置。其次,您将 POM 用作构建的聚合器。您可以在不做其他事情的情况下完成其中的每一项。

    就像 Rob 所说,从父 POM 的模块部分中删除模块 a、b 等项目。其次,将你的父 POM 移到它自己的目录中,因为就你的构建和发布过程而言,它实际上是其他模块的兄弟。你现在拥有它的方式,它更像是一个父/聚合器。

    您现在拥有它的方式也不适合单独标记和释放每个模块,因为您的父 POM 的标记可能会不必要地包含所有模块子文件夹。

    您的文件结构如下所示:

    • 父级
      • pom.xml
    • 模块一
      • pom.xml
    • 模块 X
      • pom.xml

    至于您缺少的东西,dependencyManagement 并不是很适合管理项目内依赖项的版本。那是聚合构建中模块之间的依赖关系。它更适合为外部依赖声明全局版本。

    【讨论】:

    • 不过,好的 cmets - 您和其他评论者似乎认为我的根 POM 包含我的通用配置。我提到将它添加到与我的模块在同一层的父 POM,就像您在结构中显示的那样,根 POM 在它们之上。
    【解决方案4】:

    我们最终使用的最终/可行的解决方案与我们开始使用的非常相似。实际项目结构保持不变:

    • 大系统@1.2
      • parent-1.1-SNAPSHOT
      • 模块 a@1.4-SNAPSHOT o 由 parent@1.1-SNAPSHOT 提供
      • 模块 b@1.3-SNAPSHOT o 由 parent@1.1-SNAPSHOT 提供 o 依赖于@1.1
      • 模块 c@1.1-SNAPSHOT o 由 parent@1.1-SNAPSHOT 提供 o 取决于 a@1.2 o 取决于 b@1.1
      • 分布a@1.2-SNAPSHOP

    但主要区别在于:

    • 父模块不包含任何版本的项目工件
    • 各个模块完全声明其项目依赖关系并指定版本范围,即[1.0.0,1.1.0)
    • 所有模块都从 0.1 开始版本号周期,即 1.0.1-SNAPSHOT,这允许初始快照满足版本范围(1.0.0-SNAPSHOT 早于 1.0.0 最终版本,因此不包括在内)。
    • distribution pom(最初未在问题中显示)标识要部署/包含在特定版本中的确切版本。
    • 在发布时从本地 maven 存储库中删除所有项目 -SNAPSHOTS,以便仅使用拾取版本(或使用 -Dmaven.repo.local=/tmp/sometemprepo 获取新的本地存储库)

    这使得每个模块更加独立,让我们可以轻松地发布和部署项目工件的新版本。

    【讨论】:

    • 您能否详细说明“分发 pom”中的内容 - 它如何确定要部署或发布的每个模块的版本?也许是一个例子?
    猜你喜欢
    • 2011-06-02
    • 2020-11-01
    • 2017-12-26
    • 2014-04-18
    • 2011-07-07
    • 1970-01-01
    • 1970-01-01
    • 2014-03-31
    • 2016-12-31
    相关资源
    最近更新 更多