与大型项目的版本控制和避免包含表达式的版本相关的 Maven 建议

发布于 2024-12-28 05:01:36 字数 5799 浏览 6 评论 0原文

我正在考虑重组一个大型 Maven 项目...

我们当前结构的基本概述:

build [MVN plugins, third party dependency management]:5.1
   NRW Utils:6.0.0.0-beta12-SNAPSHOT
      server-utils:6.0.0.0-beta12-SNAPSHOT
      ... 
   CMW Root:6.0.0.0-beta12-SNAPSHOT
      cmw-webapp:6.0.0.0-beta12-SNAPSHOT
      cmw-core [dependencies on NRW Utils]:6.0.0.0-beta12-SNAPSHOT
      ...
   NRW Root :6.0.0.0-beta12-SNAPSHOT
      nrw-webapp [depends on NRW Utils & CMW Root modules]:6.0.0.0-beta12-SNAPSHOT
      ...

更改原因:

每个集体模块的大小(即 NRW Utils) 、CMW 根和 NRW 根)变得越来越大,构建过程开始花费难以忍受的时间(有时约为 4 小时)。

新计划

build [MVN plugins, third party dependency management]:5.1
   NRW Utils:6.0.0.0-NU-beta4-SNAPSHOT
      server-utils:6.0.0.0-NU-beta4-SNAPSHOT
      ... 
   CMW Root:6.0.0.0-CMW-beta12-SNAPSHOT
      cmw-webapp:6.0.0.0-CMW-beta12-SNAPSHOT
      cmw-core [dependencies on NRW Utils]:6.0.0.0-CMW-beta12-SNAPSHOT
      ...
   NRW Root :6.0.0.0-NRW-beta9-SNAPSHOT
      nrw-webapp [depends on NRW Utils & CMW Root modules]:6.0.0.0-NRW-beta9-SNAPSHOT
      ...  

我们开始在版本中引入“按键”来区分不同的“集合模块”,从而可以轻松地执行逐步发布。此外,我们的实用程序模块更加稳定,因此我们可能不需要那么多的测试版 - 现在对于保持测试版数字同步没有任何限制。

还值得注意的是,实际上有 5 个不同的“集体模块”(不仅仅是 3 个),所有模块都使用不同的版本(通过唯一的键来区分)构建,这就是为什么我认为最好有一个集中的地方版本,而不是 5 个不同 POM 中的重复属性。

现在的问题在于在不同版本的不同“集体模块”中定义模块的依赖关系时,POM 文件的内容。

建议的依赖版本管理解决方案:

build [MVN plugins, third party dependency management]:5.1
   nrw-version-management:6.0.0.0-beta-SNAPSHOT
      [contains properties defining latest versions of each collective module]   
      NRW Utils:6.0.0.0-NU-beta4-SNAPSHOT
         server-utils:6.0.0.0-NU-beta4-SNAPSHOT
         ... 
      CMW Root:6.0.0.0-CMW-beta12-SNAPSHOT
         cmw-webapp:6.0.0.0-CMW-beta12-SNAPSHOT
         cmw-core [dependencies on NRW Utils]:6.0.0.0-CMW-beta12-SNAPSHOT
         ...
      NRW Root :6.0.0.0-NRW-beta9-SNAPSHOT
         nrw-webapp [depends on NRW Utils & CMW Root modules]:6.0.0.0-NRW-beta9-SNAPSHOT
         ... 

nrw-version-management (pom.xml):

...
<parent>
    <groupId>com.project</groupId>
    <artifactId>build</artifactId>
    <version>5.1</version>
</parent>
<groupId>com.project</groupId>
<artifactId>nrw-versions-manager</artifactId>
<version>6.0.0.0-beta-SNAPSHOT</version>
<name>Version Maven Properties</name>
<description>A centralised place for all module property versions</description>
<packaging>pom</packaging>
<properties>
    <nrw.utilities.version>6.0.0.0-NU-beta4-SNAPSHOT</nrw.utilities.version>
    <nrw.cmw.version>6.0.0.0-CMW-beta12-SNAPSHOT</nrw.cmw.version>
    <nrw.version>6.0.0.0-NRW-beta9-SNAPSHOT</nrw.version>
</properties>
...

CMW Root (pom.xml):

...
<parent>
    <groupId>com.project</groupId>
    <artifactId>nrw-versions-manager</artifactId>
    <version>${nrw.core.version}</version>
    ...
</parent>
<groupId>com.project</groupId>
<artifactId>CMW-root</artifactId>
<version>6.0.0.0-CMW-beta12-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencyManagement>
    <dependencies>
        ...
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>server-utils</artifactId>
            <version>${nrw.utilities.version}</version>
        </dependency>
        ...
</dependencyManagement>
<profiles>
    <profile>
        <id>all</id>
        <modules>
            <module>cmw-webapp</module>
            <module>cmw-core</module>
            ...
        </modules>
    </profile>
    ...
</profiles>
...

注意然后,通过命令行参数(或默认属性值)将属性 ${nrw.core.version} 设置为 6.3.0.0-beta-SNAPSHOT 以进行快照构建。

可能的发布过程(对于 6.0.0.0):

  1. 构建 5.1 构建模块(如果尚未构建)
  2. 构建 nrw-version-management 6.0.0.0(以避免快照依赖性 - 但尚未更改任何属性)
  3. 构建北威州公用事业 6.0.0.0-NU cmd 参数:-Dnrw.core.version=6.0.0.0
  4. 构建 CMW 根 6.0.0.0-CMW cmd 参数:-Dnrw.core.version=6.0.0.0 -Dnrw.utilities.version=6.0.0.0-NU
  5. 构建 NRW 根 6.0.0.0-NRW cmd args:-Dnrw.core.version=6.0.0.0 -Dnrw.utilities.version=6.0.0.0-NU -Dnrw.cmw.version=6.0.0.0-CMW
  6. 为存储库重新构建 nrw-version-management 6.0.0.0 cmd 参数:-Dnrw.core.version=6.0.0.0 -Dnrw.utilities.version=6.0.0.0-NU -Dnrw.cmw.version=6.0.0.0-CMW
  7. 构建 nrw-版本-管理 6.1.0.0-beta-SNAPSHOT使用新的开发版本并更新 POM 文件

问题:

构建过程似乎很冗长,尤其是相关到 nrw 版本管理模块。 另外,我开始看到这个警告:

'version'包含一个表达式,但应该是一个常量

,经过一些调查,我现在明白在设置版本时(指定父 POM 时)不建议使用表达式:

问题:

  • 我可以忽略吗这个警告?一些帖子开始表明使用属性指定父 POM 版本可能是可以接受的。
  • 这种一般方法是传统的吗?还是有缺陷?
  • 是否有更好的解决方案来解决这个不断增长的项目的重组问题?

提前致谢。

I'm looking at restructuring a large Maven project...

A basic overview of our current structure:

build [MVN plugins, third party dependency management]:5.1
   NRW Utils:6.0.0.0-beta12-SNAPSHOT
      server-utils:6.0.0.0-beta12-SNAPSHOT
      ... 
   CMW Root:6.0.0.0-beta12-SNAPSHOT
      cmw-webapp:6.0.0.0-beta12-SNAPSHOT
      cmw-core [dependencies on NRW Utils]:6.0.0.0-beta12-SNAPSHOT
      ...
   NRW Root :6.0.0.0-beta12-SNAPSHOT
      nrw-webapp [depends on NRW Utils & CMW Root modules]:6.0.0.0-beta12-SNAPSHOT
      ...

The reason for change:

The size of each collective module (i.e. NRW Utils, CMW Root and NRW Root) is getting larger and the build process is beginning to take an unbearable amount of time (~4hrs sometimes).

The new plan:

build [MVN plugins, third party dependency management]:5.1
   NRW Utils:6.0.0.0-NU-beta4-SNAPSHOT
      server-utils:6.0.0.0-NU-beta4-SNAPSHOT
      ... 
   CMW Root:6.0.0.0-CMW-beta12-SNAPSHOT
      cmw-webapp:6.0.0.0-CMW-beta12-SNAPSHOT
      cmw-core [dependencies on NRW Utils]:6.0.0.0-CMW-beta12-SNAPSHOT
      ...
   NRW Root :6.0.0.0-NRW-beta9-SNAPSHOT
      nrw-webapp [depends on NRW Utils & CMW Root modules]:6.0.0.0-NRW-beta9-SNAPSHOT
      ...  

We have started introducing 'keys' in the version to distinguish between different 'collective modules' and hence can easily perform stepped releases. In addition, our utility modules are far more stable so we may not require nearly as many beta releases - there is now no restriction on keeping beta numbers in sync.

It is also worth noting that there are in fact 5 different 'collective modules' (not just 3) all to be built with different versions (distinguished by unique keys) which is why I thought it'd be nice to have a centralised place for versions, as opposed to duplicate properties in 5 different POMs.

The problem now lies in the contents of POM files when defining dependencies on modules in a different 'collective module' of a different version.

The proposed solution to dependency version management:

build [MVN plugins, third party dependency management]:5.1
   nrw-version-management:6.0.0.0-beta-SNAPSHOT
      [contains properties defining latest versions of each collective module]   
      NRW Utils:6.0.0.0-NU-beta4-SNAPSHOT
         server-utils:6.0.0.0-NU-beta4-SNAPSHOT
         ... 
      CMW Root:6.0.0.0-CMW-beta12-SNAPSHOT
         cmw-webapp:6.0.0.0-CMW-beta12-SNAPSHOT
         cmw-core [dependencies on NRW Utils]:6.0.0.0-CMW-beta12-SNAPSHOT
         ...
      NRW Root :6.0.0.0-NRW-beta9-SNAPSHOT
         nrw-webapp [depends on NRW Utils & CMW Root modules]:6.0.0.0-NRW-beta9-SNAPSHOT
         ... 

nrw-version-management (pom.xml):

...
<parent>
    <groupId>com.project</groupId>
    <artifactId>build</artifactId>
    <version>5.1</version>
</parent>
<groupId>com.project</groupId>
<artifactId>nrw-versions-manager</artifactId>
<version>6.0.0.0-beta-SNAPSHOT</version>
<name>Version Maven Properties</name>
<description>A centralised place for all module property versions</description>
<packaging>pom</packaging>
<properties>
    <nrw.utilities.version>6.0.0.0-NU-beta4-SNAPSHOT</nrw.utilities.version>
    <nrw.cmw.version>6.0.0.0-CMW-beta12-SNAPSHOT</nrw.cmw.version>
    <nrw.version>6.0.0.0-NRW-beta9-SNAPSHOT</nrw.version>
</properties>
...

CMW Root (pom.xml):

...
<parent>
    <groupId>com.project</groupId>
    <artifactId>nrw-versions-manager</artifactId>
    <version>${nrw.core.version}</version>
    ...
</parent>
<groupId>com.project</groupId>
<artifactId>CMW-root</artifactId>
<version>6.0.0.0-CMW-beta12-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencyManagement>
    <dependencies>
        ...
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>server-utils</artifactId>
            <version>${nrw.utilities.version}</version>
        </dependency>
        ...
</dependencyManagement>
<profiles>
    <profile>
        <id>all</id>
        <modules>
            <module>cmw-webapp</module>
            <module>cmw-core</module>
            ...
        </modules>
    </profile>
    ...
</profiles>
...

N.B. the property ${nrw.core.version} would then be set to 6.3.0.0-beta-SNAPSHOT for a snapshot build via command line arguments (or a default property value).

A possible release process (for 6.0.0.0):

  1. Build the 5.1 build module if not already built
  2. Build nrw-version-management 6.0.0.0 (to avoid snapshot dependencies - however no properties are changed yet)
  3. Build NRW Utils 6.0.0.0-NU
    cmd args: -Dnrw.core.version=6.0.0.0
  4. Build CMW Root 6.0.0.0-CMW
    cmd args: -Dnrw.core.version=6.0.0.0 -Dnrw.utilities.version=6.0.0.0-NU
  5. Build NRW Root 6.0.0.0-NRW
    cmd args: -Dnrw.core.version=6.0.0.0 -Dnrw.utilities.version=6.0.0.0-NU -Dnrw.cmw.version=6.0.0.0-CMW
  6. Re-build nrw-version-management 6.0.0.0 for repository
    cmd args: -Dnrw.core.version=6.0.0.0 -Dnrw.utilities.version=6.0.0.0-NU -Dnrw.cmw.version=6.0.0.0-CMW
  7. Build nrw-version-management 6.1.0.0-beta-SNAPSHOT with new dev versions and update POM file

The problem:

The build process seems long-winded, especially related to the nrw-version-management module.
Also, I started seeing this warning:

'version' contains an expression but should be a constant

And having done some investigating I now understand expressions are not recommended when setting versions (when specifying a parent POM):

The questions:

  • Can I just ignore this warning? Some posts are starting suggest that it might just be acceptable to specify parent POM versions using properties.
  • Is this general approach conventional? Or flawed?
  • Are there better solutions to address the re-structuring of this growing project?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

山人契 2025-01-04 05:01:36

所有子模块都采用单一版本的好处是简单,这一好处不应被低估。

您确实应该多次问自己是否真的想依赖同一层次结构中不同版本的模块。正如您所指出的,发布变得很麻烦。

通过使用单一版本以标准化方式处理关系并在成功构建后部署到本地存储库,您应该能够按照预期的方式享受依赖项管理。

如果您重组项目以使其遵守发布插件的约定,那么发布就会变得轻而易举。

The benefits of having one single version for all sub modules is simplicity, a benefit that shouldn't be under estimated.

You should indeed ask yourself several times if you really want to depend on different versions of modules in the same hierarchy. As you pointed out release becomes cumbersome.

By handling relationships in a standardized way with single version and deploying to your local repo after successfull builds you should be able to enjoy dependency management the way it was intended.

If you restructure your project so that it adheres to the conventions of the release plugin, release becomes a breeze.

铜锣湾横着走 2025-01-04 05:01:36

正如 nico_ekito 在其中一条评论中所述,在我看来,您现在正陷入“依赖管理噩梦”。根据您的场景......管理子模块的不同版本(以及不同的代码稳定性)的事实难道不是这些子模块不再是大项目的一部分的症状吗?

我的意思是,作为人类,我们可以清楚地声明这些模块是全局的一部分,是解决问题的整个方法的一部分。当您发现实用程序类在大局范围之外没有用处时,这是很常见的。但是,从 Maven 的角度来看,我认为您实际上是在处理不同的项目,而不是一个大项目的模块。

因此,也许值得将不同结构的代码库分开,只简单地从实际需要它的模块中引用实用程序 jar,并使用稳定的构建而不是“该依赖项的最后版本”。如果使用稳定的构建,这是不可行的,因为即使该依赖项的代码非常稳定,但它与其他模块的代码同时不断变化,那么 Maven 为您提供的解决方案就是使用 SNAPSHOTS。

我认为将代码库分解为单独的项目时您会发现一些好处:

  • 这样 Maven 就不会在不需要时触发这些实用程序模块中的构建。
  • 如果能找到一种仅使用依赖项的稳定版本的方法,您将避免很多麻烦。
  • 您还可以打破团队,让那些只使用实用程序 jar 的团队在使用该依赖项的团队的“需求不足的基础上”这样做。
  • 如果这些实用程序足够抽象或可重用,您可能有一天会发现另一个项目也可以使用它们,而无需引用较大项目中的子模块。

互联网上有很多关于这种方式的讨论 Maven 处理依赖项(和其他事情),很多人抱怨你面临的同样问题。在我看来,Maven 是一个很棒的工具,旨在为我们在启动新项目时节省大量时间,但有时它可能会有点麻烦。我开始考虑其他工具,例如 Gradle 但现在更改构建工具可能是更糟糕的事情。只要考虑一下打破代码库的想法,有时我们只需一点“项目管理”(或在本例中为“项目组合管理”)就可以解决“软件问题”。

As nico_ekito stated in one of the comments, in my own opinion, you are falling right now into the "dependency management nightmare". As per your scenario... isn't the fact of managing different versions for submodules (as well as different code stability) a symptom of that those submodules are no longer part of the big project?

I mean, we, as humans, can clearly state that those modules are part of the big picture, the whole approach for solving a problem. That is quite common when you find that your utility classes have no use outside the scope of that big picture. But, from the Maven point of view I think that you are actually dealing with different projects rather than modules of a big one.

So, maybe it's worth to separate the codebases in different structures and just simply reference the utility jars from the modules that actually require it and just use stable builds instead of "last version of that dependency". If working with stable builds it's not feasible because, even though the code for that dependencies is quite stable, it keeps changing at the same time that the code from the other modules, then the solution that Maven gives you is using SNAPSHOTS.

I think you will find some benefits when breaking the code base into separate projects:

  • That way Maven won't trigger a build in those utility modules when it's not needed.
  • If can find a way of just using stable releases for the dependencies you will avoid a lot of hassle.
  • You can also break the team and make the ones to work with just the utility jars do so on a "under-demand basis" from the team that consumes that dependencies.
  • If those utilities are abstract or reusable enough you may find someday another project that may consume them as well without the need of referencing a submodule from a larger project.

There is a lot of discussion in the Internet about the way Maven handles dependencies (and other things) and a lot of people complain about the same problems you are facing. In my own opinion, Maven is a great tool, designed to save us a lot of time when starting new projects but sometimes it can be a bit cumbersome. I started to take a look a other tools like Gradle but now changing the build tool may be worse thing to do. Just giving a though to the idea of breaking the code base, sometimes we can solve a "software problem" just with a bit of "project management" (or "portfolio mangement" in this case).

顾冷 2025-01-04 05:01:36

我认为在这个阶段在整个项目中坚持使用单一版本是不可行的,因为构建过程现在需要很长时间(前几天它在 7 小时后失败了!!)。

但是,下面的两个链接并没有完全回答我的问题,但已经解决了:

I don't feel that sticking to a single version across the whole project is viable at this stage, given that the build process takes so long right now (the other day it failed after 7hrs!!).

However, the two links below don't completely answer my question but are getting there:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文