如何在Ant脚本中调用Maven目标?

38

在Ant脚本中能否调用或执行Maven目标?

假设我有一个名为“distribute”的Ant目标,在其中需要从另一个pom.xml文件中调用Maven的“compile”目标。


你不能只从ant编译所需的源代码吗? - Simeon
12个回答

37

由于没有任何解决方案适用于我,所以我想出了这个:

假设你正在使用Windows操作系统:

<target name="mvn">
    <exec dir="." executable="cmd">
        <arg line="/c mvn clean install" />
    </exec>
</target>

或在UNIX上:

<target name="mvn">
    <exec dir="." executable="sh">
        <arg line="-c 'mvn clean install'" />
    </exec>
</target>

或者,如果你希望它在UNIX和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>

我在我的build.xml中复制了以下代码:<target name="mvn"> <exec dir="." executable="cmd"> <arg line="/c mvn clean install" /> </exec>
</target> 然后通过cmd运行ant all,但pom.xml没有构建。请问出了什么问题?
- pankaj
@pankaj,请提交一个新问题来解决您的问题。 - Adam Siemion
@pankaj,你是将mvn目标添加为依赖项还是默认目标?新话题会很好。 - Payne

22

一个利用Maven从Windows命令行运行的exec任务的例子如下:

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

我的需求是,我有一个旧项目,它是使用ant构建的,我有一个新项目,它是使用maven构建的。我想使用build.xml从ant构建maven项目。我尝试过了,但是没有成功。我的旧项目可以成功构建,但是新项目却不行。 - pankaj

12

你还可以查看已经停止维护的 maven ant 任务。该工具允许你在 ant 构建脚本中运行特定的 maven 目标。此外,你也可以参考这个 SO 问题


3
Maven Ant 任务已经被停用。 - shonky linux user

9
您可以使用“java”任务(此示例类似于@mateusz.fiolka的答案,但也适用于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>

已使用 Maven 3.0.5 进行测试。


5

这里有一个完整的解决方案:

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

输出结果大致如下...
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

2

我使用以下目标运行maven cleaninstallclean install目标。工作正常。

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

您的maven.home属性应该指向maven主目录。例如:

<property name="maven.home" value="D:\\Downloads\\apache-maven-3.0.5"/>

2

我使用了来自@Adam Siemion这个答案,但我不想为在Windows或Linux上运行设置单独的目标。相反,我只需在我的ant脚本顶部设置属性:

<condition property="isAntRunningOnWindows">
    <os family="windows" />
</condition>

然后在我的脚本中间,我使用了一个if-then-else语句:

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

1

Maven Ant Tasks github 使得从Ant中轻松运行Maven目标。

安装 在项目根目录下创建一个lib目录,并将maven-ant-tasks.jar二进制文件, Sonatype文件放入其中。

<?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>

这些元素之间的小信息是关于 typedeftaskdef 的区别。

  • 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>
    

1
您可以使用 exec task 并调用 mvn compile 作为终端命令。这不是理想的,因为您无法控制执行过程,但是我认为没有其他方法来执行 Maven 目标。

1
这是一篇旧帖子,但对我来说仍然相关。我认为自原帖发布以来情况已经发生了变化。事实证明解决方案非常简单,你不需要所有的ant-maven集成繁琐。这让我想知道为什么8年前这不是答案,因为我很确定它现在能够正常工作。我应该提到这是针对Windows的。你可能可以调整它以支持Unix或两者都支持。
  1. 在Windows上安装maven
  2. 创建一个名为MAVEN_HOME的环境变量,指向mvn安装目录的基础路径(例如,C:\dev\apache-maven-3.6.3)
  3. 将以下内容添加到你的build.xml文件中:
<property environment="env" />
将此任务添加到您的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>

这太棒了。谢谢你。 - Mostafa Zeinali

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接