【问题标题】:Maven with an explicit finalName won't work properly具有显式 finalName 的 Maven 将无法正常工作
【发布时间】:2017-03-13 05:21:26
【问题描述】:

1.背景

我的 maven 项目有很多带有 jarswars 的模块和子模块,并且一切正常。我也可以毫无问题地将它部署在服务器上。

我决定关注this maven naming conversion,我正在使用project.nameproject.build.finalName 进行一些测试,以获得合适的名称。

我为根工件创建project.name 定义的模式是company-${project.artifactId},而模块和子模块的模式是${project.parent.name}-${project.artifactId}

  • company-any-artifact-any-module1
  • company-any-artifact-any-module2-any-submodule1
  • company-any-artifact-any-module2-any-submodule2

project.build.finalName 的模式是${project.name}-${project.version}

  • company-any-artifact-any-module1-1.0.jar
  • company-any-artifact-any-module2-any-submodule1-2.0.jar
  • company-any-artifact-any-module2-any-submodule2-3.0.war

但是 maven 没有生成这些文件,而是给了我一个 StackOverflowError

2。重现错误的示例

您可以从 github 克隆此示例:https://github.com/pauloleitemoreira/company-any-artifact

在 github 中有 master 分支,它会重现此错误。还有only-modules 分支,这是一个工作示例,它使用${project.parent.name} 生成我想要的jar finalName

让我们考虑一个具有一个根 pom 工件、一个 pom 模块和一个子模块的 maven 项目。

-any-artifact
     |
     |-any-module      
           |
           |-any-submodule

2.1 任意工件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.company</groupId>
    <artifactId>any-artifact</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>

    <name>company-${project.artifactId}</name>

    <modules>
        <module>any-module</module>
    </modules>

    <!-- if remove finalName, maven will not throw StackOverflow error -->
    <build>
        <finalName>${project.name}-${project.version}</finalName>
    </build>
</project>

2.2 任意模块

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <artifactId>any-artifact</artifactId>
        <groupId>com.company</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <groupId>com.company.any-artifact</groupId>
    <artifactId>any-module</artifactId>
    <packaging>pom</packaging>

    <name>${project.parent.name}-${project.artifactId}</name>

    <modules>
        <module>any-submodule</module>
    </modules>
</project>

2.3 任意子模块

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <artifactId>any-module</artifactId>
        <groupId>com.company.any-artifact</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <groupId>com.company.any-artifact.any-module</groupId>
    <artifactId>any-submodule</artifactId>

    <name>${project.parent.name}-${project.artifactId}</name>
</project>

3.问题

当尝试mvn clean install 时,maven 给了我一个StackOverflowError

Exception in thread "main" java.lang.StackOverflowError
    at org.codehaus.plexus.util.StringUtils.isEmpty(StringUtils.java:177)
    at org.codehaus.plexus.util.introspection.ReflectionValueExtractor.evaluate(ReflectionValueExtractor.java:194)
    at org.codehaus.plexus.util.introspection.ReflectionValueExtractor.evaluate(ReflectionValueExtractor.java:163)
    at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:266)
    at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:143)
    at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:174)
    at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:143)
    at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:429)
    at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:143)
    at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:174)
    at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:143)
    at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:429)
    at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:143)
    at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:174)
    at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:143)

重要的是要知道错误仅在我们使用子模块时发生。如果我们使用根 POM 工件和 jar 模块创建项目,则不会发生错误。

4.问题

为什么只有在我们使用子模块时才会出现这个错误?

有什么建议可以解决我的问题吗?我应该忘记它并按照我想要的模式为每个项目手动设置project.nameproject.build.fileName 吗?

重要更新:

有些答案只是说使用&amp;{parent.name},但它不起作用。拜托,这是一个赏金问题,在回答这个问题之前,请考虑使用Maven version 3.3.9 测试您的解决方案。

Maven 版本 3.3.9

编辑 - 在发生错误的阶段向问题添加详细信息,直到 prepare-package 阶段一切正常,但 StackOverflow 发生在 @ 987654353@ 项目的 Maven 生命周期阶段。

【问题讨论】:

  • 你想在哪里生成 .jar?
  • 首先,如果您尝试生成战争,则必须将包装更改为战争,而不是进一步删除 outputDirectory 配置,因为它通常没有意义。
  • @Paolo 我可以重现 stackoverflowerror 的问题,但即使将 finalName 注释掉,我也无法重现这种情况。它不会给出错误,但它也不能用作名称。由于父名没有被继承,我看不出这怎么可能奏效。
  • 这是我的 2 美分。 标签中没有带有 的标签。看一下 maven 项目描述符maven.apache.org/ref/3-LATEST/maven-model/maven.html。所以 ${project.parent.name} 根本不是一个有效的表达式。正确的解决方法是在每个项目 pom.xml 的名称标签中包含文字值。名字也不能继承。所以我认为你正在尝试做的事情甚至都没有得到官方的支持..
  • 这里是完全相同的场景,如果有帮助的话,它已经被关闭,因为不是问题。 issues.apache.org/jira/browse/MNG-5784。一旦您将每个文件中的名称更改为唯一,一切都应该检查好,是的,如果您使用有效的表达式,您可以将最终构建名称设为您喜欢的名称。

标签: java maven stack-overflow maven-package


【解决方案1】:

这是属性继承的问题。
尝试使用${parent.name} 而不是${project.parent.name}
看:Project name declared in parent POM isn't expanded in a module filtered web.xml

---更新---

Benjamin Bentmann (maven committier) 说:“不过,一般来说,${project.parent.*} 形式的表达式是一种不好的做法,因为它们依赖于特定的构建状态,并且通常不会在整个 POM 中工作,从而引起意外”。

https://issues.apache.org/jira/browse/MNG-5126?jql=text%20~%20%22parent%20name%22

也许您应该考虑使用${project.parent.*} 是一个好方法。

【讨论】:

  • 它不起作用。我的反对票是因为它不能解决我的问题。实际上,它使问题变得更糟。通过您的方法,最终名称从 company-any-artifact-any-module-1.0.war 更改为 ${parent.name}-any-module-1.0.war。
  • 请考虑在回答之前使用Maven version 3.3.9 测试您的解决方案。
  • 我用${project.parent.name} 尝试了你的例子,但对我来说它在 mvn 版本 3.3.9 上运行良好。在调用mvn package 文件夹company-any-artifact-any-module-1.0 后在`any-module/target/`下创建
  • 我不知道这是否有影响,但我尝试使用 java 版本 1.8.0_102 和 1.7.0_79。
  • 我更新了问题。当我们有一个子模块时会抛出一个StackOverflowError
【解决方案2】:

将 company-any-artifact 中的 pom.xml 更改为以下内容即可。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.company</groupId>
    <artifactId>any-artifact</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>${project.groupId}</name>


    <modules>
        <module>any-module</module>
    </modules>

    <!-- if remove finalName, maven will not throw StackOverflow error -->
    <build>
        <finalName>${project.groupId}-${project.version}</finalName>
    </build>
</project>

将子模块中的 pom.xml 更改为下面

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <artifactId>any-artifact</artifactId>
        <groupId>com.company</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <groupId>com.company.any-artifact</groupId>
    <artifactId>any-module</artifactId>
    <packaging>pom</packaging>  

  <!--   <name>${project.parent.name}-${project.artifactId}</name>  --> 

    <modules>
        <module>any-submodule</module>
    </modules>  
     <build>
        <finalName>${project.parent.name}-${project.artifactId}</finalName>
    </build> 
</project>

将子模块 pom.xml 更改为下面

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <artifactId>any-module</artifactId>
        <groupId>com.company.any-artifact</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <groupId>com.company.any-artifact.any-module</groupId>
    <artifactId>any-submodule</artifactId>
        <!-- <name>${project.parent.name}-${project.artifactId}-${project.version}</name>    -->
    <build>
        <finalName>company-${project.parent.name}-${project.artifactId}-${project.version}</finalName>
    </build>
</project>

那么输出是:company-any-module-any-submodule-1.0-SNAPSHOT

【讨论】:

  • 你现在能检查一下它的工作吗,似乎 name 和 finalname 都导致了问题,但是通过使用上面你得到了想要的结果,
  • 真的不行,有点机缘巧合。您有正确的输出,因为 any-module 的名称默认为其工件 ID。所以${project.parent.name}${project.parent.artifactId} 相同,并且按照in my answer 的解释工作。但是 OP 希望通过将最终名称放在最顶部的 POM 中来概括这一点,而这种方法在那里行不通。
  • 要查看问题,在层次结构中创建另一层 POM 父项目,它会开始失败...
  • 那么我认为问题出在 ${project.parent.name} 上,它只在下一个子模块中起作用,但如果你再往下一层,它就会开始失败。
【解决方案3】:

有趣!我开始克隆 repo 并重现错误。我将不胜感激任何可以从下面提到的帮助我调试问题的任何步骤中获得的线索 -

  1. Maven Life Cycle Phases 发生问题的阶段是生命周期的package 阶段。意思是 mvn package 重现了您的项目的问题。

  2. 查看错误中的堆栈跟踪行。了解它失败的表达式评估 -

    @Override
    public Object evaluate( String expr ) throws ExpressionEvaluationException {
        return evaluate( expr, null ); // Line 143
    }
    
  3. 这也不是导致它的 finalName 属性。由于指定相同的默认值 &lt;finalName&gt;${artifactId}-${version}&lt;/finalName&gt; 在相同的项目配置下工作正常。

  4. 然后尝试将any-submodule的包装更改为

    <packaging>pom</packaging>
    

    并且错误消失了。这意味着在包装为 jarwar 等时,表达式评估不同并导致溢出。

  5. 修改any-moduleany-submodule pom.xml 内容我可以肯定地说,是project.parent.name 在计算表达式时导致递归并导致堆栈溢出(如何? - 是@ 987654322@..)。另外,改变

    &lt;name&gt;${project.parent.name}-${project.artifactId}&lt;/name&gt;

    &lt;name&gt;${parent.name}-${project.artifactId}&lt;/name&gt;

    对我有用,因为我没有收到错误,但生成的 jar 是类型 -

    ${parent.name}-any-module-any-submodule-1.0-SNAPSHOT.jar

    ${parent.name}-any-submodule-1.0-SNAPSHOT分别跟换。

  6. 根据需求寻找解决方案,我正在寻找你正在使用的递归的尾巴。

注意 - 仍在努力寻找解决此问题的适当方法。

【讨论】:

    【解决方案4】:

    正如我在回复Difference between project.parent.name and parent.name ans use of finalName in pom.xml 时所说的

    我们先来看看基础知识:

    POM Reference中所述:

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

    名称:项目往往具有会话名称,超出 artifactId。

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

    • name 纯粹用于提供信息,主要用于生成文档和构建日志。它不会被继承,也不会在其他任何地方使用。它是人类可读的字符串,因此可以包含任何字符,即文件名中不允许的空格或字符。所以,这将是有效的:&lt;name&gt;My Turbo Project on Speed!&lt;/name&gt;。对于工件来说,这显然至少是一个有问题的文件名。

    • 如上所述,finalName 是生成的工件的名称。它继承的,所以它通常应该依赖于属性。仅有的两个真正有用的选项是默认的${artifactId}-${version} 和无版本的${artifactId}。其他一切都会导致混乱(例如一个名为foo 的项目创建了一个工件bar.jar)。实际上,我的涡轮增压计划!将是有效的,因为这是一个有效的文件名,但实际上,这样的文件名往往是相当不可用的(例如,尝试从 bash 中处理包含 ! 的文件名)


    那么,至于 Stackoverflow 发生的原因:

    • name 没有被继承
    • project.parent.name 也不会在插值期间进行评估,因为名称是少数对孩子完全不可见的属性之一
    • parent.name 实际上曾经在较旧的 Maven 版本中工作,但更多的是由于一个错误(也不推荐访问没有前导 project 的属性)。
    • 未对缺失的属性进行插值,即按原样保留在模型中
    • 因此,在 any-submodule 的有效 pom 中,finalName 的值仍然是(尝试使用 mvn help:effective-pom):${project.parent.name}-any-submodule

    到目前为止很糟糕。现在是 StackOverflow 的原因

    Maven 有一个称为后期插值的附加功能,可以在实际使用插件参数时评估它们的值。这允许 pluing 使用不属于模型的属性,但在生命周期的早期由插件生成(例如,这允许插件为最终名称提供 git 修订)。

    所以会发生这样的事情:

    编辑:使错误的实际原因更清楚(参见 cmets):

    • 评估 jar 插件的 finalName: @Parameter( defaultValue = "${project.build.finalName}", readonly = true )
    • PluginParameterExpressionEvaluator 启动并尝试评估最终名称 (${project.parent.name}-any-submodule,其中包含属性表达式 ${project.parent.name}。
    • 评估者询问模型,模型反过来返回父项目的名称,即:${project.parent.name}-any-module
    • 因此评估者尝试解决此问题,返回 ${project.parent.name}-any-module(再次),因为属性始终针对当前项目解决,循环再次开始。
    • 引发 StackOverflowError。

    如何解决这个问题

    很遗憾,你不能。

    您需要为每个项目明确指定name(以及artifactId)。没有解决方法。

    那么,你可以finalName依赖它。但是,我建议不要这样做(请参阅我对 Difference between project.parent.name and parent.name ans use of finalName in pom.xml 的回答)

    以这种方式更改最终名称的问题是本地构建工件的名称和存储库中的名称会不同,因此您的工件在本地命名为any-artifact-any-module-any-submodule.jar,但存储库中的工件名称仍为any-submodule.jar

    建议

    • 如果您真的需要区分这些细节,请改为更改 artifactId:&lt;artifactId&gt;artifact-anymodule-anysubmodule&lt;/artifactId&gt;
    • 不要在短名称中使用破折号来区分结构的级别。
    • 提示:模块的路径仍然可以是anymodule,不需要是模块的实际artifactId!
    • 当我们这样做的时候:使用 name 来实现它的目的,以便人类可读,因此您可能会考虑一些更具视觉吸引力的东西(因为这是出现在构建日志中的名称):&lt;name&gt;Artifact :: AnyModule :: AnySubModule&lt;/name&gt; .
    • 实际上很容易使用非常短的 groovy 脚本自动创建名称条目。
    • 您还可以编写一个强制规则来强制 artifactIds 的命名

    【讨论】:

    • 啊,我们同时写作。不过,stackoverflow 还有更多内容:核心问题不是project.parent 的使用,这可以正常工作,如没有子模块的 POM 的第二个项目所示。核心问题是有 2 个父级,以及PluginParameterExpressionEvaluator 工作的当前项目实例didn't change。 stackoverflow是因为submodule的父名也是它的父名。但由于当前用于评估表达式的 Maven 项目没有改变,它会循环。
    • @Tunaki 你说得对,当然这个具体细节还不够清楚。反正你的回答更详细了
    【解决方案5】:

    您的问题的严格答案是 ${project.parent.name}不会作为模型插值过程的一部分解决。反过来,您有一个 StackOverflowError,位于代码完全不同的位置,即当...构建项目的最终 JAR 时。

    第 1 部分:构建的模型错误

    这就是发生的事情。当您在项目上启动 Maven 命令时,它采取的第一个操作是创建项目的有效模型。这意味着读取您的 POM 文件、使用激活的配置文件进行推理、应用继承、对属性执行插值……所有这些都是为了为您的项目构建最终的 Maven 模型。这项工作由Maven Model Builder 组件完成。

    构建模型的过程相当复杂,很多步骤可能分为 2 个阶段,但我们感兴趣的部分在 model interpolation 部分。这是 Maven 将模型中所有由 ${...} 表示的标记替换为计算值的时候。它发生在注入配置文件并执行继承之后。在那个时间点,由MavenProject 对象表示的Maven 项目还不存在,只有它的Model 正在构建中。只有在您拥有完整的模型之后,您才能开始从中构建 Maven 项目。

    因此,当插值完成时,它仅根据 POM 文件中存在的信息进行推理,唯一有效的值是 mentioned in the model reference。 (如果您想查看源代码,此替换由 StringSearchModelInterpolator 类执行。)值得注意的是,您会注意到模型中的 &lt;parent&gt; 元素确实包含名称的父模型。 Maven 中的Model 类实际上是使用Modello 从源.mdo 文件生成的,并且该源仅为&lt;parent&gt; 元素定义groupId, artifactId, version and relativePath(以及自定义id)。这也是可见的in the documentation

    所有这些的后果是,在执行模型插值后,令牌${project.parent.name} 将不会被替换。此外,由它构造的MavenProject 将有一个未替换的包含${project.parent.name} 的名称。您可以在日志中看到这一点,在您的示例项目中,我们有

    [INFO] Reactor Build Order:
    [INFO] 
    [INFO] company-any-artifact
    [INFO] ${project.parent.name}-any-module
    [INFO] ${project.parent.name}-any-submodule
    

    意味着 Maven 将项目的实际名称 any-module 视为 ${project.parent.name}-any-module

    第 2 部分:诡异开始

    现在,反应堆中的所有项目都已正确创建甚至编译。实际上,理论上一切都应该正常工作,但项目本身的名称只是完全无聊的名称。但是你有一个奇怪的情况,它在使用maven-jar-plugin 创建 JAR 时失败。在您的示例中构建失败并显示以下日志:

    [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ any-submodule ---
    [INFO] ------------------------------------------------------------------------
    [INFO] Reactor Summary:
    [INFO] 
    [INFO] company-any-artifact ............................... SUCCESS [  0.171 s]
    [INFO] ${project.parent.name}-any-module .................. SUCCESS [  0.002 s]
    [INFO] ${project.parent.name}-any-submodule ............... FAILURE [  0.987 s]
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD FAILURE
    [INFO] ------------------------------------------------------------------------
    

    意味着在模型构建后出现了问题。而且原因是插件injects the name of the project as a parameter:

    
    /**
     * Name of the generated JAR.
     *
     * @parameter alias="jarName" expression="${jar.finalName}" default-value="${project.build.finalName}"
     * @required
     */
    private String finalName;
    

    注意 project.build.finalName 作为子模块生成的 JAR 名称的默认值。这种注入和变量的插值是由另一个名为 PluginParameterExpressionEvaluator 的类完成的。

    那么这会发生什么:

    • any-submodule 上的 JAR 插件注入了项目的最终名称,命名为 ${project.parent.name}-any-submodule
    • 感谢从父项目继承,以及在您最顶层的 POM 项目中声明 &lt;finalName&gt;,它继承了 &lt;finalName&gt;${project.name}-${project.version}&lt;/finalName&gt;
    • Maven 现在尝试将 ${project.name} 插入到 any-submodule
    • 由于第 1 部分,这将解析为 ${project.parent.name}-any-submodule
    • Maven 现在尝试将${project.parent.name} 插入any-submodule。这工作正常:MavenProject 已构建,getParent() 将在项目实例上调用,返回具体的 Maven 父项目。因此,${project.parent.name} 将尝试解析any-module 的名称,实际上是${project.parent.name}-any-module
    • Maven 现在尝试插入 ${project.parent.name}-any-module但仍在 any-submodule 项目实例上。对于 PluginParameterExpressionEvaluator,评估令牌的根 "project" 没有改变。
    • Maven 现在尝试在any-submodule 上插入${project.parent.name},这再次正常工作并返回${project.parent.name}-any-module
    • Maven 现在尝试在 any-submodule... 上插入 ${project.parent.name},这有效并返回 ${project.parent.name}-any-module,因此它尝试评估 ${project.parent.name}...

    你可以看到这里发生了无穷无尽的递归,这导致了你拥有的StackOverflowError。这是PluginParameterExpressionEvaluator 中的错误吗?这还不清楚:它的原因是模型值最初没有被正确替换。理论上,它可以处理评估${project.parent} 的特殊情况并创建一个新的PluginParameterExpressionEvaluator 处理这个父项目,而不是一直处理当前项目。如果您对此有强烈的感觉,请随时创建a JIRA issue

    第 3 部分:为什么它可以在没有子模块的情况下工作

    根据上面所说的,您现在可以推断为什么它在这种情况下有效。让我们来解释一下 Maven 需要做什么来评估最终名称,因为它必须被注入到 Maven Jar 插件中:

    • any-module 上的 JAR 插件注入了项目的最终名称,命名为 ${project.parent.name}-any-module
    • 感谢从父项目继承,以及在您最顶层的 POM 项目中声明 &lt;finalName&gt;,它继承了 &lt;finalName&gt;${project.name}-${project.version}&lt;/finalName&gt;
    • Maven 现在尝试将 ${project.name} 插入到 any-module
    • 这将解析为${project.parent.name}-any-module,与以前相同。
    • Maven 现在尝试将${project.parent.name} 插入any-module。就像以前一样,这可以正常工作:MavenProject 已构建,getParent() 将在项目实例上调用,返回具体的 Maven 父项目。因此,${project.parent.name} 将尝试解析 any-artifact 的名称,实际上是 company-any-artifact
    • 插值成功并停止。

    而且你没有任何错误。

    【讨论】:

    • 很好的解释。然而,我对建议的 Jira 问题有些分歧,因为所有属性都是以这种方式解决的,并且像 take 这样的更改可能会为非常“创造性”的用法打开大门。此外,即使解决了这个问题,模块的实际名称仍然是构建日志中奇怪的${project.parent.name}-any-module。我认为最好将其视为模型构建器早期的特殊情况(类似于project.url 的插值处理方式,但仅在明确请求时使用)。
    • @blackbuild 是的,我不确定解决这个问题的好方法是什么。 JIRA 问题将更多地真正跟踪这一点。在模型构建器级别,这会很好......我快速查看了代码,但这听起来像是一个不平凡的变化。
    • @blackbuild 另外,我想其他字段也可以这样做(如果名称取决于父描述或成立年份...?)。不确定这在低级别的模型构建器中是否真的可以解决。我仍然觉得 PluginParameterExpressionEvaluator 像这样失败有点奇怪,我们想要修复那个类,它看起来并不复杂:只需将 project.getParent() 传递给评估例程,以防表达式以 project.parent 开头。
    • 恕我直言,模型构建器应该意识到这个问题,并且在当前状态下至少抛出一个异常而不是创建一个“奇怪”的名称。除了已经在模型中的那些(artifactId、groupId、version、relativePath)和添加name,我会觉得禁止任何父访问是足够安全的,因为这有用例。恕我直言,其他父引用根本不应该被允许 - ModelInterpolation 也不能解决它,那么为什么插件参数评估的工作方式与正常机制不同呢?这只会导致更多的混乱。
    • @blackbuild 插件参数评估已经有点不同了,因为当模型插值只支持一个子集时,访问所有父参数实际上是有效的(好吧,除了这里的奇怪情况)。甚至日志中的名称也可以通过像插件参数一样评估project.getName() 来改进(尽管这感觉很奇怪)。但是,是的,它开始变成不好的做法,也许对父参数的访问应该严格限制在特定的参数中,即使在插件参数中也是如此......我会在 Maven 开发人员列表中提出这个问题,看看其他人的想法。
    猜你喜欢
    • 1970-01-01
    • 2023-03-08
    • 2015-11-05
    • 1970-01-01
    • 2013-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多