2014-09-01 70 views
5

我正在开发一些项目(目前组织为eclipse项目)。有一个主要提供核心API和一些辅助实现和抽象类的核心项目。所有其他项目都依赖于这个项目。应用maven groupId命名约定

将项目集成到我们的Maven存储库时,我们遇到了Maven命名约定的问题。正如在SO上所讨论的,groupId通常应该是反向公司域名(com.example)加上项目名称(com.example.foo)。 maven命名约定为插件等子项目提供了额外的后缀(com.example.foo.plugin)。

在我们的例子中,我们没有插件,但是核心项目提供了API的多个(主要是独立的)实现。我们当前的命名建议是:

  • com.example.foo所有项目的groupId,虽然他们分成不同的Java包(com.example.foo包含API,com.example.foo.bar包含bar实现)
  • 项目名称为的artifactId ,没有前缀参照项目(的bar代替foo-bar

关键的一点是,(虽然我们的项目被分散翻过包如上所述),他们是不是真的子-p API核心项目的主要内容。

此建议是否符合maven命名约定?

以防万一:这个问题是而不是要求有意义的答复,但对上述问题的争论性答案。

+0

我必须诚实地说,我从来没有把这么多想法放入Maven的命名约定中:-) – kaqqao 2014-09-01 18:50:55

+0

@kaqqao嗯,我们做:) – 2014-09-01 19:43:05

回答

7

我会说这是你自己的品味和喜好的问题。

通常情况下,您可以在相同的groupId下对相似的模块组进行分组。例如,你可以有以下几点:

com.foo.bar:parent       (parent pom for all projects) 
com.foo.bar:core-api      (some very core classes) 
com.foo.bar:commons       (some common classes) 
com.foo.bar:io        (some IO classes) 
com.foo.bar:utils       (some utility classes) 
com.foo.bar.messaging:messaging-core  (messaging core classes) 
com.foo.bar.messaging:messaging-rest-api (REST API for messaging) 
com.foo.bar.messaging:messaging-jms   (some JMS code) 
com.foo.bar.web:rest-api     (your restlets) 
com.foo.bar.web:web-core     (core classes to be used by web modules) 
com.foo.bar.web:web-parent     (a parent pom for all your web projects) 
com.foo.bar.web:web-ui      (UI stuff like css/images/js/etc) 
com.foo.bar.web:web-assembly    (a web assembly that bundles all modules) 
... (I hope by now you get my drift) ... 

你并不一定需要一群人的班级开始在相同groupId一个共同的包中的所有模块。你可能这样做,如果你喜欢,但很少有人真正在现实生活中使用它。严格程度和详细程度取决于您,但对于工件而言,通常无关紧要,因为没有必要将包名称与groupId绑定。

此外,为您的模块使用前缀也很有帮助,但取决于您。如果你喜欢,你可以有:

com.foo.bar:bar-parent 
com.foo.bar:bar-core-api 
com.foo.bar:bar-commons 

这真的取决于你。有人会说,如果你有groupIdcom.foo.bar,那么bar-parent的前缀就不需要有bar-的前缀。在某种程度上,这是事实。但是,您可能有com.foo.bar:parentcom.foo.bar.web:parent,并且当您使用像Nexus,Archiva或Artifactory这样的存储库管理器时,如果您正在搜索parent(或其他常用名称,例如... commons),则可能会结束结果列表较长,与bar-parent相反。

最后,重要的是你愿意去什么样的细节和什么会真正适合你的需求。 Maven可以让你在这方面获得所有你需要的自由。

+2

另外:请记住,groupId + artifactId组合在全球范围内必须是唯一的(!),因此使用domainname作为groupId的开头的约定会有所帮助。使用单个groupId就像为所有文件使用单个文件夹:一旦您达到某个数字,您将忽略概述,并且会引入子文件夹。切换到新的groupId和/或artifactId可能对Maven有影响,因为它不知道它是相同的,导致项目中出现重复的代码。所以是的,在前面选择合适的组。 – 2014-09-07 12:41:06

+0

很高兴收到一位Maven官方开发人员的评论,确认(并扩展)我的观点! – carlspring 2014-09-07 12:51:39

3

所以当我看到它,你有一堆随后行家命名约定选项...

富指的是核心API和酒吧是指实施。

  1. com.example.foo(指核心API)作为组,然后是FOO条的实施(约定说您在您的工件名称钩回组)。

  2. com.example.bar作为THR组和工件ID是直板IMPL或其它一些适当的后缀

  3. com.example.foo.bar作为组和条形IMPL或其它一些适当的后缀。

对于你说对不熟悉的:实现紧密耦合到API并具有密切相关的发布周期。当核心API的新版本发布时,还会发布一个版本的实现。此外,实施是核心API的一个孩子,并不是真正的独立。你也在说酒吧的核心业务是实施酒吧,除此之外没什么价值(它不会做其他事情)。

您在说核心API的实现确实有它自己的生命周期,并且通常不会在与API相同的周期内发布。此外,它不是核心API的子项目,因此可以独立运作。换句话说,这是核心业务,使用不仅仅是作为foo的实现。如果酒吧可以有兄弟姐妹,这是特别有吸引力的。

是两者之间的中间道路。它表示bar本身具有价值,并且具有作为foo的实现的重要性,并且还可能允许兄弟姐妹。它略微提高了2,因为它提供了一些反馈,这个工件是foo的实现。再次,如果酒吧可以有兄弟姐妹,这更有意义。

所以我想你需要选择你的API实现的位置。最大的推动力可能是酒吧是否可以有兄弟姐妹。

+0

好吧,酒吧可以有兄弟姐妹,我们开发了一个由独立实现的客户端和服务器包组成的实现。你描述的第三种方式听起来很棒。你能再给我一个答案吗?如果我写了一个基本上在api附近提供UI的gui,该怎么办?它与核心api无关,所以应该是com.example.foo.gui还是com.example.foo-gui?我想这终究真的是个人品味的问题,你怎么看?无论如何感谢您的回答! – 2014-09-04 11:17:00

1

我想说可以将所有工件放在同一个groupId中。但是你应该在适当的地方使用子项目模式。

例如,spring的所有主要工件都在一个组中,org.springframework。这包括Spring的核心和JMS,ORM和WMV子项目。但是,像Spring Boot这样的更大的子项目有一个单独的组ID,org.springframework.boot。我会说这是一个很好的模式。

1

事物的命名非常重要,名字应该马上传达重要信息。出于这个原因,我公司使用的约定规定,对于特定事物的所有实现,组Id应该是相同的:每个组的Id都是com.example.foo,因为它们都是实现的。该项目的名称应该是指接口,并且,连字符和名称为自己特定的实现,以显着位置标明为“父”主父POM:

com.example.foo:parent 
com.example.foo:foo-bar 
com.example.foo:foo-bat 
com.example.foo:foo-baz 

这种方式,你可以从名字一眼就能看出这些事情究竟是如何相关的,并且工件名称也单独表示它们是不同类型的foo。这也意味着在java代码中的导入遵循完全相同的结构。它也使得导入在java代码中非常易读易懂。