18

1. Background

My maven project has a lot of modules and submodules with jars and wars and everything works. I also can deploy it on server without any problem.

I decided to follow this maven naming conversion, I am making some tests with project.name and project.build.finalName to have an appropriate name.

The pattern I defined to create project.name for the root artifact is company-${project.artifactId} and for the modules and sub-modules is ${project.parent.name}-${project.artifactId}:

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

The pattern for project.build.finalName is ${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

But instead of producing these files, maven gives me a StackOverflowError.

2. The example to reproduce the error

You can clone this example from github: https://github.com/pauloleitemoreira/company-any-artifact

In github, there is the master branch, that will reproduce this error. And there is only-modules branch, that is a working example that uses ${project.parent.name} to generate the jar finalName as I want.

Let's consider a maven project with one root pom artifact, one pom module and one submodule.

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

2.1 any-artifact

<?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 any-module

<?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-submodule

<?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. Problem

When try to mvn clean install, maven gives me a 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)

It is important to know that the error occurs only when we are working with submodules. If we create a project with a root POM artifact and a jar module, the error don't occur.

4. The question

Why this error occurs only when we are using submodules?

Any suggestion to solve my problem? Should I forget it and set project.name and project.build.fileName manually for each project, following the pattern I want?

IMPORTANT UPDATED:

Some answers just say to use &{parent.name}, but it does not work. Please, it is a question with a bounty, consider test your solution with Maven version 3.3.9, before answering this question.

Maven version 3.3.9

Edit - Adding details to the question with the phase when the error occurs, things are working fine until the prepare-package phase, but the StackOverflow occurs at the package phase on maven lifecycle for the project.

Community
  • 1
  • 1
Paulo
  • 2,956
  • 3
  • 20
  • 30
  • where do you want .jar to be generated? – kuhajeyan Oct 31 '16 at 06:21
  • First if you try to generate war you have to change packaging to war instead furthermore remove the outputDirectory configuration cause it usually does not make sense. – khmarbaise Oct 31 '16 at 10:03
  • @khmarbaise I updated the question to avoid misunderstanding. – Paulo Oct 31 '16 at 13:07
  • what do you expect to see in ${project.parent.name}? – Peter Gelderbloem Nov 02 '16 at 09:37
  • Please check http://stackoverflow.com/a/26004524/2293534 – SkyWalker Nov 02 '16 at 10:32
  • `${parent.name}` doesn't work. – Paulo Nov 02 '16 at 11:46
  • @SkyWalker it doen't work – Paulo Nov 02 '16 at 11:51
  • What version of IntelliJ are you using? It will be helpful in order to reproduce the issue and test a solution. – M. Rizzo Nov 02 '16 at 16:13
  • @M.Rizzo where do you get the info that he'd be using IntelliJ? – eis Nov 02 '16 at 21:14
  • nice infinite loop :) don't you have some circular reference in placeholders between parent and child module ? – Gab Nov 02 '16 at 21:14
  • @M.Rizzo I updated the question and reproduce this error just using prompt. – Paulo Nov 02 '16 at 21:16
  • @eis I updated the question. Before, I was thinking it could be an IntelliJ error. But now I get that I was wrong and we can reproduce the error just using `mvn clean install` in prompt. – Paulo Nov 02 '16 at 21:18
  • @Gab It is weird, It seems like there is a circular reference in any place, I beleive it is not in my poms. Everything works fine when I use just a root artifact and a jar module. But the error occurs when I have an additional submodule. – Paulo Nov 02 '16 at 21:22
  • 1
    @Paolo I can reproduce the problem with stackoverflowerror, but even with finalName commented out, I can't reproduce the situation where this would ever work. It won't give an error, but it won't work as a name either. As parent name is not inherited, I don't see how this could have ever worked. – eis Nov 02 '16 at 21:33
  • @eis try to clean the project or check maven version. because I can make the project works when I comment our the `finalName`. – Paulo Nov 02 '16 at 21:42
  • @Paulo I have cleaned, and I'm using the latest version. Maven doesn't support inheriting the parent name, at least not in the project layout you have on github. – eis Nov 02 '16 at 21:44
  • [this](http://pastebin.com/raw/VMTRmdiJ) is what happens when removing finalName and then running, on Maven 3.3.9. – eis Nov 02 '16 at 21:47
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/127227/discussion-between-paulo-and-eis). – Paulo Nov 02 '16 at 21:48
  • 1
    Here are my 2 cents. There is no tag with in the tag.Take a look at the maven project descriptor http://maven.apache.org/ref/3-LATEST/maven-model/maven.html. so ${project.parent.name} is not a valid expression at all. The right fix is to include the literal value in the name tag in each project pom. Also the name are not inheritable. So I think what you;re trying to do is not even supported either way officially.. – s7vr Nov 03 '16 at 09:29
  • 2
    Here is the exact same scenario that has been closed as not a problem if that helps. https://issues.apache.org/jira/browse/MNG-5784. Once you change the name to unique in each file everything should just checkout okay & yes you can have the final build name the name you like provided you use valid expression. – s7vr Nov 03 '16 at 09:43
  • Stack overflow error that you see is a common error that will happen when you use an invalid expression that starts with the correct identifier 'project' or 'pom' as the model builder is trying to evaluate expression recursively only to run out of stack size. – s7vr Nov 03 '16 at 09:48

5 Answers5

10

The strict answer to your question is that ${project.parent.name} will not be resolved as part the model interpolation process. And in turn, you have a StackOverflowError, in a completely different place of the code, namely when... building the final JAR of your project.

Part 1: The Model built is wrong

Here's what happens. When you're launching a Maven command on a project, the first action it takes is creating the effective model of the project. This means reading your POM file, reasoning with activated profiles, applying inheritance, performing interpolation on properties... all of this to build the final Maven model for your project. This work is done by the Maven Model Builder component.

The process of building the model is quite complicated, with a lot of steps divided in possibly 2 phases, but the part we're interested in here in the model interpolation part. This is when Maven will replace in the model all tokens denoted by ${...} with a calculated value. It happens after profiles are injected, and inheritance is performed. At that point in time, the Maven project, as represented by a MavenProject object, doesn't exist yet, only its Model is being built. And it is only after you have a full model that you can start constructing the Maven project from it.

As such, when interpolation is done, it only reasons in terms of the information present in the POM file, and the only valid values are the ones mentioned in the model reference. (This replacement is performed by the StringSearchModelInterpolator class, if you want to look at the source code.) Quite notably, you will notice that the <parent> element in the model does not contain the name of the parent model. The class Model in Maven is actually generated with Modello from a source .mdo file, and that source only defines groupId, artifactId, version and relativePath (along with a custom id) for the <parent> element. This is also visible in the documentation.

The consequence of all that, is that after model interpolation is performed, the token ${project.parent.name} will not be replaced. And, further, the MavenProject constructed from it will have a name containing ${project.parent.name} unreplaced. You can see this in the logs, in your sample project, we have

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

Meaning that Maven consider the actual name of the project any-module to be ${project.parent.name}-any-module.

Part 2: The weirdness begins

We're now at a time when all of the projects in the reactor were correctly created and even compiled. Actually, everything should theoretically work just fine, but with only completely borked names for the projects themselves. But you have a strange case, where it fails at the creation of the JAR with the maven-jar-plugin. The build fails in your example with the following logs:

[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] ------------------------------------------------------------------------

meaning that something went wrong well after the model was built. And the reason is that the plugin 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;

Notice project.build.finalName as the default value of the generated JAR name for the submodule. This injection, and the interpolation of the variables are done by another class called PluginParameterExpressionEvaluator.

So what happens in this:

  • The JAR plugin on the any-submodule injects the final name of the project, named ${project.parent.name}-any-submodule.
  • Thanks for inheritance from the parent projects, and the declaration of <finalName> in your top-most POM project, it inherits <finalName>${project.name}-${project.version}</finalName>.
  • Maven now tries to interpolate ${project.name} for any-submodule.
  • This resolves to ${project.parent.name}-any-submodule, due to Part 1.
  • Maven tries now to interpolate ${project.parent.name} for any-submodule. This works correctly: the MavenProject is built and getParent() will be called on the project instance, returning the concrete Maven parent project. As such, ${project.parent.name} will try to resolve the name of any-module, which is actually ${project.parent.name}-any-module.
  • Maven now tries to interpolate ${project.parent.name}-any-module, but still on the any-submodule project instance. For PluginParameterExpressionEvaluator, the root "project" on which to evaluate tokens hasn't changed.
  • Maven now tries to interpolate ${project.parent.name} on any-submodule, which, again, works correctly and returns ${project.parent.name}-any-module.
  • Maven now tries to interpolate ${project.parent.name} on any-submodule... which works and returns ${project.parent.name}-any-module so it tries to evaluate ${project.parent.name}...

And you can see the endless recursion happening here, which results in the StackOverflowError you have. Is this a bug in PluginParameterExpressionEvaluator? This is unclear: it reasons on model values that were not correctly replaced in the first place. In theory, it could handle the special case of evaluating ${project.parent} and create a new PluginParameterExpressionEvaluator working on this parent project, instead of always working on the current project. If you feel strongly about this, feel free to create a JIRA issue.

Part 3: Why it works without the sub module

With what has been said above, you could now deduce why it works in this case. Let's reason with what Maven needs to do to evaluate the final name, as has to be injected in the Maven Jar Plugin:

  • The JAR plugin on the any-module injects the final name of the project, named ${project.parent.name}-any-module.
  • Thanks for inheritance from the parent project, and the declaration of <finalName> in your top-most POM project, it inherits <finalName>${project.name}-${project.version}</finalName>.
  • Maven now tries to interpolate ${project.name} for any-module.
  • This resolves to ${project.parent.name}-any-module, same as before.
  • Maven tries now to interpolate ${project.parent.name} for any-module. Just like before, this works correctly: the MavenProject is built and getParent() will be called on the project instance, returning the concrete Maven parent project. As such, ${project.parent.name} will try to resolve the name of any-artifact, which is actually company-any-artifact.
  • Interpolation has succeeded and stops.

And you don't have any errors.

Tunaki
  • 132,869
  • 46
  • 340
  • 423
  • Very good explaination. I am, however somewhat split about the suggested Jira-Issue, since all properties are resolved that way, and a change like take might open doors to very 'creative' usages. Also, even if that were solved, the actual name of the module would still be the weird `${project.parent.name}-any-module` in the build logs. I think it would be better to consider this as special case earlier in the ModelBuilder (similar to how interpolation of `project.url` is handled, but only used if requested explicitly). – blackbuild Nov 08 '16 at 10:31
  • @blackbuild Yeah I'm not sure what would be the good way to solve this. The JIRA issue would be more to track this really. At the Model Builder level, it would be nice... I took a quick look at the code and it sounds like a non-trivial change though. – Tunaki Nov 08 '16 at 11:00
  • @blackbuild Also, I suppose the same could be done for other fields (what if the name depends on the parent description or inception year...?). Not sure this is really solvable at the model builder which is low level. I still find a bit weird that `PluginParameterExpressionEvaluator` fails like this, and it we want to fix that class, it doesn't look very complicated: just pass `project.getParent()` to the evaluation routine in case the expression starts with `project.parent`. – Tunaki Nov 08 '16 at 11:36
  • IMHO the ModelBuilder should be aware of this issue and in the current state at least throw an Exception instead of creating a 'weird' name. I would feel safe enough to disallow any parent access except the ones already in the model (artifactId, groupId, version, relativePath) and the addition of `name`, since this has usecases. Other parent references should IMHO not be allowed at all - ModelInterpolation does not resolve it either, so why should Plugin param evaluation work differently that the normal mechanism? This would only lead to more confusion. – blackbuild Nov 08 '16 at 12:15
  • @blackbuild Plugin param evaluation is already a bit different since accessing all of the parent params actually work (well, except the weird case here), when only a subset are supported in model interpolation. Even the name in the logs could possibly be improved by evaluating `project.getName()` like a plugin param (although that feels weird). But, yes, it starts to become not good practice, maybe access to parent parameters should be strictly restricted to specific ones, even in plugin params... I'll raise the issue on the Maven dev list and see others people thought. – Tunaki Nov 08 '16 at 12:42
4

As I stated in my answer to Difference between project.parent.name and parent.name ans use of finalName in pom.xml

Let's first look at the basics:

as stated in POM Reference:

finalName: This is the name of the bundled project when it is finally built (sans the file extension, for example: my-project-1.0.jar). It defaults to ${artifactId}-${version}.

name: Projects tend to have conversational names, beyond the artifactId.

So these two have different uses.

  • name is purely informational and mainly used for generated documentation and in the build logs. It is not inherited nor used anywhere else. It is a human readable String and can thus contain any character, i.e. spaces or characters not allowed in filenames. So, this would be valid: <name>My Turbo Project on Speed!</name>. Which is clearly at least a questionable file name for an artifact.

  • as stated above, finalName is the name of the generated artifact. It is inherited, so it should usually rely on properties. The only two really useful options are the default ${artifactId}-${version} and the versionless ${artifactId}. Everything else leads to confusion (such as a project named foo creating an artifact bar.jar). Actually, My turbo Project! would be valid, since this is a valid filename, but in reality, filenames like that tend to be rather unusable (try adressing a filename containing ! from a bash, for example)


So, as to why the Stackoverflow happens:

  • name is not inherited
  • project.parent.name also is not evaluated during interpolation, since the name is one of the few properties which are completey invisible to the children
  • parent.name actually used to work in older Maven versions, but more due to a bug (also it is deprecated to access properties without the leading project).
  • a missing property is not interpolated, i.e. stays in the model as is
  • Therefore, in your effective pom for any-submodule, the value for finalName is (try it with mvn help:effective-pom) still: ${project.parent.name}-any-submodule

So far so bad. Now comes the reason for the StackOverflow

Maven has an addtional feature called late interpolation that evaluates values in plugin parameters when they are actually used. This allows a pluing to use properties that are not part of the model, but are generated by plugins earlier in the lifecycle (this allows, for instance plugins to contribute a git revision to the final name).

So what happens is this:

edit: made the actual reason for the error clearer (see comments):

  • The finalName for the jar plugin is evaluated: @Parameter( defaultValue = "${project.build.finalName}", readonly = true )
  • The PluginParameterExpressionEvaluator kicks in and tries to evaluate the final name (${project.parent.name}-any-submodule, which contains a property expression ${project.parent.name}.
  • The evaluator asks the model, which in turn returns the name of the parent project, which is: ${project.parent.name}-any-module.
  • So the evaluator tries to resolve this, which return ${project.parent.name}-any-module (again), since a property is always resolved against the current project, the cycle begins again.
  • A StackOverflowError is thrown.

How to solve this

Sadly, you can't.

You need to explicitly specify name (as well as artifactId) for every project. There is no workaround.

Then, you could let finalName rely on it. I would however advise against it (see my answer to Difference between project.parent.name and parent.name ans use of finalName in pom.xml)

The problem in changing the final name that way is that the name of the locally build artifact and the one in the repository would differ, so locally your artifact is named any-artifact-any-module-any-submodule.jar, but the artifact name in your repository would be still any-submodule.jar

Suggestion

  • If you really need to differentiate that fine, change the artifactId instead: <artifactId>artifact-anymodule-anysubmodule</artifactId>.
  • Don't use dashes for the shortname to differentiate between levels of your structure.
  • hint: the path of the module can be still anymodule, is does not need to be the actual artifactId of the module!
  • While we are at it: use the name for what it was intended, to be human readable, so you might consider something more visually appealling (since this is the name that appears in the build log): <name>Artifact :: AnyModule :: AnySubModule</name>.
  • It is actually very easy to simply create the name entries automatically using a very short groovy script.
  • You could also write an enforce rule to enforce the naming of the artifactIds
Community
  • 1
  • 1
blackbuild
  • 5,026
  • 1
  • 23
  • 35
  • Ah, we were writing at the same time. There's a bit more to the stackoverflow though: the core issue isn't the use of `project.parent`, this works fine, as demonstrated in the second project of the POM without submodules. The core issue is that there are 2 parents, and the current project instance on which the `PluginParameterExpressionEvaluator` works [didn't change](http://stackoverflow.com/a/40483587/1743880). The stackoverflow is because the parent name of `submodule`, is also its parent name. But since the current Maven project on which to evaluate expressions hasn't changed, it loops. – Tunaki Nov 08 '16 at 09:59
  • @Tunaki You are right, of course, this specific detail is not clear enough. Your answer is more detailed, anyway – blackbuild Nov 08 '16 at 10:15
2

This is issue with attribute inheritance.
Try to use ${parent.name} instead of ${project.parent.name}.
Look at: Project name declared in parent POM isn't expanded in a module filtered web.xml.

---UPDATE---

Benjamin Bentmann (maven committier) said: "In general though, expressions of the form ${project.parent.*} are a bad practice as they rely on a certain build state and do not generally work throughout the POM, giving rise to surprises".

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

Maybe you should consider is using ${project.parent.*} is a good way.

Community
  • 1
  • 1
Javoslaw
  • 357
  • 2
  • 6
  • It doesn't work. My down voting is because it does not solve my problem. Actually, it worsens the problem. With your approach the final name changes from company-any-artifact-any-module-1.0.war to ${parent.name}-any-module-1.0.war. – Paulo Nov 02 '16 at 11:19
  • Please, consider to test your solution with `Maven version 3.3.9` before answering. – Paulo Nov 02 '16 at 11:47
  • I tried your example with `${project.parent.name}` but for me it works fine on mvn version 3.3.9. After invoked `mvn package` folder `company-any-artifact-any-module-1.0` was created under ` any-module/target/` – Javoslaw Nov 02 '16 at 14:58
  • I don't know if this has impact but I tried with java version 1.8.0_102 and 1.7.0_79. – Javoslaw Nov 02 '16 at 15:03
  • I updated the question. A `StackOverflowError` is thrown when we have a submodule. – Paulo Nov 02 '16 at 17:30
  • Your solution (`parent.name` instead of `project.parent.name`) would use deprecated access, and does not work on newer versions, anyway. However, your update contains a very important hint. – blackbuild Nov 08 '16 at 10:42
-1

change pom.xml in company-any-artifact to below and it will work .

<?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>

change pom.xml in submodule to below

<?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>

change submodule pom.xml to below

<?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>

then the output was : company-any-module-any-submodule-1.0-SNAPSHOT

gladiator
  • 1,249
  • 8
  • 23
  • Can u check now its working ,seems having name and finalname both causing issue but by using above you get desired result, – gladiator Nov 08 '16 at 09:16
  • It doesn't really work, a bit of chance. You have the correct output because the name of `any-module` default to its artifact id. So `${project.parent.name}` is the same as `${project.parent.artifactId}` and that works as explained [in my answer](http://stackoverflow.com/a/40483587/1743880). But the OP wants to generalize this by putting the final name in the top most POM, and this approach won't work there. – Tunaki Nov 08 '16 at 12:19
  • To see the issue, create another layer of POM parent project in the hierarchy, and it'll start failing... – Tunaki Nov 08 '16 at 12:32
  • then i think issue is with ${project.parent.name} which works in just the next sub-module but if you go one more level down it starts failing . – gladiator Nov 09 '16 at 06:29
-2

Interesting! I started off cloning the repo and reproducing the error. I would appreciate any leads that can be taken from any of the steps mentioned below that helped me debug the problem -

  1. Maven Life Cycle Phases The phase where the issue occurred was the package phase of the lifecycle. Meaning mvn package reproduces the issue with your project.

  2. Went through the stack trace lines in the error. Getting to know its the expression evaluation where it's failing -

    @Override
    public Object evaluate( String expr ) throws ExpressionEvaluationException {
        return evaluate( expr, null ); // Line 143
    }
    
  3. It's also not the finalName attribute which was causing it. Since specifying the default value of the same <finalName>${artifactId}-${version}</finalName> works fine with the same project configs.

  4. Then tried changing the packaging of the any-submodule as

    <packaging>pom</packaging>
    

    and the error went away. Meaning while packaging as jar , war etc the expression evaluation is different and results in an overflow.

  5. Modifying the any-module or the any-submodule pom.xml content I can say with some confidence that it's the project.parent.name that is causing a recursion in evaluating the expression and causing the stack overflow(How? - is something I am still looking for..). Also, changing

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

    to

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

    works for me in the sense that I do not get an error but the jar generated is of type -

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

    ${parent.name}-any-submodule-1.0-SNAPSHOT respectively with the change.

  6. Looking for the solution according to the requirement, I am seeking a tail to the recursion that you are using.

Note - Still working on finding an appropriate solution to this problem.

Community
  • 1
  • 1
Naman
  • 27,789
  • 26
  • 218
  • 353