Maven家长pom与模块pom

在一个多项目构build中,似乎有几种方法来组织父母,我想知道是否有人对每种方式的优点/缺点有什么想法。

有一个父pom最简单的方法将把它放在一个项目的根,即

myproject/ myproject-core/ myproject-api/ myproject-app/ pom.xml 

其中pom.xml既是父项目也是描述了-core -api和-app模块

下一个方法是把父母分成它自己的子目录

 myproject/ mypoject-parent/ pom.xml myproject-core/ myproject-api/ myproject-app/ 

父pom仍然包含模块,但它们是相对的,例如../myproject-core

最后,有模块定义和父项分开的选项

 myproject/ mypoject-parent/ pom.xml myproject-core/ myproject-api/ myproject-app/ pom.xml 

父pom包含任何“共享”configuration(dependencyManagement,属性等),myproject / pom.xml包含模块列表。

其目的是扩展到大规模的构build,所以应该扩展到大量的项目和文物。

一些奖励问题:

  • 在源代码控制,部署目录,通用插件等中定义各种共享configuration的最好的地方在哪里(我假设父母,但我经常被这个咬伤,他们已经结束在每个项目,而不是一个普通的)。
  • maven-release插件,hudson和nexus如何处理你如何设置你的多项目(可能是一个巨大的问题,如果任何人被多个项目build立的话,已经被捕获了)。

编辑:每个子项目有自己的pom.xml,我已经离开它保持简洁。

在我看来,要回答这个问题,你需要考虑项目生命周期和版本控制。 换句话说,父pom是否有其自己的生命周期,即是否可以与其他模块分开发布?

如果答案是肯定的 (这就是问题中或评论中提到的大多数项目的情况),那么父pom需要从VCS和Maven的angular度来看他自己的模块,在VCS级别有这样的事情:

 root |-- parent-pom | |-- branches | |-- tags | `-- trunk | `-- pom.xml `-- projectA |-- branches |-- tags `-- trunk |-- module1 | `-- pom.xml |-- moduleN | `-- pom.xml `-- pom.xml 

这使得结帐有点痛苦,一个常见的处理方法是使用svn:externals 。 例如,添加一个trunks目录:

 root |-- parent-pom | |-- branches | |-- tags | `-- trunk | `-- pom.xml |-- projectA | |-- branches | |-- tags | `-- trunk | |-- module1 | | `-- pom.xml | |-- moduleN | | `-- pom.xml | `-- pom.xml `-- trunks 

有了以下外部定义:

 parent-pom http://host/svn/parent-pom/trunk projectA http://host/svn/projectA/trunk 

trunks的结账会导致下面的局部结构(模式#2):

 root/ parent-pom/ pom.xml projectA/ 

或者,您甚至可以在pom.xml目录中添加一个pom.xml文件:

 root |-- parent-pom | |-- branches | |-- tags | `-- trunk | `-- pom.xml |-- projectA | |-- branches | |-- tags | `-- trunk | |-- module1 | | `-- pom.xml | |-- moduleN | | `-- pom.xml | `-- pom.xml `-- trunks `-- pom.xml 

这个pom.xml是一种“假”的pom:它永远不会被释放,它不包含真正的版本,因为这个文件永远不会被释放,它只包含一个模块列表。 有了这个文件,签出会导致这个结构(模式#3):

 root/ parent-pom/ pom.xml projectA/ pom.xml 

这个“黑客”允许在结帐后从根部启动反应堆构build,使事情变得更加方便。 实际上,这就是我喜欢为大型构build设置Maven项目和VCS存储库的方法:它可以正常工作,扩展性好,可以提供所需的所有灵活性。

如果答案是否定的 (回到最初的问题),那么我认为你可以与模式#1(做最简单的事情可能工作)。

现在,关于奖金问题:

  • 在源代码控制,部署目录,通用插件等中定义各种共享configuration的最好的地方在哪里(我假设父母,但我经常被这个咬伤,他们已经结束在每个项目,而不是一个普通的)。

老实说,我不知道怎么在这里不给一个普遍的答案(比如“用你认为有意义的层次来互相作用”)。 无论如何,孩子poms总是可以覆盖inheritance的设置。

  • maven-release插件,hudson和nexus如何处理你如何设置你的多项目(可能是一个巨大的问题,如果任何人被多个项目build立的话,已经被捕获了)。

我使用的设置工作得很好,没有什么特别的提及。

实际上,我想知道maven-release-plugin是如何处理模式#1的(特别是对于<parent>部分,因为在发布时不能有SNAPSHOT依赖关系)。 这听起来像一个鸡或鸡蛋的问题,但我不记得它是否工作,并懒得testing它。

从我的经验和Maven的最佳实践中,有两种“父母”

  • “公司”家长pom – 这个pom包含你的公司特定的信息和configuration,inheritance每一个pom,不需要复制。 这些信息是:

    • 资料库
    • 分配pipe理部分
    • 常见的插件configuration(如maven-compiler-plugin源码和目标版本)
    • 组织,开发者等

    准备这个家长团队需要谨慎行事,因为你所有的公司团队都会从团队中inheritance,所以这个团队必须是成熟和稳定的(发布一个家长团队的版本不应该影响你的公司项目的发布!)

  • 第二种父母是一个多模块的父母。 我更喜欢你的第一个解决scheme – 这是一个默认的多模块项目的maven约定,通常代表VCS代码结构

其目的是扩展到大规模的构build,所以应该扩展到大量的项目和文物。

Mutliprojects具有树的结构 – 所以你不会落在父母的一个层次上。 尝试为您的需求find一个合适的项目结构 – 一个典型的例子是如何distimibute mutimodule项目

 distibution/ documentation/ myproject/ myproject-core/ myproject-api/ myproject-app/ pom.xml pom.xml 

一些奖励问题:

  • 在源代码控制,部署目录,通用插件等中定义各种共享configuration的最好的地方在哪里(我假设父母,但我经常被这个咬伤,他们已经结束在每个项目,而不是一个普通的)。

这种configuration必须明智地分解为“公司”母公司和项目母公司。 与你所有项目相关的事情都转到“公司”母公司,这与当前项目有关。

  • maven-release插件,hudson和nexus如何处理你如何设置你的多项目(可能是一个巨大的问题,如果任何人被多个项目build立的话,已经被捕获了)。

公司母公司必须先被发布。 对于多项目,适用标准规则。 CI服务器需要知道所有正确构build项目。

  1. 独立的父母是在其他非耦合组件之间共享configuration和选项的最佳实践。 Apache有一个父母项目来分享法律通知和一些常见的包装选项。

  2. 如果您的顶级项目在其中有实际的工作,比如聚合javadoc或打包发布,那么您在执行此项工作所需的设置与您想要通过父项共享的设置之间会产生冲突。 一个只有父母的项目避免了这一点。

  3. 一个常见的模式(暂时忽略#1)是项目代码使用一个父项目作为他们的父母,并使用顶层作为父项目。 这可以让所有人共享核心内容,但避免了#2中描述的问题。

  4. 如果父级结构与目录结构不一样,那么站点插件会变得非常困惑。 如果你想build立一个聚合的网站,你需要做一些摆渡来解决这个问题。

  5. Apache CXF就是#2模式的一个例子。

第三种方法有一点小问题。 由于聚合POM(myproject / pom.xml)通常没有父级,所以它们不共享configuration。 这意味着所有这些聚合POM将只有默认的存储库。

如果您只使用Central的插件,那么这不是问题,但是如果您使用内部存储库中的plugin:goal格式运行插件,将会失败。 例如,您可以使用org.example的groupId提供目标generate-foo foo-maven-plugin 。 如果尝试使用像mvn org.example:foo-maven-plugin:generate-foo这样的命令从项目根目录运行它mvn org.example:foo-maven-plugin:generate-foo ,它将无法在聚合模块上运行(请参阅兼容性说明 )。

可能有几种解决scheme:

  1. 将插件部署到Maven Central(并非总是可行)。
  2. 在所有聚合POM中指定存储库部分(打破DRY原则)。
  3. 在settings.xml(在〜/ .m2 / settings.xml的本地设置中或在/conf/settings.xml的全局设置中)configuration此内部存储库。 如果没有这些settings.xml,构build失败(对于那些从来不应该在公司之外构build的大型内部项目,这可能是可以的)。
  4. 在您的聚合POM中使用父级与存储库设置(可能是太多的父POM?)。