I created a Maven Archetype. My META-INF/maven/archetype-metadata.xml
looks like this:
<archetype-descriptor xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd">
<fileSets>
<fileSet filtered="true" packaged="true" encoding="UTF-8" >
<directory>src/main/java</directory>
</fileSet>
</fileSets>
</archetype-descriptor>
This works, as in that it creates a Java source folder and puts my classes in the package as defined by the groupId
and the artifactId
.
However, I want to modify his package name. For example, if my groupId is com.example
and my artifactId wvdz
, then my package should be:
com.example.wvdz.mypackage
Question: How do I accomplish this?
In short, Archetype is a Maven project templating toolkit. An archetype is defined as an original pattern or model from which all other things of the same kind are made. The name fits as we are trying to provide a system that provides a consistent means of generating Maven projects.
The Archetype Plugin allows the user to create a Maven project from an existing template called an archetype. It also allows the user to create an archetype from an existing project. This plugin requires Java 7.
The metadata about an archetype is stored in the archetype-metadata. xml file located in the directory META-INF/maven of its JAR file, see the reference documentation. The metadata file stores the additional properties, with corresponding default values. It also stores the project's generated files in filesets.
To accomplish your objectives and since you are already using the packaged
attribute to true
(explained later), you can simply add directories to your path below.
Keeping the same configuration, with an additional include
element as following:
<fileSets>
<fileSet filtered="true" packaged="true" encoding="UTF-8" >
<directory>src/main/java</directory>
<includes>
<include>**/*.java</include>
</includes>
</fileSet>
</fileSets>
You could then place under src/main/java/mypackage
your Java sources templated where the package statement would be as following:
package ${package}.mypackage
Note the .mypackage
reflects exactly the mypackage
folder directly under src/main/java
. However, when creating the archetype, Maven will then place as a folder (and as such as a package) in between the ${package} property value, which by default would be the ${groupId}.
You can always pass the -Dpackage
property and override it the default value (the groupId
), which will then be used as a prefix of the package, based on the template above.
This happens because of the packaged
attribute set to true
in the fileSet
section above. In this case true
means: add to it the folder hierarchy specified by the ${package}
property. Setting it at false
would result in ${package}
ignored, which can be used if you really want to hard-code the folder structure and obviously reflect it in to the package
statement of your Java code, for consistency.
The behavior above is documented in the official How is metadata about an archetype stored?:
the archetype defines a single fileset:
- the fileset will take all the files in
archetype-resources/src/main/java
that match the**/*.java
pattern- the selected files will be generated using the Velocity engine (
filtered=true
)- the files will be generated in the
src/main/java
directory of the generated project in the same directory as in the JAR file, but with that directory prepended by thepackage
property.
And also:
Filesets can be
packaged
, which means the selected files will be generated/copied in a directory structure that is prepended by the package property. They can be non-packaged, which means that the selected files will be generated/copied without that prepend.
The same details (about the packaged
property) can also be found in the official Archetype Descriptor Model.
Another possible solution is to use an additional property or define your package
property value directly in the archetype-metadata.xml
file as following:
<archetype-descriptor
xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd">
<fileSets>
<fileSet filtered="true" packaged="true" encoding="UTF-8">
<directory>src/main/java</directory>
</fileSet>
</fileSets>
<requiredProperties>
<requiredProperty key="package">
<defaultValue>${groupId}.${artifactId}.mypackage</defaultValue>
</requiredProperty>
</requiredProperties>
</archetype-descriptor>
Note the new requiredProperties
section: here we are setting the default value for the package
property, no need to provide it at runtime anymore (yet possible to override the value above though).
As such, the Java source template under src/main/java
(no need for further static folders) would simply be:
package ${package}
During the creation (archetype:generate
) Maven will then use the com.sample.something.mypackage
as package value (in the Java source file) and populate the packageInPathFormat
property with the value com/sample/something/mypackage
(the same property, but in path format) and create the desired package hierarchy, consistent with what the Java source code would expect to be placed in.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With