1. Background
My maven project has a lot of modules and submodules with jars
and wars
and everything works. I also can dep
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:
. 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 inheritedproject.parent.name
also is not evaluated during interpolation, since the name is one of the few properties which are completey invisible to the childrenparent.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
).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):
@Parameter( defaultValue = "${project.build.finalName}", readonly = true )
PluginParameterExpressionEvaluator
kicks in and tries to evaluate the final name (${project.parent.name}-any-submodule
, which contains a property expression ${project.parent.name}.${project.parent.name}-any-module
.${project.parent.name}-any-module
(again), since a property is always resolved against the current project, the cycle begins again.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
artifact-anymodule-anysubmodule
.anymodule
, is does not need to be the actual artifactId of the module!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): Artifact :: AnyModule :: AnySubModule
.