【问题标题】:How to manage multi app project in maven?如何在 Maven 中管理多应用程序项目?
【发布时间】:2019-10-10 08:10:48
【问题描述】:

我目前正在尝试将一个多应用项目从 Ant 迁移到 Maven
目前该项目由多个包组成,创建了某种依赖树,没有循环依赖。这棵树的叶子是“应用程序”包,包含Main。中间节点是“库”包,由其他库“包”或“应用程序”包使用。
允许节点“一起生长”为单个节点或叶子。 我发现,这些包可能应该被分组到 Maven 模块中,我现在有一个类似于这样的结构:

root
    - lib1
    - lib1A (depends on lib1)
    - lib1B (depends on lib1)
    - app1A (depends on lib1A)
    - lib2  (depends on lib1B)
    - lib2A (depends on lib2)
    - lib2B (depends on lib2)
    - app2  (depends on lib2A and lib2B)
    - lib3  (depends on lib2A and lib2B)
    - app3A (depends on lib3)
    - app3B (depends on lib3)

基本上,一个库和一个应用程序可以依赖于一个或多个其他库。
现在我希望能够自己构建每个应用程序并为其创建一个可执行的 jar。
我现在尝试这样做的方式如下:

  • 配置每个apppom.xml 以使用maven-assembly-plugin 创建可执行jar。
  • 为特定应用构建所需的每个模块。
  • 构建应用模块,生成可执行的 jar。

所以app2 的构建将构建lib1lib1Alib1Blib2lib2Alib2B,最后是app2
但是,为了自动化构建,我需要为每个应用程序创建一个构建脚本,它负责构建所有需要的依赖项,而 maven 应该已经自己完成了。
另外,如果我想一次构建多个应用程序,我需要多次构建所有库,或者自己跟踪已经构建的模块。
由于我是 maven 新手,我不确定这是否是管理此类多应用项目的正确方法。
所以我想就如何正确管理这个用例征求一些建议。

编辑:
澄清我希望能够做什么:

  • 使用其依赖项构建单个应用程序, 无需构建所有应用程序(在父 pom 上运行 maven)。
  • 使用它们的依赖项构建多个应用程序(不是全部),而无需多次构建依赖项。

【问题讨论】:

  • 只构建所有应用程序(而忘记那些您不需要的应用程序)有什么害处?
  • @JFMeier 项目很大,构建所有应用程序需要很长时间。如果我只对app1A 进行更改,则没有理由构建除lib1lib1Aapp1A 之外的任何东西。构建时间会大大缩短。
  • 可以使用-am-pl 选项来使用您需要的所有库构建项目的一部分,但是您很容易进入版本地狱,因为您的模块启动有不同的版本号,其中的一部分有时会增加。
  • @JFMeier “版本地狱”是什么意思?就我而言,所有模块总是需要使用所有库的最新版本。
  • 假设你有一个简单的结构,比如 app1、app2 和 lib。 app1 和 app2 都依赖于 lib。一开始,所有人的 POM 中都有 1.0.0-SNAPSHOT 版本。现在,您从 app1 及其依赖库构建一个版本。您将它们构建为版本1.0.0。之后,您(或 maven 发布插件)将两个模块 POM 中的版本更改为 1.0.1-SNAPSHOT。现在您还需要更新 app2 的 POM 以引用 lib 的 1.0.1-SNAPSHOT。不过,app2 的 POM 中的版本是1.0.0-SNAPSHOT。因此,您的模块版本开始出现分歧。

标签: java maven module


【解决方案1】:

如果您在各自的 POM 中定义依赖关系并构建整个项目(在根级别),那么 Maven 会自动对模块进行拓扑排序,这意味着构建每个模块一次,并且一切都以正确的顺序完成。

【讨论】:

  • 是的,但我认为值得明确指出“root”需要是 Maven 父 pom,将子代定义为模块。我不确定问题中提议的结构中是否已经存在这种情况。
  • @JFMeier 是正确的,但我希望能够只构建一个应用程序。构建所有应用程序需要更长的时间,而且并不总是必要的。因此,我正在寻找一种无需构建所有应用程序即可构建单个应用程序(包括它们的模块)的方法。我编辑了问题以澄清这一点。
  • 如果这是要求,那么您必须将每个应用程序提取到单独的存储库中,以便您可以单独构建并将库也提取到单独的存储库中......除此之外,您为什么需要构建单个应用程序?
  • @khmarbaise 正如我所说,这是一个多应用程序项目,其中每个应用程序都独立于其他应用程序。他们只共享一些通用代码。我不知道你是否有一些Android开发经验,但是你有所谓的app-moduleslib-modules,其中app-modules用于创建APK,而lib-modules用于共享代码。我想在 Maven 中实现类似的东西。
【解决方案2】:

我现在正在使用一个父项目,它定义了 maven 版本、通用依赖项和通用插件配置。
父项目还在module-tags 中定义了它的子模块。
每个子模块都引用此父项目并使用相同的版本。
为了构建应用程序,我在父项目中运行 maven,使用 -pl-am 标志,如 this comment 中所述。
-pl 标志告诉 maven 只构建列出的模块,而不是构建整个项目。
-am 标志告诉 maven 也构建所需的依赖项。
示例:
给定以下结构:

parent
---- lib1
---- lib1A (depends on lib1)
---- lib1B (depends on lib1)
---- lib2 (depends on lib1B)
---- lib2A (depends on lib2)
---- lib2B (depends on lib2)
---- app1A (depends on lib1A)
---- app2A (depends on lib2A)
---- app2B (depends on lib2B)

执行mvn clean install -pl app1A,app2A -am 将构建除app2Blib2B 之外的所有模块。
此外,app1Aapp2A 使用的模块lib1 只会构建一次。

通常,您希望独立地对每个模块进行版本控制,但在我们的例子中,这会带来巨大的工作量,因为我们有很多模块构建在彼此之上。 “最低”模块(示例中为lib1)中的微小变化会导致几乎每个模块都发生变化。
所以在这种情况下,我们需要增加每个版本号并更新所有模块中所有引用的依赖项。
相反,我们决定始终重建所有依赖项,从而生成始终保持最新的 Jar。所以我们只在父项目中管理maven版本。

【讨论】:

    【解决方案3】:

    我认为使用 maven 多模块,您只需导航到要构建的模块,然后从那里运行 maven 命令。 Maven 将自动构建具有相关依赖关系的模块,而无需构建不必要的模块。

    已编辑:原始答案不正确,经过一些测试后,我发现以下内容应该会有所帮助: Maven Modules + Building a Single Specific Module 从父级构建特定模块时,您只需要添加 -pl 和 -am 标志。

    【讨论】:

    • 这似乎不是真的。如果我从app1 运行mvn clean package,而不首先构建lib1,我会收到错误Could not find artifact my.test:lib1:jar:0.0.1-SNAPSHOT
    • 我再次检查了一遍,看起来你是对的(我之前手动使用 mvn clean install,然后我可以在单个模块中运行 'mvn clean package' 然后它总是会成功)。我又做了一些研究,这似乎适合你的问题:stackoverflow.com/questions/1114026/…
    • 这似乎是我的情况的正确解决方案。我目前正在为我们的案例验证这种方法,并将其作为解决方案。
    • 那么我认为现在唯一的问题是关于您的构建自动化脚本。很久以前我也有同样的问题,但是没有足够的时间来研究 Jenkins 管道脚本的标准解决方案。
    • 您的构建自动化脚本面临什么样的问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-20
    • 1970-01-01
    • 1970-01-01
    • 2014-07-27
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多