如何在Maven中更新子模块的版本?

Jos*_*nez 18 java module maven multi-module

如何更新子模块的版本?有很多类似这样的Stackoverflow问题,但是我找不到适合这种情况的问题...如果这是重复的话,我会很高兴.

考虑以下项目.

parent
  --mod1
  --mod2
Run Code Online (Sandbox Code Playgroud)

在开发阶段开始时,我需要将父模块和模块更新为相同的版本.如果父版本和模块的版本在整个版本中保持不变,那么我将只省略<version>模块中的标记并执行versions:set -DnewVersion=1.1.1以启动开发周期.但事实证明,模块不会以相同的版本结束循环.由于错误和修复只能实现那些带有错误的模块,因此会更新.例如,parent和mod2可能是版本1.1.1-RC1,但mod1可能是1.1.1-RC2.

因此,我需要:
1)<version>在模块中包含一个标签,以独立跟踪每个模块版本.

2)如果mod2需要mod1作为依赖项,我需要确保mod2引用最新版本的mod1.

这导致以下两个问题.

1)在循环开始时如何在一个maven命令中将父模块和模块设置为相同的版本?我试过了version:set -DnewVersion=1.1.1,但这只是更新了所有POM的父版本,而不是模块的版本.我也尝试了-N versions:update-child-modules,但我认为我使用它是错误的,因为它什么也没做,只是跳过了所有模块.

2)这有点难,与上面第2项相符.如何一步更新mod1的版本和mod2对mod1版本的引用?我知道如何分两步完成:

父母pom:

<properties>
    <!-- update this manually if mod1's version no longer matches parent -->
    <mod1.version>${project.version}</mod1.version>
</properties>
Run Code Online (Sandbox Code Playgroud)

mod2 pom:

    <dependency>
        <groupId>com.xxx</groupId>
        <artifactId>mod1</artifactId>
        <version>${mod1.version}</version>
    </dependency>
Run Code Online (Sandbox Code Playgroud)

当mod1碰到1.1.1-RC2时,我更新父POM和mod1 POM以反映这一点.这是两个步骤.无论如何把它变成一步?

我的例子虽小,但在现实生活中有许多模块可以节省大量时间,而且我很好奇.

Jua*_*uan 5

问题1)

管理应用程序生命周期和发布的最佳方法是使用发布插件.

您可能知道,Maven哲学是对配置的约定.Maven约定是在开发期间使用快照版本(以-SNAPSHOT结尾的版本)并仅为版本分配非快照版本.

假设您正在开发1.1.1版.在开发过程中,您只需使用1.1.1-SNAPSHOT.Maven将负责快照的更新.如果使用工件存储库,则可以使用-U确保始终具有最新版本的快照.

当发布准备就绪时,发布插件会生成并部署1.1.1版并使用新的开发版本更新POM,例如1.1.2-SNAPSHOT.

关于多模块项目,有两种情况:模块是相关的但是独立的(例如几个Web应用程序),或者它们是单个大型应用程序或库的模块,它们共享版本.你似乎对后者感兴趣.

在这种情况下,最好的方法是继承相同的父模块(也可能是根模块),包括其版本.您引用父组:artifact:version并且您没有为子项指定版本.通常你也会继承组,所以你的孩子pom可以看起来像:

<parent>
   <groupId>com.mycompany.myproject</groupId>
   <artifactId>myproject-parent</artifactId>
   <version>1.1.1-SNAPSHOT</version>
   <relativePath>../myproject-parent</relativePath>
</parent>
<artifactId>myproject-module1</artifactId>
Run Code Online (Sandbox Code Playgroud)

现在你只需要在发布插件的帮助下照顾孩子指向正确的父版本.

为了帮助它了解孩子,你应该通过包含模块部分使你的父pom成为根pom,如下所示.

问题2)我通常在父类中声明属性,其中包含可能被引用的所有工件的所有版本.如果多个模块共享版本,则只需要一个属性.父母可以看起来像:

<groupId>com.mycompany.myproject</groupId>
<artifactId>myproject-parent</artifactId>
<version>1.1.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
   <myproject.version>1.1.1-SNAPSHOT</myproject.version>
</properties>

.......

<modules>
   <module>../myproject-module1</module>
   ...
</modules>
Run Code Online (Sandbox Code Playgroud)

儿童可以参考其他模块

<version>${myproject.version}</version>
Run Code Online (Sandbox Code Playgroud)

使用LATEST声明依赖项是一种非常糟糕的做法.假设你为版本1.1.1执行此操作.现在您正在使用版本1.1.2-SNAPSHOT,并且您可能在本地存储库中安装了此版本的工件.

现在说出于某种原因你需要重建版本1.1.1,例如由于生产中的错误.您的构建将使用新版本.如果你很幸运,这将破坏构建.如果你运气不好,它甚至可能不会被注意到生产.

最后但并非最不重要的是,有些人喜欢使用属性值来声明子版本.强烈建议不要这样做,并且会被maven报告为警告.我个人从来没有这样做过.原因还与构建的可重现性以及maven假定发布版本永远不会改变这一事实有关.让模块版本可外部调整并不是一个好主意.

编辑:

模块版本未对齐时的情况.

实际上两种情况都可以混合使用.你可以拥有,例如:

---的Component1

--- COMPONENT2

--- Component3

------ Comp3Module1

------ Como3Module2

------ Comp3Module3

其中父组件和三组件版本不同,组件3的三个模块共享其相同的版本,如前所述.

问题1)在这种情况下,每个模块都有不同的版本.如前所述,使用属性指定模块版本是一个糟糕的问题,这是我只能建议逐字指定版本的原因.如前所述,要管理版本控制,最好的方法是使用发布插件,并将其与版本控制系统(如SVN)集成.其他答案提供了如何使用它的详细信息,因此除非有要求,否则我不会进一步详细说明.

问题2)推荐的方法与共享相同版本的情况相同,只是需要多个属性.父母可以看起来像:

<properties>
   <myproject.group>com.mycompany.myproject</myproject.group>
   <component1.version>1.1.1-RC1</component1.version>
   <component2.version>1.1.1-RC2</component2.version>
   <component3.version>2.0.0</component3.version>
<properties>
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用依赖关系管理来集中父级中的版本管理.

例如,在父母pom中,

<dependencyManagement>
   <dependencies>
      <dependency>
         <groupId>${myproject.group}</groupId>
         <artifactId>component1</artifactId>
         <version>${component1.version}</version>
      </dependency>
      <dependency>
        <groupId>${myproject.group}</groupId>
         <artifactId>component2</artifactId>
         <version>${component2.version}</version>
         <type>war</type>
      </dependency>
      <dependency>
         <groupId>${myproject.group}</groupId>
         <artifactId>comp3module1</artifactId>
         <version>${component3.version}</version>
        <type>ejb</type>
      </dependency>
      <dependency>
         <groupId>${myproject.group}</groupId>
         <artifactId>comp3module1</artifactId>
         <version>${component3.version}</version>
        <type>ejb-client</type>
      </dependency>
      <dependency>
         <groupId>${myproject.group}</groupId>
         <artifactId>comp3module2</artifactId>
         <version>${component3.version}</version>
        <type>war</version>
      </dependency>
   </dependencies>
</dependencyManagement>
Run Code Online (Sandbox Code Playgroud)

现在,要从任何其他模块引用任何模块,它就像:

<dependency>
   <groupId>${myproject.group}</groupId>
   <artifactId>component1</artifactId>
</dependency>
<dependency>
   <groupId>${myproject.group}</groupId>
   <artifactId>comp3module1</artifactId>
   <type>ejb-client</type>
</dependency>
Run Code Online (Sandbox Code Playgroud)

从父级自动管理版本.您不需要在子项依赖项中维护它们,这些依赖项也变得不那么冗长.