Maven:多个父POM?

9

我有一个多模块的foo项目,其POM结构如下:

Foo

Foo POM 结构

/pom.xml             (root/'grandparent' POM)
/parent-foo/pom.xml  (a parent with 'foo' dependencies & configurations) 
/child-1/pom.xml     
...
/child-n/pom.xml   

Foo POM继承

这种标准的父子关系是parent-fooroot继承,而child-nparent-foo继承。

root -> parent-foo -> child-n

这些都很好,并且对于这个简单的案例可以正常工作。

(未来)用例

使用parent-foo适用于基于foo的旧有用例,但也要测试我们正在迁移的未来用例:bar

Bar

Bar POM结构

/pom.xml             (root POM)
/parent-bar/pom.xml  (a parent with 'bar' dependencies & configurations) 
/child-1/pom.xml     
...
/child-n/pom.xml 

Bar POM 继承

root -> parent-bar -> child-n

问题

我是否可以实现以下的反应堆构建,而不必每次修改child-n POM时都要进行一些变通?或者说有没有类似的解决方案?或者说,Maven是否只是这种用例的错误工具?

[INFO] ------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] root ............................................... SUCCESS
[INFO] parent-foo ......................................... SUCCESS
[INFO] child-1 ............................................ SUCCESS (foo parent)
[INFO] ...
[INFO] child-n ............................................ SUCCESS (foo parent)
[INFO] parent-bar ......................................... SUCCESS
[INFO] child-1 ............................................ SUCCESS (bar parent)
[INFO] ...
[INFO] child-n ............................................ SUCCESS (bar parent)
[INFO] ------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------

理想情况下,我希望将所有内容放在一个反应堆构建中,每个“child-n”都编译并使用每个“parent-*”继承的依赖项。我知道这会使我的Maven仓库处于不良状态,但至少我可以将反应堆构建插入我的CI中,并确保我的构建在“parent-*”依赖平台上运行。

当前解决方法

目前的解决方法是修改所有“child-n” POM的父级,如下所示:
# 1. modify all child-n POMs
   # Old:
      root -> parent-foo -> child-n
   # New:
      root -> parent-bar -> child-n
2. Run reactor build effective with 'root -> parent-bar -> child-n' dependency tree

编辑 1:

  • 注意到root POM实质上是“祖父”POM,根据@OhadR的评论。
  • 注意到'foo'和'bar'不仅提供依赖继承,还提供构建配置--如果它们只提供了依赖项,则基于Maven配置文件的解决方案就足够了。

你可以查看瓦片。 - bmargulies
@bmarguiles,“tiles”是一个相当常见的词;有链接或者例子吗?我查看了maven-tiles-plugin,但似乎不太合适。如果您有这些信息,将其放在答案中可能更好。 - JJ Zabkar
你能不能创建一个“祖先”POM,它将有两个模块:parent-foo和parent-bar?parent-foo和parent-bar之间有什么区别?你能把它们粘贴在这里吗? - OhadR
1
@OhadR:我更新了帖子,以反映root确实是祖父。每个父级(foo、bar)都有一个完整的构建配置要继承(例如:一个JDK6,另一个JDK8),除了独立的依赖项。目标是拥有共同的+共享的根、共同的+共享的子代和独立/中间的父代,以便它们可以将其构建/配置传递给子代。祖父是一个单一的静态实体,不能单独实现该解决方案(没有修改)。 - JJ Zabkar
https://github.com/repaint-io/maven-tiles - bmargulies
2个回答

15

简短回答:Maven不支持多继承,但通过在依赖管理部分使用"import"作用域间接支持该概念。

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>other.pom.group.id</groupId>
            <artifactId>other-pom-artifact-id</artifactId>
            <version>SNAPSHOT</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>   
    </dependencies>
</dependencyManagement> 

由于它属于管理部分,唯一的不便之处是您必须显式声明依赖项,但是......您所实现的是:

具有不同的 POM 文件 - 每个文件都管理一组相关的依赖项。项目只需要导入这些 POM 文件,然后使用依赖项而无需担心依赖项版本。从根本上讲,这使得父级 POM 文件简单且精简。


1
孩子-n项目之间的依赖关系如何?只在每个父级-*内部还是跨越父级-*?
如果是我,我会创建像这样的东西:
/pom.xml                                    (Parent POM for all projects)

/project-foo/pom.xml                        (BOM for Project Foo. only dependencyManagement for foo-* artefacts)
/project-foo/parent/pom.xml                 (Parent POM for Project Foo. dependencyManagement for external used artifacts. ev.including import of bar BOM)
/project-foo/parent/foo-child1/pom.xml      (Child Artifact fron Project Foo)
/project-foo/parent/foo-child2/pom.xml      (Child Artifact fron Project Foo)
/project-foo/parent/foo-child3/pom.xml      (Child Artifact fron Project Foo)

/project-bar/pom.xml                        (BOM for Project Bar. only dependencyManagement for bar-* artefacts. ev.including import of foo BOM)
/project-bar/parent/pom.xml                 (Parent POM for Project Bar)
/project-bar/parent/bar-child1/pom.xml      (Child Artifact fron Project Bar)
/project-bar/parent/bar-child2/pom.xml      (Child Artifact fron Project Bar)
/project-bar/parent/bar-child2/pom.xml      (Child Artifact fron Project Bar)

我认为您每个项目都有一个持续集成/构建工作。然后,您可以将其指向您的/project-*/pom.xml。
官方Maven页面中的链接: http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Management 我希望我完全理解了您的问题...

这里只有孩子,没有“foo-children”或“bar-children”。我提出这个问题的目标是为了扩展到n个父母;虽然只有“foo”和“bar”很简单(n=2),但我正在寻找解决更一般情况的方案(n>2)。 - JJ Zabkar
1
好的,我想我现在明白了...我已经创建了一个Git存储库...我认为这更好地解释了...https://github.com/StefanHeimberg/stackoverflow-27255471/问题是模块只能在反应器中使用一次。第二个问题是属性和依赖项是从父级继承的。而且你只能有一个父级,它不能通过属性进行动态配置,因为属性不会被父级继承,因为如果父级是动态的,那么父级就是未知的...(鸡生蛋问题)... - StefanHeimberg
对于不同的依赖或属性,我认为最好的解决方案是使用配置文件...但你不能在同一个构建反应堆内有多个相同的子项目。但你可以在你的CI中创建多个作业。代替两个父级,你只有一个父级,但有两个配置文件。每个配置文件在相应的独立CI作业中启用...但是你必须用相同的源文件创建不同的工作目录,因为目标文件夹不能在不同的配置文件执行之间“共享”。 - StefanHeimberg
我知道我的英文不是最好的。但我希望我理解了你的问题,你也能明白我的意思。 - StefanHeimberg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接