1.背景
我的Maven项目中有很多模块和子模块,jars
并且wars
和一切正常。我也可以毫无问题地将其部署在服务器上。
我决定遵循此Maven命名转换,我正在进行一些测试,project.name
并project.build.finalName
使用一个适当的名称。
我project.name
为根工件定义的模式是,company-${project.artifactId}
以及为模块和子模块创建的模式是${project.parent.name}-${project.artifactId}
:
的模式project.build.finalName
是${project.name}-${project.version}
:
但是maven不会产生这些文件,而是给我一个StackOverflowError
。
2.重现该错误的示例
您可以从github克隆此示例:https : //github.com/pauloleitemoreira/company-any-
artifact
在github中,有一个master
分支将重现此错误。有only- modules
分支,这是一个工作示例,用于${project.parent.name}
根据需要生成jar finalName
。
让我们考虑一个具有一个root 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 any-子模块
<?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.name
并project.build.fileName
按照我想要的模式为每个项目手动设置和设置?
重要更新:
有些答案只是说要使用 &{parent.name}
,但这 是行不通的 。请,这是一个悬而未决的问题Maven version 3.3.9
,请在回答此问题之前考虑使用来测试您的解决方案。
Maven版本3.3.9
编辑 -发生错误时,在阶段中向问题中添加详细信息,直到该prepare- package
阶段为止一切工作都很好,但是StackOverflow发生在package
项目的maven生命周期中的阶段。
严格回答你的问题是,${project.parent.name}
会 不会
被解析为部分型号插值处理。反过来,您StackOverflowError
在代码的完全不同的位置有一个,即何时…构建项目的最终JAR。
这是发生了什么。在项目上启动Maven命令时,它要执行的第一步是创建项目的有效模型。这意味着读取您的POM文件,使用激活的配置文件进行推理,应用继承,对属性进行插值…所有这些都为您的项目构建了最终的Maven模型。这项工作由Maven
Model Builder
组件完成。
建立模型的过程非常复杂,许多步骤可能分为两个阶段,但是我们在模型插值部分对此感兴趣。这是Maven在模型${...}
中用计算值替换所有标记所用的时间。它在注入配置文件并执行继承之后发生。在那个时候,以MavenProject
对象表示的Maven项目还不存在,只有它Model
正在构建中。只有拥有完整的模型之后,您才能开始从中构建Maven项目。
这样,完成插值时,仅根据POM文件中存在的信息进行解释,唯一有效的值是模型参考中提到的值。(StringSearchModelInterpolator
如果要查看源代码,则由类执行此替换。)值得注意的是,您会注意到<parent>
模型中的元素
不 包含父模型的名称。类Model
Maven中实际上是与生成MODELLO从源.mdo
文件,和其源仅定义groupId
,artifactId
,version
和relativePath
(连同定制id
)的<parent>
元件。这在文档中也可见。
所有这些的结果是,在执行模型插值后,${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
。
现在,我们已经正确地创建甚至编译了反应堆中的所有项目。实际上,理论上所有内容都可以正常工作,但项目本身的名称完全令人讨厌。但是,您遇到了一个奇怪的情况,在使用创建JAR时,它失败了maven- jar-plugin
。在您的示例中,构建失败并显示以下日志:
[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] ------------------------------------------------------------------------
表示在建立模型后出现了一些问题。原因是该插件将项目名称作为参数注入:
/** * 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
注入了项目的最终名称,名为${project.parent.name}-any-submodule
。<finalName>
最顶层的POM项目中声明,它继承了<finalName>${project.name}-${project.version}</finalName>
。${project.name}
的any-submodule
。${project.parent.name}-any-submodule
由于第1部分,因此解决为。${project.parent.name}
的any-submodule
。这可以正常工作:MavenProject
已构建并将getParent()
在项目实例上调用,返回具体的Maven父项目。因此,${project.parent.name}
将尝试解析的名称any-module
,实际上是${project.parent.name}-any-module
。${project.parent.name}-any-module
, 但仍在any-submodule
项目实例上。对于PluginParameterExpressionEvaluator
,"project"
评估令牌的根没有改变。${project.parent.name}
上进行插值any-submodule
,该插值再次可以正常工作并返回${project.parent.name}-any-module
。${project.parent.name}
在any-submodule
…上进行插值,该方法可以工作并返回,${project.parent.name}-any-module
因此它尝试评估${project.parent.name}
…您会看到这里发生了无尽的递归,从而导致了StackOverflowError
您的拥有。这是错误PluginParameterExpressionEvaluator
吗?尚不清楚:这是因为最初没有正确替换的模型值。从理论上讲,它可以处理评估的特殊情况${project.parent}
并PluginParameterExpressionEvaluator
在此父项目上创建新工作,而不是始终在当前项目上工作。如果对此有强烈的想法,请随时创建JIRA问题。
通过上面所说的,您现在可以推断出在这种情况下它为什么起作用了。让我们来解释一下Maven需要做什么来评估最终名称,就像必须注入Maven Jar插件中一样:
any-module
注入了项目的最终名称,名为${project.parent.name}-any-module
。<finalName>
最顶层的POM项目中声明,它继承了<finalName>${project.name}-${project.version}</finalName>
。${project.name}
的any-module
。${project.parent.name}-any-module
,和以前一样。${project.parent.name}
的any-module
。像以前一样,它可以正常工作:生成了MavenProject
,getParent()
并将在项目实例上调用,返回具体的Maven父项目。因此,${project.parent.name}
将尝试解析的名称any-artifact
,实际上是company-any-artifact
。而且您没有任何错误。
问题内容: 我有一个数据库表 mytable ,它的列 名称 为Varchar格式,列 日期 为Datetime值。我想用按日期分组的某些参数来计算名称。这是我的工作: 似乎这里的范围语法有问题,如果我这样做的话,它确实可以正确计数以’a’开头的所有字段。但是,上面的查询为n返回0,尽管应该计算包含至少一个字母的所有字段。 问题答案: 你写: 似乎这里的范围语法有问题 的确如此。MySQL的LIK
问题内容: 最近,我开始在Node.js上将MongoDB与Mongoose结合使用。 当我将Model.find方法与条件和字段一起使用时,猫鼬无法正常工作。 这不起作用: 顺便说一句,如果我删除了’_id’部分,这确实可行! 在MongoDB Shell中,两者都可以正常工作。 问题答案: 我通过谷歌搜索解决了这个问题:
问题内容: 我每天都使用TimedRotatingFileHandler记录Django日志并轮换使用,但是检查日志文件,奇怪的问题是昨天的日志被截断了,今天的日志很少,昨天的日志丢失了! Django 1.4 uwsgi 1.4.9 Python 2.6 我从uwsgi开始8个django实例。setting.py是 我错过了什么?为什么旧的日志丢失了? 问题答案: 您不应该同时从多个进程登录到
问题内容: 我正在尝试使用node-imagemagick库调整图像的大小,但无法正常工作。 我用来调整大小的代码是 引发错误 问题答案: 在Windows上,您还需要安装imagemagick exe。nodejs imagemagick库只是imagemagick exe的包装器。因此,只有安装了imagemagick exe并转换并标识可执行文件在路径中后,它才能起作用。
问题内容: 我正在尝试使AspectJ编织工作在一个简单的Maven项目中,并且不确定它出了什么问题:当我使用“ mvn exec:java”运行代码时,看不到预期的输出。 我确定代码可以正常工作,因为我在STS中尝试了相同的方法,在这里工作良好。我只是想让AspectJ在Maven项目中工作。 任何有关如何调试此类问题的提示将不胜感激。 外观文件与代码位于同一文件夹中: Java文件: 问题答案
问题内容: 这个问题已经在这里有了答案 : 字符串替换方法不替换字符 (5个答案) 2年前关闭。 我正在尝试将所有特殊字符替换为“%”,例如: 我的正则表达式是: 在在线工具中*它可以正常运行,但在Java中 弦保持不变。 *我尝试过:http : //www.regexplanet.com/ http://regex101.com/和其他 问题答案: 字符串是不可变的。您忘了将新变量重新分配给: