如何正确地设置具有滑动发布周期的多模块Maven项目

时间:2023-01-13 12:26:29

I'm trying to work out the best way to setup our multi-module Apache Maven project in a way that allows for disparate release cycles of modules, and doesn't introduce dependency issues when debugging the project.

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

We currently have a setup along the lines of:

我们目前有一个类似的设置:

  • bigsystem@1.2
    • parent-1.1-SNAPSHOT
    • 母公司- 1.1 -快照
    • module a@1.4-SNAPSHOT
      • parented by parent@1.1-SNAPSHOT
      • 父子关系通过parent@1.1-SNAPSHOT
    • 由parent@1.1-SNAPSHOT解析的模块a@1.4-SNAPSHOT
    • module b@1.3-SNAPSHOT
      • parented by parent@1.1-SNAPSHOT
      • 父子关系通过parent@1.1-SNAPSHOT
      • depends on a@1.1
      • 取决于a@1.1
    • parent@1.1-SNAPSHOT代理的模块b@1.3-SNAPSHOT依赖于a@1.1
    • module c@1.1-SNAPSHOT
      • parented by parent@1.1-SNAPSHOT
      • 父子关系通过parent@1.1-SNAPSHOT
      • depends on a@1.2
      • 取决于a@1.2
      • depends on b@1.1
      • 取决于b@1.1
    • parent@1.1-SNAPSHOT代理的模块c@1.1-SNAPSHOT依赖于a@1.2依赖于b@1.1
  • 由parent@1.1-SNAPSHOT模块b@1.3-SNAPSHOT快照由parent@1.1-SNAPSHOT模块b@1.3-SNAPSHOT快照支持,依赖于由parent@1.1-SNAPSHOT支持的a@1.1模块c@1.1-SNAPSHOT快照依赖于a@1.2依赖于b@1.1

The dependencies declared in modules b and c contain the minimum version required to compile the module, which isn't necessarily the current version of the module, or the version of the module being deployed.

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

From a build perspective this works well, each module can be released/updated as needed, however when trying to debug the deployed application under IntelliJ IDEA (versions 8 and 9 EAPs) having opened the top level pom, IDEA decides that since we declared a dependency on a@1.2, that anytime we step into one of a's classes, it should open it from a-1.2-sources.jar rather than the current a@1.4 sources in the project. This is further confused by the fact that stepping into any of b's classes takes us to b@1.1 rather than b@1.3.

从构建的角度来看这工作得很好,每个模块可以根据需要发布/更新,然而在尝试调试已部署的应用程序在IntelliJ IDEA(版本8和9中心打开了*pom,想法决定,因为我们宣布依赖a@1.2,随时,我们进入一个的一个类,它应该从- 1.2 -来源打开它。jar而不是项目中当前的a@1.4源。更让人困惑的是,进入b的任何一个类都会将我们带到b@1.1而不是b@1.3。

My initial attempt to work around this was to declare the version numbers in the parent pom's dependencyManagement section and just have the sub-modules inherit the version. This worked to the degree of solving the IDEA debug issue as the dependencyManagement section can point everyone to the current -SNAPSHOT versions.

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

This unfortunately causes a problem when doing a maven release due to having to release the parent pom before releasing the module, but as the parent may refer to multiple in-development -SNAPSHOTS it can't be released and we end up adding version references back to the modules pom to satisfy the release.

时,这种不幸的原因问题做一个maven版本由于不得不释放父pom释放模块之前,但随着父母可能是指多个研的快照不能释放,我们最终添加版本引用回模块pom满足释放。

It would seem that using maven's dependencyManagement section would only really work well if we were releasing ALL bundles at the same time, regardless of if they changed, but as we're wanting to manage releases of each sub module only when needed this model doesn't seem to fit.

似乎使用maven的dependencyManagement一节只有在同时发布所有包(不管它们是否发生了更改)的情况下才能正常工作,但是因为我们希望在需要的时候管理每个子模块的发布,所以这个模型似乎并不适合。

I have a suspicion I'm missing something, and that a combination of dependencyManagement and version ranges might satisfy out requirements although I've yet to see version ranges work properly.

我怀疑我漏掉了一些东西,依赖管理和版本范围的组合可能满足需求,尽管我还没有看到版本范围正常工作。

Is there a better way? A proper way?

有更好的方法吗?一个合适的方式?

4 个解决方案

#1


4  

I would recommend not making them modules, but make their POMs independent. That way you do not have to worry about trying to satisfy parent POM dependencies. Since they are released independently, they really should have independent project object models. Think of Apache Commons as a template.

我建议不要让它们成为模块,而是让它们的pom独立。这样,您就不必担心如何满足父POM依赖项。由于它们是独立发布的,所以它们实际上应该有独立的项目对象模型。可以将Apache Commons看作模板。

#2


2  

I think the problem with IDEA arises because you are using the root POM in your source structure to do two things that are usually mutually exclusive in Maven. You are first using the POM as a location to store common configuration information for unrelated (from a build perspective) Maven projects. Secondly you are using the POM as an aggregator for your build. You can do each of these without doing the other.

我认为问题出在IDEA上,因为您正在使用源结构中的根POM来做两件事,这两件事在Maven中通常是相互排斥的。您首先使用POM作为位置,为不相关(从构建角度)的Maven项目存储公共配置信息。其次,您正在使用POM作为构建的聚合器。你可以不做其他的就做这些。

Like Rob said, remove your module a, b, etc. projects from the modules section of your parent POM. Secondly, move your parent POM down into its own directory as it is really a sibling of the other modules with respect to your build and release process. The way you have it now, it is more of a parent/aggregator.

如Rob所说,从父POM的模块部分删除模块a、b等项目。其次,将父POM移动到它自己的目录中,因为它实际上是与构建和发布过程相关的其他模块的兄弟。现在的方法是,它更多的是一个父/聚合器。

The way you have it now also doesn't lend itself to tagging and releasing each module individually as a tag of your parent POM would likely needlessly include all of the module sub-folders.

现在的方法也不支持将每个模块单独作为父POM的标记进行标记和释放,可能不必要地包含所有模块子文件夹。

Your file structure would look like:

您的文件结构如下:

  • parent
    • pom.xml
    • pom.xml
  • 父母pom.xml
  • module a
    • pom.xml
    • pom.xml
  • 模块一个pom.xml
  • module X
    • pom.xml
    • pom.xml
  • 模块X pom.xml

As for the thing you are missing, dependencyManagement isn't really well suited to manage versions for intra-project dependencies. That is dependencies between modules within an aggregated build. It is more well suited for declaring global versions for external dependencies.

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

#3


2  

The final/working solution we ended up using was fairly similar to what we started with. The actual project structure remains the same:

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

  • bigsystem@1.2
    • parent-1.1-SNAPSHOT
    • 母公司- 1.1 -快照
    • module a@1.4-SNAPSHOT o parented by parent@1.1-SNAPSHOT
    • 模块a@1.4-SNAPSHOT o由parent@1.1-SNAPSHOT解析
    • module b@1.3-SNAPSHOT o parented by parent@1.1-SNAPSHOT o depends on a@1.1
    • parent@1.1-SNAPSHOT o代理的模块b@1.3-SNAPSHOT o依赖于a@1.1
    • module c@1.1-SNAPSHOT o parented by parent@1.1-SNAPSHOT o depends on a@1.2 o depends on b@1.1
    • 由parent@1.1-SNAPSHOT o代理的模块c@1.1-SNAPSHOT o依赖于a@1.2 o依赖于b@1.1
    • distribution a@1.2-SNAPSHOP
    • 分布a@1.2-SNAPSHOP
  • 由parent@1.1-SNAPSHOT模块b@1.3-SNAPSHOT o代理的bigsystem@1.2 parents -1.1- snapshot模块a@1.4-SNAPSHOT o依赖于由parent@1.1-SNAPSHOT o代理的a@1.1模块c@1.1-SNAPSHOT o依赖于a@1.2的分布a@1.2- snapshop

However the main differences are that:

然而,主要的区别是:

  • parent module does not include any versions of project artifacts
  • 父模块不包含项目构件的任何版本
  • individual modules fully declare their project dependencies and specify a version range, i.e. [1.0.0,1.1.0)
  • 单个模块完全声明其项目依赖项,并指定一个版本范围,即[1.0.0,1.1.0]
  • all modules start there version number cycles from .1, i.e 1.0.1-SNAPSHOT, this allows the version range to satisfied by initial snapshots (1.0.0-SNAPSHOT is earlier than 1.0.0 final, so not included).
  • 所有模块从。1开始,版本号循环。e 1.0.1-SNAPSHOT,这允许通过初始快照来满足版本范围(1.0.0- snapshot比1.0.0 final早,所以不包括在内)。
  • distribution pom (not initially shown in question) identifies the exact version to be deployed/included in a specific release.
  • 发行版pom(最初未显示)标识要部署/包含在特定版本中的确切版本。
  • delete all project -SNAPSHOTS from local maven repository when releasing so that ranges pickup releases only ( or use -Dmaven.repo.local=/tmp/sometemprepo for a fresh local repo)
  • 在发布时,从本地maven存储库中删除所有项目快照,以便只处理临时版本(或使用-Dmaven.repo)。local=/tmp/sometemprepo为一个新的本地回购)

This makes each module more standalone and gives us the freedom to release and deploy new versions of our project artifacts with minimal fuss.

这使每个模块更加独立,并使我们可以*地发布和部署项目构件的新版本。

#4


0  

They certainly seem like separate modules. What benefits are you gaining by smashing them together if they have different dependencies, even within the multi-module project?

它们看起来确实像是独立的模块。如果它们具有不同的依赖关系(甚至在多模块项目中),那么将它们合并到一起会获得什么好处呢?

#1


4  

I would recommend not making them modules, but make their POMs independent. That way you do not have to worry about trying to satisfy parent POM dependencies. Since they are released independently, they really should have independent project object models. Think of Apache Commons as a template.

我建议不要让它们成为模块,而是让它们的pom独立。这样,您就不必担心如何满足父POM依赖项。由于它们是独立发布的,所以它们实际上应该有独立的项目对象模型。可以将Apache Commons看作模板。

#2


2  

I think the problem with IDEA arises because you are using the root POM in your source structure to do two things that are usually mutually exclusive in Maven. You are first using the POM as a location to store common configuration information for unrelated (from a build perspective) Maven projects. Secondly you are using the POM as an aggregator for your build. You can do each of these without doing the other.

我认为问题出在IDEA上,因为您正在使用源结构中的根POM来做两件事,这两件事在Maven中通常是相互排斥的。您首先使用POM作为位置,为不相关(从构建角度)的Maven项目存储公共配置信息。其次,您正在使用POM作为构建的聚合器。你可以不做其他的就做这些。

Like Rob said, remove your module a, b, etc. projects from the modules section of your parent POM. Secondly, move your parent POM down into its own directory as it is really a sibling of the other modules with respect to your build and release process. The way you have it now, it is more of a parent/aggregator.

如Rob所说,从父POM的模块部分删除模块a、b等项目。其次,将父POM移动到它自己的目录中,因为它实际上是与构建和发布过程相关的其他模块的兄弟。现在的方法是,它更多的是一个父/聚合器。

The way you have it now also doesn't lend itself to tagging and releasing each module individually as a tag of your parent POM would likely needlessly include all of the module sub-folders.

现在的方法也不支持将每个模块单独作为父POM的标记进行标记和释放,可能不必要地包含所有模块子文件夹。

Your file structure would look like:

您的文件结构如下:

  • parent
    • pom.xml
    • pom.xml
  • 父母pom.xml
  • module a
    • pom.xml
    • pom.xml
  • 模块一个pom.xml
  • module X
    • pom.xml
    • pom.xml
  • 模块X pom.xml

As for the thing you are missing, dependencyManagement isn't really well suited to manage versions for intra-project dependencies. That is dependencies between modules within an aggregated build. It is more well suited for declaring global versions for external dependencies.

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

#3


2  

The final/working solution we ended up using was fairly similar to what we started with. The actual project structure remains the same:

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

  • bigsystem@1.2
    • parent-1.1-SNAPSHOT
    • 母公司- 1.1 -快照
    • module a@1.4-SNAPSHOT o parented by parent@1.1-SNAPSHOT
    • 模块a@1.4-SNAPSHOT o由parent@1.1-SNAPSHOT解析
    • module b@1.3-SNAPSHOT o parented by parent@1.1-SNAPSHOT o depends on a@1.1
    • parent@1.1-SNAPSHOT o代理的模块b@1.3-SNAPSHOT o依赖于a@1.1
    • module c@1.1-SNAPSHOT o parented by parent@1.1-SNAPSHOT o depends on a@1.2 o depends on b@1.1
    • 由parent@1.1-SNAPSHOT o代理的模块c@1.1-SNAPSHOT o依赖于a@1.2 o依赖于b@1.1
    • distribution a@1.2-SNAPSHOP
    • 分布a@1.2-SNAPSHOP
  • 由parent@1.1-SNAPSHOT模块b@1.3-SNAPSHOT o代理的bigsystem@1.2 parents -1.1- snapshot模块a@1.4-SNAPSHOT o依赖于由parent@1.1-SNAPSHOT o代理的a@1.1模块c@1.1-SNAPSHOT o依赖于a@1.2的分布a@1.2- snapshop

However the main differences are that:

然而,主要的区别是:

  • parent module does not include any versions of project artifacts
  • 父模块不包含项目构件的任何版本
  • individual modules fully declare their project dependencies and specify a version range, i.e. [1.0.0,1.1.0)
  • 单个模块完全声明其项目依赖项,并指定一个版本范围,即[1.0.0,1.1.0]
  • all modules start there version number cycles from .1, i.e 1.0.1-SNAPSHOT, this allows the version range to satisfied by initial snapshots (1.0.0-SNAPSHOT is earlier than 1.0.0 final, so not included).
  • 所有模块从。1开始,版本号循环。e 1.0.1-SNAPSHOT,这允许通过初始快照来满足版本范围(1.0.0- snapshot比1.0.0 final早,所以不包括在内)。
  • distribution pom (not initially shown in question) identifies the exact version to be deployed/included in a specific release.
  • 发行版pom(最初未显示)标识要部署/包含在特定版本中的确切版本。
  • delete all project -SNAPSHOTS from local maven repository when releasing so that ranges pickup releases only ( or use -Dmaven.repo.local=/tmp/sometemprepo for a fresh local repo)
  • 在发布时,从本地maven存储库中删除所有项目快照,以便只处理临时版本(或使用-Dmaven.repo)。local=/tmp/sometemprepo为一个新的本地回购)

This makes each module more standalone and gives us the freedom to release and deploy new versions of our project artifacts with minimal fuss.

这使每个模块更加独立,并使我们可以*地发布和部署项目构件的新版本。

#4


0  

They certainly seem like separate modules. What benefits are you gaining by smashing them together if they have different dependencies, even within the multi-module project?

它们看起来确实像是独立的模块。如果它们具有不同的依赖关系(甚至在多模块项目中),那么将它们合并到一起会获得什么好处呢?