Yesterday I was looking for a good recipe of how to run PowerShell script from Ant build file. Unfortunately, it seems that most of the people are looking for an advise on exactly the opposite – how to run Ant from PowerShell. So, I did some trial and error on my own, and here are the results.
The following Ant snippet executes PowerShell script MyScript.ps1 in the current directory and verifies that it did not fail. The result of the script execution is stored in myscript.out property.
The main caveat here is the error checking. Despite the failonerror flag, the exec task will not fail in case of many errors – like compilation issues, missing parameters and other runtime errors. This happens because the task verifies invocation of PowerShell itself and not the script execution, which is handled inside PowerShell. The solution is to capture error stream into dedicated property and verify that nothing was actually written there.
Pay attention that if tag (lines 6-13) requires ant-contrib tasks library available. The same condition may be rewritten in less readable form with pure Ant:
Another note is the bypass of default execution policy on line 3. This is not specific to Ant, but rather to PowerShell in general. There are a lot of discussions on the net about the topic, so I won’t cover it here.
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.
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.
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.
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.
As you probably know, maven-antrun-plugin provides a custom AttachArtifact task that is able to attach artifacts generated by Ant to the current Maven project. The usage is really straightforward with inline Ant targets, but an attempt to use this task with external build.xml results in an error:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.7:run (...) on project ...:
An Ant BuildException has occured: The following error occurred while executing this line:
[ERROR] C:\...\build.xml:158: Maven project reference not found: maven.project
[ The solution described here does not really work. See update at the bottom. ]
The solution is simple – external Ant invocation should inherit references from the inline target: