编辑:
问题1
project.parent.attribute
是访问父项目属性的正确方法。
parent.attribute
指向相同的值,但已被弃用(Maven 3.3+在构建开始时显然对此表示不满)
(见
Model Builder
,其中指出
*
和
pom.*
问题2
name
和
finalName
完全无关。
名称
是项目的明文名称(并且是子项目从未继承的少数元素之一),
最终名称
是工件文件的名称。
如
POM Reference
:
最终名称
:这是最终构建绑定项目时的名称(无文件扩展名,例如:my-project-1.0.jar)。默认为${artifactId}-${version}。
名称
:项目往往有会话名称,而不仅仅是artifactId。
所以这两个有不同的用途。
-
名称
纯粹是信息性的,主要用于生成文档和构建日志。它不会被继承,也不会在其他地方使用。它是人类可读的字符串,因此可以包含任何字符,即文件名中不允许的空格或字符。因此,这是有效的:
<name>My Turbo Project on Speed!</name>
这显然至少是工件的可疑文件名。
-
如上所述,
最终名称
是生成的工件的名称。它
是
继承,因此它通常应该依赖于属性。只有两个真正有用的选项是默认值
${artifactId}-${version}
和无版本
${artifactId}
.其他一切都会导致混淆(例如名为
foo
bar.jar
). 实际上,这是我的涡轮项目!将是有效的,因为这是一个有效的文件名,但实际上,这样的文件名往往是不可用的(例如,尝试从bash中处理包含!的文件名)
问题3
在pom的解析中,首先按顺序应用所有父项,然后解析属性(始终针对当前项目)。因此,该名称将是最内部子级的名称(但是,请参见上文:不要使用
project.name
,因为它可能包含空格和其他非法字符)
看见
模型构建器
大胆的
:
-
第一阶段
-
-
原始模型验证:ModelValidator(javadoc)及其DefaultModelValidactor实现(源代码)
-
模型规范化-合并重复项:ModelNormalizer(javadoc)及其DefaultModelNormalimer实现(源代码)
-
配置文件注入:ProfileInjector(javadoc),及其默认的ProfileInject实现(源代码)
-
-
继承程序集:InheritanceAssembler(javadoc),及其默认的InheritaceAssembler实现(源代码)。注意这个项目。url,project.scm。在这个连接中,project.scm。developerConnection,project.scm。url和project.distributionManagement.site。url有一个特殊的处理:如果未在子项中重写,则默认值为父项的值,并附加子项id
-
模型插值(见下文)
-
url规范化:UrlNormalizer(javadoc),及其默认的UrlNormallizer实现(源代码)
因此,给定两个文件(仅相关部分):
父母亲
<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”,包含超级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>${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>
一般来说,
最终名称
应小心使用。删除本地生成的工件中的版本可能很有用,以使本地容器中的测试更容易(
${project.artifactId}
而不是默认值
${project.artifactId}-${project.version}
),但我强烈建议不要使用其他任何东西,因为上传的工件(到存储库)无论如何都会将原始工件ID作为文件名,并且同一文件使用不同的名称可能会混淆。