I am going to create a multi-module archetype. It will generate several modules. Some users of the archetype may need all of them, while some only need some of them.
Can my archetype take arguments from the command line and decide which modules to generate? I checked https://maven.apache.org/archetype/archetype-models/archetype-descriptor/archetype-descriptor.html and it doesn't seem to support that.
Why Multi-Module Project? One single command is required to build all projects, including the submodules. Maven always cares about the build order for you. You don't need to worry about that.
A multi-module project is built from an aggregator POM that manages a group of submodules. In most cases, the aggregator is located in the project's root directory and must have packaging of type pom. The submodules are regular Maven projects, and they can be built separately or through the aggregator POM.
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.
Some of the common Maven archetypes are as follows: maven-archetype-quickstart – Can be used to create a basic Maven project. maven-archetype-j2ee-simple – Can be used to create a simple j2ee project. maven-archetype-webapp – Can be used to create a web application.
In this specific case, the archetype could always create all the required modules and move the different flavors (set of modules) into profiles. Only one profile will be active by default as specified during the archetype:generate
step.
As such, if I want to have the set of modules for flavorA, I will run the archetype as
mvn archetype:generate -DarchetypeGroupId=.. -DflavorA=true
And the archetype will pass this variable to the activeByDefault
element of the flavorA profile re-defining the modules
element for the set of modules required by the flavorA users.
The same could be done for flavorB and flavorB (for example), each defining a different set of modules.
An example of such an aggregator/parent POM as part of the archetype would be:
<profiles>
<profile>
<id>flavourA</id>
<activation>
<activeByDefault>${flavourA}</activeByDefault>
</activation>
<modules>
<module>profiled-module2</module>
<module>profiled-module3</module>
</modules>
</profile>
<profile>
<id>flavourB</id>
<activation>
<activeByDefault>${flavourB}</activeByDefault>
</activation>
<modules>
<module>profiled-module3</module>
</modules>
</profile>
<profile>
<id>flavourC</id>
<activation>
<activeByDefault>${flavourC}</activeByDefault>
</activation>
<modules>
<module>profiles-module1</module>
<module>profiled-module2</module>
<module>profiled-module3</module>
</modules>
</profile>
</profiles>
The archetype-metadata.xml
file could then specify:
<requiredProperties>
<requiredProperty key="flavourA">
<defaultValue>false</defaultValue>
</requiredProperty>
<requiredProperty key="flavourB">
<defaultValue>false</defaultValue>
</requiredProperty>
<requiredProperty key="flavourC">
<defaultValue>false</defaultValue>
</requiredProperty>
</requiredProperties>
And the archetype invoked with the -DflavorB=true
option would then generate a pom as following:
<profiles>
<profile>
<id>flavourA</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<modules>
<module>profiled-module2</module>
<module>profiled-module3</module>
</modules>
</profile>
<profile>
<id>flavourB</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>profiled-module3</module>
</modules>
</profile>
<profile>
<id>flavourC</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<modules>
<module>profiles-module1</module>
<module>profiled-module2</module>
<module>profiled-module3</module>
</modules>
</profile>
</profiles>
Such an approach has the following advantages and disadvantages:
Advantages
Disadvantages
Moreover, on top of the approach above, we could also configure the Maven Clean Plugin in each profile to delete the modules not concerned by its flavor, so that at its first build (a maven clean
), any non required module would be deleted. Such an approach would leave the POM with inconsistent profiles though, but it might be considered as well (not recommended).
Something like:
<profile>
<id>flavourA</id>
<activation>
<activeByDefault>${flavorA}</activeByDefault>
</activation>
<modules>
<module>profiled-module2</module>
<module>profiled-module3</module>
</modules>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<filesets>
<fileset>
<directory>${basedir}/profiled-module1</directory>
</fileset>
</filesets>
</configuration>
</plugin>
</plugins>
</build>
</profile>
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