project.parent.name和parent.name之间的区别在pom.xml中使用finalName

时间:2016-11-07 04:45:05

标签: xml maven maven-3

研究线程Maven with an explicit finalName won't work properly。我想知道 -

问题1 - maven' project.parent.attributeparent.attributepom.xml之间的区别是什么?

目前使用Maven 3.3.9和intellJ作为IDE所有我看到的属性都导航到相同的属性。还想到了这个事实

  

<project>是描述符的根。

用于定义任何pom.xml,在这种情况下,project.parent。*应等于模块的parent.*

问题2 - 如果上述说明合理,那么finalName属性会在调用时覆盖父项的<name>属性它的子模块是pom.xml吗?

问题3 - 父模块的${project.name}finalName的值是多少?它是父项的name还是最内层的name [打包为jarwar等]的孩子?

1 个答案:

答案 0 :(得分:3)

修改:使用链接/示例扩展回答

问题1

project.parent.attribute是访问父项目属性的正确方法。 parent.attribute指向相同的值,但已被弃用(Maven 3.3+在构建开始时明确抱怨)

(请参阅Model Builder,其中说明已弃用*pom.*访问权限)

问题2

namefinalName完全无关。 name是项目的明文名称(并且是从未由子项目继承的少数元素之一),finalName是工件文件的名称。

POM Reference中所述:

  

finalName :这是捆绑项目最终构建时的名称(没有文件扩展名,例如:my-project-1.0.jar)。它默认为$ {artifactId} - $ {version}。

     

名称:除了artifactId之外,项目往往具有会话名称。

所以这两个有不同的用途。

  • name纯粹是信息性的,主要用于生成的文档和构建日志。它不是在任何其他地方继承或使用的。它是一个人类可读的字符串,因此可以包含任何字符,即文件名中不允许的空格或字符。所以,这是有效的:<name>My Turbo Project on Speed!</name>。这显然至少是一件神器的可疑文件名。

  • 如上所述,finalName是生成的工件的名称。 继承,因此它通常应该依赖于属性。只有两个非常有用的选项是默认${artifactId}-${version}和无版本${artifactId}。其他一切都会导致混淆(例如名为foo的项目创建工件bar.jar)。其实,我的涡轮增压项目!是有效的,因为这是一个有效的文件名,但实际上,像这样的文件名往往是无法使用的(例如,尝试使用bash中包含!的文件名)

问题3

在pom的解析中,首先按顺序应用所有父项,然后仅解析属性(始终针对当前项目)。所以名称将是最里面的孩子的名字(但是,请参见上文:不要使用project.name,因为它可能包含空格和其他非法字符)

请参阅Model Builder了解详情,此处的相关步骤标有粗体

  
      
  • 第1阶段      
        
    • 个人资料激活:查看可用的激活器。请注意,模型插值尚未发生,然后基于文件的激活插值仅限于$ {basedir}(因为Maven 3),系统属性和请求属性
    •   
    • 原始模型验证:ModelValidator(javadoc)及其DefaultModelValidator实现(源代码)      
          
      • 模型规范化 - 合并重复项:ModelNormalizer(javadoc)及其DefaultModelNormalizer实现(源代码)
      •   
      • profile injection:ProfileInjector(javadoc)及其DefaultProfileInjector实现(源代码)
      •   
      • 直到super-pom的父级解析
      •   
      • 继承程序集:InheritanceAssembler(javadoc)及其DefaultInheritanceAssembler实现(源代码)。请注意,project.url,project.scm.connection,project.scm.developerConnection,project.scm.url和project.distributionManagement.site.url有一个特殊的处理方法:如果未在子节点中重写,则默认值为父节点的子节点附加工件ID
      •   
      • 模型插值(见下文)
      •   
      • url规范化:UrlNormalizer(javadoc)及其DefaultUrlNormalizer实现(源代码)
      •   
    •   
  •   

所以给出了两个文件(只有相关部分):

<artifactId>parent</artifactId>

<name>Parent Project</name>

<properties>
  <myProp>in-parent</myProp>
</properties>

<build>
  <finalName>${project.artifactId}-${myProp}</finalName>
</build>

<parent>
    <artifactId>parent</artifactId>
</parent>
<artifactId>child</artifactId>

<properties>
  <myProp>in-child</myProp>
</properties>

步骤按以下顺序执行(仅两个重要步骤):

  • 创建一个“世代pom”,其中包含所有poms的内容,直到超级pom:

世代POM

<parent>
    <artifactId>parent</artifactId>
</parent>
<artifactId>child</artifactId> <!-- artifact id is never inherited -->

<!-- name is NOT inherited, so no name for child -->

<properties>
  <myProp>in-child</myProp> <!-- from child -->
</properties>

<build> <!-- inherited from parent -->
  <finalName>${project.artifactId}-${myProp}</finalName>
</build>

并非代际pom仍然只包含属性,而不是值。

最后,在模型插值中,解析属性。在此步骤中,不再使用父pom,在上一步之后,所有内容仅在当前项目的(代际)模型上完成:

有效POM

<parent>
    <artifactId>parent</artifactId>
</parent>
<artifactId>child</artifactId> <!-- artifact id is never inherited -->

<!-- name is NOT inherited, so no name for child -->

<properties>
  <myProp>in-child</myProp> <!-- from child -->
</properties>

<build> <!-- inherited from parent -->
  <finalName>child-in-child</finalName> <!-- resolved against generational pom -->
</build>

一般来说,finalName应谨慎使用。删除本地生成的工件中的版本可以更方便地在本地容器中进行测试(${project.artifactId}而不是默认的${project.artifactId}-${project.version}),但我强烈建议不要使用其他任何东西,因为上传工件(到存储库)无论如何都会将原始artifactId作为文件名,并且可能会混淆同一文件的不同名称。