开发者

How to call for a Maven goal within an Ant script?

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"/>


You can use the exec task and call mvn compile as a terminal command. This is not ideal since you won't have any control over the execution, but otherwise I don't think there is a way to execute a Maven goal.


Maven Ant Tasks github easy to run maven with goals form Ant.

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>
    


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.


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.

  1. Install maven for Windows
  2. Create an environment variable MAVEN_HOME that points to the base mvn install directory (e.g., C:\dev\apache-maven-3.6.3)
  3. Add this task to your build.xml:
<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>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜