研究线程Maven with an explicit finalName won't work properly。我想知道 -
问题1 - maven' project.parent.attribute
中parent.attribute
和pom.xml
之间的区别是什么?
目前使用Maven 3.3.9和intellJ作为IDE所有我看到的属性都导航到相同的属性。还想到了这个事实
<project>
是描述符的根。
用于定义任何pom.xml,在这种情况下,project.parent。*应等于模块的parent.*
。
问题2 - 如果上述说明合理,那么finalName
属性会在调用时覆盖父项的<name>
属性它的子模块是pom.xml吗?
问题3 - 父模块的${project.name}
中finalName
的值是多少?它是父项的name
还是最内层的name
[打包为jar
,war
等]的孩子?
答案 0 :(得分:3)
修改:使用链接/示例扩展回答
project.parent.attribute
是访问父项目属性的正确方法。 parent.attribute
指向相同的值,但已被弃用(Maven 3.3+在构建开始时明确抱怨)
(请参阅Model Builder,其中说明已弃用*
和pom.*
访问权限)
name
和finalName
完全无关。 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中包含!的文件名)
在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>
步骤按以下顺序执行(仅两个重要步骤):
<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,在上一步之后,所有内容仅在当前项目的(代际)模型上完成:
<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作为文件名,并且可能会混淆同一文件的不同名称。