Time for a real first post. Recently, I’ve been working on creating a Maven archetype for a certain open-source project, and discovered to my delight that archetypes actually support a limited kind of logic. If it’s not immediately obvious why that would be useful, consider that you can make use of this logic to, for example, optionally add a dependency based on a custom parameter.
Making use of the fact that Maven builds its archetypes using Apache’s
Velocity template engine, you can embed
statements reminiscent of C-style preprocessor directives in any file in the
archetype. To add an optional dependency, try embedding the logic below in the
pom.xml
file
<dependencies>
...
#if (${includeNetty} == 'true' || ${includeNetty} == 'yes' || ${includeNetty} == 'y')
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty</artifactId>
<version>3.4.6.Final</version>
<scope>compile</scope>
</dependency>
#end
</dependencies>
This will work provided, of course, that you’ve defined includeNetty
like so
in your archetype-metadata.xml
file.
<requiredProperties>
<requiredProperty key="includeNetty">
<defaultValue>false</defaultValue>
</requiredProperty>
</requiredProperties>
The above snippet becomes
<dependencies>
...
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty</artifactId>
<version>3.4.6.Final</version>
<scope>compile</scope>
</dependency>
</dependencies>
when -DincludeNetty
is set to true
(or yes
, or y
, in keeping with
Maven-style commands), and
<dependencies>
...
</dependencies>
when it is false (or, really, anything but true
, yes
, or y
).
Unfortunately, this trick doesn’t work to optionally include whole files –
there isn’t currently a way to do that at all in Maven,
although the feature has been suggested.
Avoid leading whitespace
Just a tip: when embedding these preprocessing commands, don’t put any
whitespace before the #
character, otherwise it will be included in the
output. This snippet
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<currentYear>2013</currentYear>
#if (${includeNetty} == "true")
<nettyVersion>3.4.6.Final</nettyVersion>
#end
<properties>
harmless though it looks, will actually output
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<currentYear>2013</currentYear>
<nettyVersion>3.4.6.Final</nettyVersion>
<properties>
due to the leading whitespace, which can be extremely annoying if you actually
care about nicely formatted pom.xml
files.