简体   繁体   English

如何使用滑动释放循环正确设置多模块Maven项目

[英]How do I properly setup a multi-module Maven project with sliding release cycles

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 bigsystem@1.2
    • parent-1.1-SNAPSHOT 父 - 1.1-SNAPSHOT
    • module a@1.4-SNAPSHOT 模块a@1.4-SNAPSHOT
      • parented by parent@1.1-SNAPSHOT 由parent@1.1-SNAPSHOT提供资助
    • module b@1.3-SNAPSHOT 模块b@1.3-SNAPSHOT
      • parented by parent@1.1-SNAPSHOT 由parent@1.1-SNAPSHOT提供资助
      • depends on a@1.1 取决于a@1.1
    • module c@1.1-SNAPSHOT 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

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. 从构建角度来看,这很有效,每个模块都可以根据需要发布/更新,但是当尝试调试已经打开顶级pom的IntelliJ IDEA(版本8和9 EAP)下部署的应用程序时,IDEA决定,因为我们声明了依赖于a@1.2,只要我们进入其中一个类,就应该从a-1.2-sources.jar而不是项目中当前的a@1.4源打开它。 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. 这进一步混淆了这样一个事实,即进入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. 我最初尝试解决这个问题是在父pom的dependencyManagement部分中声明版本号,并让子模块继承该版本。 This worked to the degree of solving the IDEA debug issue as the dependencyManagement section can point everyone to the current -SNAPSHOT versions. 这有助于解决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. 不幸的是,由于必须在释放模块之前释放父pom,因此在执行maven释放时会出现问题,但由于父级可能引用多个开发中-SNAPSHOTS,因此无法释放它,我们最终会添加版本引用到模块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部分只有在我们同时发布所有bundle时才会真正起作用,无论它们是否发生了变化,但是因为我们只想在需要时管理每个子模块的版本,这个模型不会似乎很合适。

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. 我怀疑我遗漏了什么,并且dependencyManagement和版本范围的组合可能满足要求,尽管我还没有看到版本范围正常工作。

Is there a better way? 有没有更好的办法? A proper way? 一个正确的方法?

I would recommend not making them modules, but make their POMs independent. 我建议不要制作模块,但要让它们的POM独立。 That way you do not have to worry about trying to satisfy parent POM dependencies. 这样您就不必担心尝试满足父POM依赖项。 Since they are released independently, they really should have independent project object models. 由于它们是独立发布的,因此它们应该具有独立的项目对象模型。 Think of Apache Commons as a template. 将Apache Commons视为模板。

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. 我认为IDEA的问题出现是因为您在源结构中使用根POM来做两件通常在Maven中互斥的事情。 You are first using the POM as a location to store common configuration information for unrelated (from a build perspective) Maven projects. 您首先使用POM作为存储不相关(从构建角度)Maven项目的公共配置信息的位置。 Secondly you are using the POM as an aggregator for your build. 其次,您使用POM作为构建的聚合器。 You can do each of these without doing the other. 您可以在不执行其他操作的情况下执行这些操作。

Like Rob said, remove your module a, b, etc. projects from the modules section of your parent POM. 像Rob说的那样,从父POM的模块部分删除模块a,b等项目。 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. 其次,将您的父POM移动到它自己的目录中,因为它实际上是构建和发布过程中其他模块的兄弟。 The way you have it now, it is more of a parent/aggregator. 现在的方式,它更像是父/聚合器。

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
  • module a 模块
    • pom.xml 的pom.xml
  • module X 模块X.
    • pom.xml 的pom.xml

As for the thing you are missing, dependencyManagement isn't really well suited to manage versions for intra-project dependencies. 至于你缺少的东西,dependencyManagement不太适合管理项目内依赖项的版本。 That is dependencies between modules within an aggregated build. 这是聚合构建中的模块之间的依赖关系。 It is more well suited for declaring global versions for external dependencies. 它更适合声明外部依赖项的全局版本。

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 bigsystem@1.2
    • parent-1.1-SNAPSHOT 父 - 1.1-SNAPSHOT
    • 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 模块b@1.3-SNAPSHOT o由parent@1.1-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 模块c@1.1-SNAPSHOT o由parent@1.1-SNAPSHOT提供o取决于a@1.2 o取决于b@1.1
    • distribution a@1.2-SNAPSHOP 分发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, ie [1.0.0,1.1.0) 各个模块完全声明其项目依赖关系并指定版本范围,即[1.0.0,1.1.0)
  • all modules start there version number cycles from .1, ie 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开始版本号循环,即1.0.1-SNAPSHOT,这允许初始快照满足版本范围(1.0.0-SNAPSHOT最终早于1.0.0,因此不包括在内)。
  • 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存储库中删除所有项目-SNAPSHOTS,以便仅发布范围拾取(或者使用-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. 这使得每个模块更加独立,并且让我们可以自由地发布和部署项目工件的新版本,而不用担心。

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? 如果它们具有不同的依赖关系,即使在多模块项目中,通过将它们粉碎在一起会获得什么好处?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM