Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change package property in Maven Archetype

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?

like image 985
wvdz Avatar asked Aug 22 '16 13:08

wvdz


People also ask

Is Maven and Maven archetype same?

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.

Which Maven plugin is used for archetype generation?

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.

Where are Maven archetypes stored?

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.


1 Answers

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 the package 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.

like image 81
A_Di-Matteo Avatar answered Oct 02 '22 21:10

A_Di-Matteo