33

我对具有分层目录结构的多模块项目中的 Maven 命名约定(groupId、artifactId 和目录名称)有疑问。

研究

在询问之前,我浏览了有关此主题的其他网络以及我为自己清除的内容:

  1. 我的问题可能重复,但它不涵盖多层次结构。

  2. 项目目录名称应与 artificatId 匹配

  3. 命名约定指南 提供了示例:

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

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

这很简单,我理解它,但是仍然有一些不清楚的地方。

约定中提到的artifactId示例只能应用于一级层次结构模块。

例子

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

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

Apache CXF命名对于 Apache 来说是非常规的。工件是独立的模块,名称中最多有 5 个可能的不同工件,例如。cxf-tools-wsdlto-databinding-jaxb。

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

最后,Maven 插件首先是一个多模块项目(在 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)
  • 第一级层次结构名称继承自根 - project-portal-plugins(例如 spring-context-support)。
  • 二级层次结构名称 - project-sample-plugin(例如 maven-compiler-plugin)。

现在我们被困在第三层,就像在没有保存和检查点的旧游戏中一样。

  1. 这是从 Maven 示例中获取的更深层次结构级别的正确目录命名路径吗?
  2. 您是否遵循任何约定或规则来支持简单的目录和工件名称,避免在更深层次上使用意大利面条名称?
  3. 如果有简单的名称,groupId 是否会从存储库中的冲突中保存重复的工件名称(由于简单而会发生)?
  4. 如何在具有重复名称的 Web/存储库上搜索和查找工件(由于简单性)?

我不想在我的项目结构中看到像 project-portal-liferay-plugins-themes 这样的模块用于父级,或者更糟糕的是 project-portal-liferay-plugins-themes-white-puppy-wtf-name 用于孩子。

如果您可以为任何提到的问题和可能的问题提供您的意见和实践,那不仅对我有很大帮助,而且对使用 maven 的每个人也有很大帮助。谢谢你。

4

3 回答 3

22

在早期使用 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)
于 2012-02-27T07:49:43.423 回答
5

I don't think there are conventions that would clearly specify on how you should setup your project structure in this case.

E.g. I would try to answer where the artifacts end up with their name and whats the chance of running into a conflict. For a framework like spring it does make sense to have the project name in the artifactId ("spring-*"), same is true for commons- libraries (although "commons-logging" may by a risky name).

For a project that runs standalone I is probably not necessary to do this. But it looks like you will use a liferay portal where a lot of different jars will be around so I would encourage a prefix for the artifacts. But I would not try to rebuild the project structure based on artifactId's. So "project-modulename" will be a good module name. Since the jars will build the classpath and the dependency structure was defined during the build this is not an issue. If you need to rebuild the dependency tree based on a list of jars: maven includes information in META-INF (if you use the release-plugin, which I also recommend) so the information can be retrieved from there.

I would also recommend to not nest modules to deeply. Eclipse has some issues with this (IntelliJ does not, Netbeans afaik supports nested structures too).

The main portal module may not change that often compared to the plugin modules. So I makes sense to split them into separate projects - this would also allow to release the projects separatly.

For me it is a good practice to name parent modules with "-parent" suffix. These modules are rarely used as dependency and a "-parent" for a dependency would indicate something is suspicious. As you said: artifacId and module name should be the same. I would also recommend using the artifactId as name in the pom. Some plugins dont consider differences here and also Eclipse behaves better if these values are all the same.

It is true the goupId and the artifactId often contain duplicate information (e.g. parts of it will be the projectname). If this was done on purpose or happend in the last years...? I dont know but I would keep it this way. Artifacts are identified using the GAV(P) coordinates (groupId, artifactId, version, (packaging)). If groupId or artifactId contain the projectname artifacts are more easy to find if you only have one of them.

Finding artifacts is easy if you are running a repository manager (like Nexus, Artifactory, Archiva). The search will often render groupId/artifactId and so on so a search for "util" would give you enough information to find the artifact you are looking for.

hope this helped a bit :) regards

wemu

于 2012-02-27T07:26:12.033 回答
3

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

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

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

于 2012-03-10T11:45:34.943 回答