Suppose I have set groupId
to com.example
, and artifactId
to fancy.project
, and now I want to create a archetype, such that when created, expands into the following structure:
|--src
|--main
|--com
|--example
|-fancy
|-project
|-App.java
That is, I wonder how to expand a variable into a nested directory.
I understand that the dual-underscore-wrapped variables will be substituted in file/directory names, but I can only get the following with __groupId__
.
|--src
|--main
|--com.example
|-fancy.project
|-App.java
As input to the archetype you can specify the
package
option (which would then follow your input, the groupId and artifactId concatenation if you want, even though it is not always the case and hence provide even more flexibility).Then, in your archetype you can use the
packageInPathFormat
option (available since archetype 2.2) which would replace any dot.
into slash\
and as such transforming it to a path into the generated project.However, the option is not officially documented (pity) even though supported and works fine for such a scenario.
Looking at the code, the
DefaultFilesetArchetypeGenerator
and itsgetPackageInPathFormat
provide the concerned transformation from thepackage
option to a path, while the org.apache.maven.archetype.common.Constants.PACKAGE_IN_PATH_FORMAT is the official entry point for this option.Some externals pointers on the usage of this option:
To further explain:
__packageInPathFormat__
folder under your src/main/java, for example__packageInPathFormat
would then be replaced by thepackage
option transforming dots into slashespackage
option has a default value togroupId
, so if you don't specify it, for agroupId
with valuecom.sample
, the path would becom/sample
-Dpackage=your.package
repeating the values for-DgroupId
and-DartifactId
(a bit verbose and error prone though), the final result will actually be what you expected (transformed to correct path).You can specify new default values via a
archetype-metada.xml
file, as specified in the official documentation, via therequiredProperties
section, you could have something like:However, the generated path would then be
com.sample/artifactid
rather thancom/sample/artifactid
. Hence it would not work as expected due to the processing workflow which would replace the placeholders after transforming it to a path (pity!).(Note: it would transform the dot we provided as configured value, but would then not transform dots into the replaced placeholders).
As of a quick code analysis, seems like the
DefaultFilesetArchetypeGenerator
class in itsgenerateArchetype
method is preparing the context too early (in itsprepareVelocityContext
method, where thepackageInPathFormat
is transformed and added to the context), then the context is passed toprocessArchetypeTemplate*
methods which would eventually invoke the Velocity engine (which is going to replace placeholders then). I am not a Velocity expert though, hence I may miss some glue, but the observed behavior and the code workflow seem to lead to this conclusion.