Is it possible to call or execute a Maven goal within an Ant script?
Say I have an ant target called 'distribute' and inside which I need to call a maven 'compile' goal from another pom.xml.
Is it possible to call or execute a Maven goal within an Ant script?
Say I have an ant target called 'distribute' and inside which I need to call a maven 'compile' goal from another pom.xml.
Since none of the solutions worked for me, this is what I came up with:
Assuming you are running on Windows:
<target name="mvn">
<exec dir="." executable="cmd">
<arg line="/c mvn clean install" />
</exec>
</target>
or on UNIX:
<target name="mvn">
<exec dir="." executable="sh">
<arg line="-c 'mvn clean install'" />
</exec>
</target>
or if you want it to work on both UNIX and Windows:
<condition property="isWindows">
<os family="windows" />
</condition>
<condition property="isUnix">
<os family="unix" />
</condition>
<target name="all" depends="mvn_windows, mvn_unix"/>
<target name="mvn_windows" if="isWindows">
<exec dir="." executable="cmd">
<arg line="/c mvn clean install" />
</exec>
</target>
<target name="mvn_unix" if="isUnix">
<exec dir="." executable="sh">
<arg line="-c 'mvn clean install'" />
</exec>
</target>
An example of use of exec task utilizing Maven run from the Windows CLI would be:
<target name="buildProject" description="Builds the individual project">
<exec dir="${source.dir}\${projectName}" executable="cmd">
<arg value="/C"/>
<arg value="${env.MAVEN_HOME}\bin\mvn.bat"/>
<arg line="clean install" />
</exec>
</target>
You can also look at maven ant tasks which is now retired though as commented below. This allows you to run specific maven goals from within your ant build script. You can look at this SO question as well.
You may use a java
task (this example is similar to @mateusz.fiolka answer but also works on Linux)
<target name="mvn-install">
<property environment="env" />
<path id="classpath">
<fileset dir="${env.M2_HOME}/boot">
<include name="plexus-classworlds-*.jar" />
</fileset>
</path>
<property name="mvn.mainclass" value="org.codehaus.plexus.classworlds.launcher.Launcher" />
<java classname="${mvn.mainclass}" classpathref="classpath" fork="true" failonerror="true">
<jvmarg value="-Dclassworlds.conf=${env.M2_HOME}/bin/m2.conf" />
<jvmarg value="-Dmaven.home=${env.M2_HOME}" />
<arg value="install" />
</java>
</target>
tested with maven 3.0.5
Here there is a complete solution:
<target name="mvn_windows_setup" if="isWindows">
<property name="mvn.executable" value="cmd" />
<property name="mvn.args" value="/c" />
</target>
<target name="mvn_unix_setup" if="isUnix">
<property name="mvn.executable" value="sh" />
<property name="mvn.args" value="-c" />
</target>
<target name="run-mvn-goals" depends="mvn_windows_setup, mvn_unix_setup">
<exec dir="${basedir}" executable="${mvn.executable}">
<arg line="${mvn.args} 'mvn ${p_goals}'" />
</exec>
</target>
<!-- EXAMPLES OF HOW TO USE -->
<!-- let's say you want to run mvn clean install -->
<target name="mvn-clean-install">
<antcall target="run-mvn-goals">
<param name="p_goals" value="clean install"/>
</antcall>
</target>
<!-- or maybe you want to clean, package but skipping tests -->
<target name="mvn-clean-package-notests">
<antcall target="run-mvn-goals">
<param name="p_goals" value="clean package -DskipTests"/>
</antcall>
</target>
The output is something like this...
Buildfile: /home/.../build.xml
deploy-complete:
deploy-complete:
mvn_windows_setup:
mvn_unix_setup:
run-mvn-goals:
[exec] [INFO] Scanning for projects...
[exec] [INFO]
[exec] [INFO] ------------------------------------------------------------------------
[exec] [INFO] Building wpm 0.0.1-SNAPSHOT
[exec] [INFO] ------------------------------------------------------------------------
[exec] [INFO]
[exec] [INFO] --- maven-clean-plugin:2.6.1:clean (default-clean) @ wpm ---
...
...
...
[exec] [INFO] BUILD SUCCESS
[exec] [INFO] ------------------------------------------------------------------------
[exec] [INFO] Total time: 28.817 s
[exec] [INFO] Finished at: 2016-11-14T14:01:34-05:00
[exec] [INFO] Final Memory: 84M/872M
[exec] [INFO] ------------------------------------------------------------------------
BUILD SUCCESSFUL
Total time: 31 seconds
I used this answer from @Adam Siemion above, but I didn't want separate targets for running on Windows or Linux. Instead I just set the property near the top of my ant script:
<condition property="isAntRunningOnWindows">
<os family="windows" />
</condition>
Then in the middle of my script I use an if-then-else statement:
<if>
<equals arg1="${isAntRunningOnWindows}" arg2="true" />
<then>
<echo message="OS is Windows" />
<exec dir="." executable="cmd">
<arg line="/c mvn clean package" />
</exec>
</then>
<else>
<echo message="OS is Linux/Unix" />
<exec dir="." executable="sh">
<arg line="-c 'mvn clean package'" />
</exec>
</else>
</if>
I am using the following target to run maven clean
, install
and clean install
goals. Works fine.
<project name="Maven run goals" basedir="."
xmlns:artifact="antlib:org.apache.maven.artifact.ant"
xmlns:rsel="antlib:org.apache.tools.ant.types.resources.selectors">
<target name="maven clean">
<artifact:mvn mavenHome="${maven.home}" fork="true">
<arg value="clean" />
</artifact:mvn>
</target>
<target name="maven install">
<artifact:mvn mavenHome="${maven.home}" fork="true">
<arg value="install" />
</artifact:mvn>
</target>
<target name="maven clean-install">
<artifact:mvn mavenHome="${maven.home}" fork="true">
<arg value="clean" />
<arg value="install" />
</artifact:mvn>
</target>
</project>
Your maven.home property should point to the maven home directory. For example,
<property name="maven.home" value="D:\\Downloads\\apache-maven-3.0.5"/>
Installation
Create a lib
directory in the root of your project and place the maven-ant-tasks.jarbinaries, sonatype file inside it.
<?xml version="1.0" encoding="UTF-8"?>
<project name="maven" default="build" xmlns:artifact="antlib:org.apache.maven.artifact.ant">
<property environment="env" />
<!-- <get src="http://search.maven.org/remotecontent?filepath=org/apache/maven/maven-ant-tasks/2.1.3/maven-ant-tasks-2.1.3.jar" dest="lib/maven-ant-tasks-2.1.3.jar"/> -->
<path id="maven-ant-tasks.classpath" path="lib/maven-ant-tasks-2.1.3.jar" />
<typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="antlib:org.apache.maven.artifact.ant" classpathref="maven-ant-tasks.classpath" />
<record name="build.log" loglevel="verbose" action="start"/>
<target name="build" description="project build ant script">
<fail unless="env.MAVEN_HOME" message="Environment variable MAVEN_HOME was not found on your system!" />
<artifact:mvn mavenHome="${env.MAVEN_HOME}" fork="true">
<arg value="clean" />
<arg value="install" />
<arg value="-Pqa" />
</artifact:mvn>
</target>
</project>
Small information between these elements ant typedef
vs taskdef
.
Typedef
: Using a typedef
declaration allows you to store the Ant Tasks' library anywhere you like (such as source control) and put it's location in the build file.
<typedef name="urlset" classname="com.mydomain.URLSet"/>
Taskdef
Adds a task definition to the current project, such that this new task can be used in the current project.
Using PropertyFiles.java task by adding it to taskdef externally.
<taskdef name = "propertyfiles"
classname = "org.apache.tools.ant.taskdefs.optional.PropertyFiles" />
All the taskdef
are configured in apache-ant-1.9.4\lib\ant.jar\org\apache\tools\ant\taskdefs\defaults.properties
properties files. But i have created an external class and placed inside jar file. But instead of adding entry in defaults.properties
file externally informing the task by taskdef
.
Second way, You can create a jar file, list all the tasksef
in one properties file and refer the resource
antcontrib You can place the JAR in your Ant lib directory, and set classpath.
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="${env.ANT_HOME}/lib/ant-contrib-0.6.jar"/>
</classpath>
</taskdef>
This is an old post, but still relevant (for me, anyhow). I think things have changed since the original post. Turns out the solution is quite simple, and you don't need all the ant-maven integration fluff. It makes me wonder why this wasn't the answer 8 years ago, as I'm pretty sure it would have worked then as it does now. I should mention this is for Windows. You could probably tweak it to support Unix or both.
<property environment="env" />
<target name="mvnPackage" description="Creates war file"> <fail unless="env.MAVEN_HOME" message="Environment variable MAVEN_HOME was not found on your system!" /> <exec executable="${env.MAVEN_HOME}\bin\mvn.cmd"> <arg value="clean" /> <arg value="package" /> </exec> </target>
From Thiagoh answer, I have to add this to make it work.
<condition property="isWindows">
<os family="windows" />
</condition>
<condition property="isLinux">
<os family="unix" />
</condition>
<target name="mvn_windows_setup" if="isWindows">
<property name="mvn.executable" value="cmd" />
<property name="mvn.args" value="/c" />
</target>
<target name="mvn_unix_setup" if="isLinux">
<property name="mvn.executable" value="sh" />
<property name="mvn.args" value="-c" />
</target>
<target name="run-mvn-goals" depends="mvn_windows_setup, mvn_unix_setup">
<exec dir="${basedir}" executable="${mvn.executable}">
<arg line="${mvn.args} 'mvn ${p_goals}'" />
</exec>
</target>
plexus
seems to be an older solution for embedding Maven.
Take a look at the Apache's Maven Embedder project.
This article paragraph outlines embedding Maven into Java code, without a locally installed Maven executable.