Java 如何将多模块项目移动到maven

Java 如何将多模块项目移动到maven,java,maven,Java,Maven,我们正试图将几个多模块应用程序迁移到maven,但遇到了一些问题 每个模块都独立存储在cvs中。我们有每个应用程序的清单文件,其中列出了该应用程序所需的模块(以及可选的版本)。并非所有模块都是maven形式 因此,“客户关怀”应用程序具有以下清单: <manifest> <module id="MY_api"/> <module id="custcare_webapp"/> </manifest> 类似地,应用程序“核心批处理”的清单

我们正试图将几个多模块应用程序迁移到maven,但遇到了一些问题

每个模块都独立存储在cvs中。我们有每个应用程序的清单文件,其中列出了该应用程序所需的模块(以及可选的版本)。并非所有模块都是maven形式

因此,“客户关怀”应用程序具有以下清单:

 <manifest>
 <module id="MY_api"/>
 <module id="custcare_webapp"/>
 </manifest>

类似地,应用程序“核心批处理”的清单如下所示:

 <manifest>
 <module id="MY_api"/>
 <module id="core"/>
 <module id="batch"/><!--NB this is a non-maven module -->
 </manifest>

我已经开始“mavenising”我们的代码,因此MY_api项目有一个定义了依赖项的pom.xml,包括另一个内部代码模块“central_config”上的依赖项。我已指定版本发布

问题 这一切都很好,直到我需要创建一个冻结清单。我可以为每个模块指定一个版本:

 <manifest>
 <module id="MY_api" version="0.123.0"/>
 <module id="core" version="0.456.0"/>
 <module id="batch" version="0.789.0"/><!--NB this is a non-maven module -->
 </manifest>

但是这个构建是不可复制的,因为MY_api中的“centralconfig”依赖项的版本是“RELEASE”。因此,如果有人发布了新版本的“centralconfig”,那么下次我们构建这个冻结清单时,情况就不同了

那么我们为什么不使用像central config这样的依赖项的硬编码版本呢?因为这样,每次有人将centralconfig更新到新版本时,我们都必须更新10或20个pom文件。所有依赖于中央配置的东西,以及所有依赖于中央配置的东西,都需要更新pom.xml并重新发布。这不仅是大量的工作,我不知道如何以编程方式可靠地识别每个声明依赖于中央配置的模块

可能的解决方案? 我能否在一个地方定义“centralconfig.version”,然后在所有模块中引用它?如果是,我应该在哪里做?我不太了解家长POM,但我觉得他们可能会提供一个解决方案

更新 看来,使用父pom是一种可行的方法。但根据这个问题:,maven child项目不可能有多个家长

那么,MY_api模块如何成为custcare_webapp和core_batch的子模块呢

更新
我的结论是maven不符合我的要求,我们又回到了使用ant和CVS的12年自主开发的解决方案构建中。

我认为您确实需要一个父POM。这是一个顶级的
pom.xml
,它只是一个pom模块,没有关联的代码。通过在此
pom.xml
上运行
mvn
命令,可以构建整个项目

POM应该位于所有模块目录之上的目录中。也就是说,您的每个模块都将位于包含master
pom.xml

此POM的
类型将为
POM
。这意味着它是一个只有POM的项目,没有自己的代码。它还将有一个
标记,其中包含每个模块的一个
元素。这样,当您运行
mvn
命令时,Maven也将知道如何构建这些模块。一个像样的父母POM

使用标准的
标记在此POM中设置所有依赖项。模块POMs将继承它们。(更新:参见下面的注释,绝对值得探索父POM的
标记。)


最后,每个模块POM都应该引用主POM。这样,如果您在一个模块目录中运行
mvn
(即,您只是在构建一个模块),它将查找父模块的依赖项。您可以使用一个
标记来执行此操作,该标记将保存

另一个通常比管理版本的父结构更好的选项是导入依赖项

为了说明这是如何工作的,您创建了一个仅包含pom的项目,该pom指定了要用于所有模块的版本:

<project>
 <modelVersion>4.0.0</modelVersion>
 <groupId>test</groupId>
 <artifactId>module-versions</artifactId>
 <packaging>pom</packaging>
 <version>1.0</version>
 <dependencyManagement>
   <dependencies>
     <dependency>
       <groupId>test</groupId>
       <artifactId>a</artifactId>
       <version>1.1</version>
     </dependency>
     <dependency>
       <groupId>foo</groupId>
       <artifactId>bar</artifactId>
       <version>2</version>
     </dependency>
   </dependencies>
 </dependencyManagement>
</project>

4.0.0
测试
模块版本
聚甲醛
1
测试
A.
1.1
福
酒吧
2.
然后,在所有需要依赖于任何硬编码版本的项目中,以以下方式导入此项目:

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>test</groupId>
        <artifactId>module-versions</artifactId>
        <version>1.0</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

测试
模块版本
1
聚甲醛
进口
通过这种方式,只要在发布任何依赖项的新版本时更改
模块版本
项目即可

通过这种方式,您可以拥有多个“模块版本”-项目来稍微拆分一些内容


当然,您仍然存在一个问题,即希望使用新版本的所有项目也必须依次发布,但这是在Maven中使用已发布依赖项的成本。

我在Maven中使用多模块项目时总是遇到问题。最后,我转到了格拉德尔。事实上我有一篇关于SO([)的帖子这可能有助于你开始使用该工具进行多模块项目。其他答案也很有帮助。不要试图吹响我的喇叭或Gradle的喇叭,只是希望这可能会有所帮助。如果Gradle不是一个选项,请理解。@sparc_spread,谢谢你的提示。我不反对使用Gradle,但有一点学习曲线,而且已经投入了很多为了让maven工作,我花费了大量的时间和精力,如果抛开这一切,从gradle开始,那将是一件很遗憾的事情。我觉得maven有一个解决方案,但这是遥不可及的!没问题-大家都同意。希望你能很快得到一些答案。老实说,我不太理解问题的描述。从我所能收集到的信息来看,我在我看来,使用适当的maven多模块设置是必要的,这确实需要使用父pom来进行dependencyManagement。但我想我只是没有抓住要点。@Gimby你能详细说明一下你的想法吗?我不明白的是:如果我在父pom中为这两个pom指定一个版本的MY_api客户关怀和核心批次,如何处理