Two days ago I did some internal research in order to understand how do resolved properties propagate from Maven to Ant via maven-antrun-plugin
. On my way I had to recall several rarely remembered facts and learn some new ones. The implications of their combination leads to pretty interesting results that are worth writing them down. At least, now I’ll know where to look for this information next time.
Fact #1
There are multiple sources for properties resolution in Maven – implicit project properties (like project.version), environment variables, user-defined properties (ones you use in properties
tag or your pom.xml
), Java system properties… The full list with detailed explanations is available in The Complete Reference online book.
Pay attention – when you “override” some user-defined property via command line parameter (-D
), in fact you are setting a new Java system property. This works because system properties have higher precedence during properties resolution process.
Fact #2
All properties that are explicitly used in pom.xml
are resolved before Maven lifecycle actually starts, even before the initialize phase. It happens when so-called “effective pom” (full project definition, including all implicit data and configuration settings propagated from parent project) is generated. BTW, you can see this in action by call mvn help:effective-pom
on your project.
Implication #1
Modifications of project properties that happen during project lifecycle have no effect on the effective pom – it is just too late. Examples of such modifications include groovy scripts (via gmaven-plugin) and properties loaded from external files via maven-properties-plugin. So, why do we need them at all? Since they can be used by other plugins in runtime, when they are read directly from properties collection during plugin invocation.
Fact #3
The maven-antrun-plugin
supports both execution of inline Ant scripts and invocation of external build file (via Ant task). For inline scripts, regular property resolution rules apply. For external script, it becomes more complicated. It appears that only subset of Maven properties propagates to the external Ant execution. Specifically, the plugin provides access to the user-defined properties and to the prefixed versions of implicit project properties (for example, project.version
becomes maven.project.version
). This fact is rarely known (or understood), although this is properly documented on plugin usage page.
Implication #2a
Maven command line parameters, being in fact Java system properties, are not propagated to the external Ant scripts. If you want to be able to override user-defined properties that are available to Ant via command line, you have to specify them explicitly via nested properties
element:
<plugin> <artifactId>maven-antrun-plugin</artifactId> <version>1.7</version> <executions> <execution> <phase> <!-- a lifecycle phase --> </phase> <goals> <goal>run</goal> </goals> <configuration> <target> <ant antfile="build.xml"> <property name="external.property" value="${external.property}"/> </ant> </target> </configuration> </execution> </executions> </plugin>
Implication #2b
The user-defined properties that are defined (or overridden) via by Maven plugins are available to external Ant script without any additional configuration. However, if you’ll define such property explicitly via nested element (like shown above), only the original value that was explicitly specified in pom.xml
will be visible by Ant. Why? Recall fact #2 above – this is the value that is available during effective pom calculation.
Implication #3
The last and the most interesting implication is a combination of previous two. If you need your user-defined property to be available to the external Ant script, this can be coded in only one of the two ways – either it is intended to be overridden via command line arguments (-D
), or via configuration file (maven-properties-plugin
). You cannot support both override techniques in the same project.
Thank you for your notes!
I’m really sad that such obvious think like overwrite pom properties from external file has no easy solution.