分层多模块项目的Maven命名约定

时间:2012-02-24 17:43:36

标签: maven naming-conventions hierarchy directory-structure multi-module

我在一个带有分层目录结构的多模块项目中有一个关于Maven命名约定(groupId,artifactId和目录名称)的问题。

研究

在询问之前,我通过其他网络了解了这个主题以及我为自己清理的内容:

  1. Possible duplication for my question, but it does not cover multiple-hierarchy levels.

  2. Project directory name should match artificatId

  3. Guide to Naming Conventions 举例:

    • groupId 将在所有项目中唯一标识您的项目,因此我们需要强制执行命名架构。它必须遵循包名称规则(例如org.apache.maven,org.apache.commons,org.apache.maven.plugins)

    • artifactId 如果你创建了它,那么你可以用小写字母选择你想要的名字而不是奇怪的符号。 (例如,maven,commons-math)

  4. 这很简单,我理解,但有些事情仍然不清楚。

    约定中提到的

    artifactId 示例只能应用于单级层次结构模块。

    实施例

    我浏览了maven存储库并提取了一些示例:

    Spring主要使用名称:spring-core,spring-context,spring-context-support。所有独立模块都是一级层次结构和弹出前缀,以提高搜索效率。没有问题,因为等级不是那么深。

    对于Apache来说,

    Apache CXF namings非常传统。工件是独立模块,在名称中最多可包含5个不同的工件。 CXF的工具,wsdlto,数据绑定,JAXB。

    有很多工件(cxf-rt-databinding-jaxb,cxf-rt-databinding-aegis,cxf-rt-databinding-xmlbeans,cxf-rt-databinding-sdo)可以在多个模块项目中分组( cxf-rt-databindings),但他们没有,所以这些名字变成了意大利面条。

    最后,Maven Plugins首先是一个多模块项目(在org.apache.maven之后),其中包含以下工件:maven-compiler-plugin,maven-enforcer-plugin。

    有很多例子,并且在命名artifactIds(因此是项目目录)时都遵循不同的约定

    结果

    从示例中获取最佳实践,让我们检查层次结构级别。

    单级层次结构命名将是(

    groupId:    org.organization.project
    artifactId: project-portal ---.
                                  |
                                  project-portal-service
                                  |
                                  project-portal-plugins (continued on next diagram)
                                  |
                                  project-portal-util
    

    (续)两级层次结构将是:

    groupId:    org.organization.project.plugins
    artifactId: project-portal-plugins ---.
                                          |
                                          project-sample-plugin
                                          |
                                          project-another-great-plugin
                                          |
                                          ???? (multiple module project)
    

    你看到问号?

    问题

    我遵循示例中的约定(忽略意大利面条Apache CXF示例):

    • 根 - 项目门户(例如,spring-core,maven-core)
    • 第一级层次结构名称从root-project-portal-plugins继承(例如spring-context-support)。
    • 二级层次结构名称 - project-sample-plugin(例如maven-compiler-plugin)。

    现在我们被困在第三级,比如没有保存和检查点的旧游戏。

    1. 这是从Maven示例中获取的更深层次结构级别的正确目录命名路径吗?
    2. 您是否遵循任何约定或规则来支持简单的目录和工件名称,以避免更深层次上的意大利面条名称?
    3. 如果有简单的名称,groupId会从存储库中的冲突中保存重复的工件名称(这会因简单而发生)吗?
    4. 如何在具有重复名称的Web /存储库中搜索和查找工件(由于简单性)?
    5. 我不希望在我的项目结构中看到像project-portal-liferay-plugins-themes这样的模块,用于父级甚至更糟糕的项目 - portal-liferay-plugins-themes-white-puppy-wtf-name for children

      如果您可以提出您对任何提及的问题和可能出现的问题的意见和做法,那不仅对我而且对每个使用maven的人都有很大的帮助。谢谢。

3 个答案:

答案 0 :(得分:20)

在maven的早期阶段,我遵循了您所描述的以下结构:

appname
  +--- appname-module1
  +--- appname-module2
              +--- appname-module2-chhild1
              +--- appname-module2-chhild2
  +--- appname-module3

但如果你获得更多关卡,这将变得荒谬。

所以我决定改变主意,现在使用以下内容:

appname
  +--- module1
  +--- module2
          +--- chhild1
                 +--- subchild1
          +--- chhild2
  +--- module3

我通过关卡改变的唯一方法是groupId ......

appname (groupId: com.soebes.appname)
  +--- module1 (groupId: com.soebes.appname.module1)
  +--- module2 (groupId: com.soebes.appname.module2)
          +--- chhild1 (groupId: com.soebes.appname.module1.child1)
          +--- chhild2 (groupId: com.soebes.appname.module1.child2)
  +--- module3 (groupId: com.soebes.appname.module3)

答案 1 :(得分:4)

在这种情况下,我认为没有明确规定如何设置项目结构的约定。

E.g。我会尝试回答文物最终的名称,以及发生冲突的可能性。 对于像spring这样的框架,在artifactId(“spring- *”)中使用项目名称是有意义的,对于commons-libraries也是如此(尽管“commons-logging”可能是一个冒险的名称)。

对于独立运行的项目,我可能没有必要这样做。但看起来你会使用一个liferay门户网站,周围有很多不同的罐子,所以我会鼓励这些文物的前缀。 但我不会尝试基于artifactId重建项目结构。所以“project-modulename”将是一个很好的模块名称。由于jar将构建类路径并且在构建期间定义了依赖关系结构,因此这不是问题。如果需要根据jar列表重建依赖关系树:maven包含META-INF中的信息(如果你使用release-plugin,我也推荐),这样就可以从那里检索信息。

我还建议不要深入嵌套模块。 Eclipse有一些问题(IntelliJ没有,Netbeans afaik也支持嵌套结构)。

与插件模块相比,主门户模块可能不会经常更改。所以我将它们拆分成单独的项目是有意义的 - 这也允许分开发布项目。

对我来说,将父模块命名为“-parent”后缀是一个好习惯。这些模块很少用作依赖项,依赖项的“-parent”表示某些内容可疑。正如你所说:artifacId和模块名称应该是相同的。我还建议使用artifactId作为pom中的名称。有些插件不考虑这里的差异,如果这些值完全相同,Eclipse的表现也会更好。

goupId和artifactId通常包含重复信息(例如,它的一部分将是项目名称)。如果这是故意或在过去几年发生的......?我不知道,但我会保持这种方式。使用GAV(P)坐标(groupId,artifactId,version,(packaging))识别伪像。如果groupId或artifactId包含projectname工件,如果你只有其中一个,则更容易找到。

如果您正在运行存储库管理器(如Nexus,Artifactory,Archiva),则查找工件很容易。搜索通常会渲染groupId / artifactId等等,因此搜索“util”会为您提供足够的信息来查找您要查找的工件。

希望这有点帮助:) 问候

wemu

答案 2 :(得分:2)

另一种可能的方法是查看多于层次结构的功能组。

假设项目B有webapps,插件和核心库,那么所有模块共享相同的组ID(com.mycompany.b)和artefacts分别命名为webapp - ???,plugin - ???和核心 - ???。

我们还使用前面提到的-parent约定:因此,所有webapps的父POM称为webapp-parent.pom。