在Ant脚本中能否调用或执行Maven目标?
假设我有一个名为“distribute”的Ant目标,在其中需要从另一个pom.xml文件中调用Maven的“compile”目标。
由于没有任何解决方案适用于我,所以我想出了这个:
假设你正在使用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>
一个利用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>
你还可以查看已经停止维护的 maven ant 任务。该工具允许你在 ant 构建脚本中运行特定的 maven 目标。此外,你也可以参考这个 SO 问题。
<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 进行测试。
这里有一个完整的解决方案:
<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
我使用以下目标运行maven clean
,install
和clean 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"/>
我使用了来自@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>
安装
在项目根目录下创建一个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>
这些元素之间的小信息是关于 typedef
和 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>
<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>