Ant的简介与基础知识
1. Ant是什么?
Ant相当于Linux环境下的shell脚本,只不过是xml文档来编写的。我们知道,在Linux环境中,可以通过编写shell脚本,封装一系列繁琐而日常需要经常重复的工作。在需要进行这些操作时,只需要运行这个脚本就可以批处理这些操作了。Ant脚本也是一样,只不过它一般是为了方便Java项目的编译、运行、测试、打包等工作服务的。
日常工作中,一个项目除了编码外,还需单元测试、集成测试、系统测试,测试过程中可能会不断修改代码,然后在测试。这样重复而繁琐的过程是十分耗时间的。在程序编译、测试通过后,还需要打包导出,如果之后需要改变了代码,这些工作还需要重新再做。Ant的产生,就是为了把我们从这些重复而琐碎的工作中解放出来。
2. Ant能干什么?
Ant脚本,通过一个xml文件制定一系列文件的创建删除任务、编译任务、运行任务、测试任务、打包任务等。我们可以通过ant指令执行这个xml脚本,来处理这些任务,这样就可以实现“一键”完成编码后的编译、运行、测试、打包导出等工作,使我们可以更加专注于代码的编写与质量。
3. Ant的使用
3.1安装配置
-
下载地址:http://ant.apache.org/
-
安装:解压得到apache-ant文件夹,这个就是Ant的安装目录了,复制到你想安装的地方即可。
-
配置:与配置Java运行环境类型相似:
在系统变量中添加:ANT_HOME = XX:\xx\apache-ant(apache-ant安装目录)
在Path环境变量值后面加上:XX:\xx\apache-ant\bin(apache-ant\bin所在路径)
3.2编写Ant脚本
一个Ant脚本即可完成至少一个项目的编译、运行、测试、打包等工作。Ant脚本统一命名:build.xml
脚本内容:
1)project节点:一个脚本相当于一个project,用一个project来统领脚本中的众多操作命 令。用这个project对象来指向脚本本身的基本属性。
project元素是Ant构件文件的根元素,Ant构件文件至少应该包含一个project元素,否则会 发生错误。
- name属性:用于指定project元素的名称。
- default属性:用于指定project默认执行时所执行的target的名称。如果没有该参数,则需要在项目运行时手动指定执行的任务
- basedir属性:表示项目执行的默认目录【.代表当前目录】
2)property节点:属性节点,相当于Ant脚本中的变量,通过属性值来携带具体内容,在每 个任务中通过${属性名}来访问其属性值,从而获取内容。
Ant提供了一些内置的属性,他能得到的系统属性的列表与Java文档中System.getPropertie() 方法得到的属性一致。ant还提供了一些自己的内置属性:
basedir:project基目录的绝对路径;
ant.file: buildfile的绝对路径;
ant.version:Ant的版本信息;
ant.project.name:当前指定的project的名字;
ant.java.version:Ant检测到的JDK版本。
<project name="antwar" default="publish" basedir=".">
<!-- 打包生成的war名字 -->
<property name="war.name" value="Internationalisation" />
<!-- java源文件路径 -->
<property name="src.dir" value="${basedir}/src" />
<!-- webapp路径 -->
<property name="webapp.dir" value="${basedir}/WebContent" />
</project>
3)target节点:任务节点。一个target可以制定一个或内嵌更多任务。
target为ant的基本执行单元,它可以包含一个或多个具体的单元/任务。多个target 可以存 在相互依赖关系,target的执行顺序可以有两种方式控制:一种是依赖,depends属性,A depends B,则B先执行;另一种就是内嵌:在target A中通过 命令执行B任务。
- name属性:指定target元素的名称,这个属性在一个project元素中是唯一的。我们可以通过指定target元素的名称来指定某个target。
- depends属性:用于描述target之间的依赖关系,Ant会依照depends属性中的target出现的顺序依次执行每个target,被依赖的target会先执行。
- if属性:用于验证指定的属性是否存在,若存在,所在的target将会被执行。
- unless属性:该属性的功能与if属性的功能正好相反,若不存在,所在target将会被执行。
- description属性:该属性是关于target功能的简短描述和说明。
4)copy命令
copy主要用来对文件和目录的复制功能。
- file:表示源文件
- tofile:表示目标文件
- todir:表示目标目录
- overwrite:表示是否覆盖目标文件,默认是不覆盖
5)delete命令
对文件或目录进行删除。
- file:表示想要删除的文件
- dir:表示想要删除的目录
- includeEmptyDirs:表示是否删除指定目录中的空目录,如:includeEmptyDirs=”true“
- failonerror:表示碰到错误时是否停止,默认是自动停止
6)mkdir命令
创建目录。
7)move命令
移动文件或目录。
8)echo命令
在控制台输出信息。他包括message、file、append和level四个属性。
9)jar命令:打包成jar包并导出
- destfile:打包导出的JAR路径名,即:导出jar包到哪里。
- basedir:被打包的文件,一般是编译通过的文件。
- includes:表示被归档的文件类型。
- exchudes:表示被排除的文件类型。
- compress:表示是否压缩
<?xml version="1.0"?>
<project name="javacTest" default="makeJar" basedir=".">
<target name="clean">
<delete dir="build"/>
</target>
<target name="compile" depends="clean">
<mkdir dir="build/classes"/>
<javac srcdir="src" destdir="build/classes"/>
</target>
<target name="run" depends="compile">
<java classname="javase.base.Demo2">
<classpath>
<pathelement path="build/classes/"/>
</classpath>
</java>
</target>
<target name="makeJar" depends="run">
<jar destfile="Demo.jar" basedir="build/classes">
<manifest>
<attribute name="Main-class" value="javase.base.Demo2"/>
</manifest>
</jar>
</target>
</project>
10)javac命令标签:编译标签。
该标签用于编译一个或一组java文件。
- srcdir:表示源程序的目录。
- destdir:表示class文件的输出目录。
- include:表示被编译的文件的模式。
- excludes:表示被排除的文件的模式。
- classpath:表示所使用的类路径。
- debug:表示包含的调试信息。
- optimize:表示是否使用优化。
- verbose :表示提供详细的输出信息。
- fileonerror:表示当碰到错误就自动停止。
<target name="compile" depends="clean">
<mkdir dir="build/classes" />
<javac srcdir="src" destdir="build/classes" />
</target>
11)java命令标签:运行标签
该标签用来执行编译生成的.class文件。
-
classname:表示将执行的类名。
-
jar:表示包含该类的JAR文件名。
-
classpath:所表示用到的类路径。
-
fork:表示在一个新的虚拟机中运行该类。
-
failonerror:表示当出现错误时自动停止。
-
output:表示输出文件。
-
append:表示追加或者覆盖默认文件。
<target name="run" depends="compile">
<java classname="javase.base.Demo2">
<classpath>
<pathelement path="build/classes/" />
</classpath>
</java>
</target>
12)arg参数标签:可以用于定义测试用例,向运行程序进行输入,观察 输出
通过元素向其传递命令行参数
- values:是一个命令参数
- file:表示一个参数的文件名
- line:表示用空格分隔的多个参数列表
- pathref:引用的path(使用path元素节点定义path)的id
- prefix:前缀
- suffix:后缀
13)path节点:表示一个路径
path元素用来表示一个类路径,不过它还可以用于表示其他的路径。
- location:表示一个文件或目录。Ant在内部将此扩展为一个绝对路径。
- refid:是对当前构建文件中某处定义的一个path的引用。
- path:表示一个文件或路径名列表。
<path id="classpath">
<fileset dir="${lib.dir}">
<include name="**/*.jar" />
</fileset>
<fileset dir="${tomcat.home}/lib">
<include name="**/*.jar" />
</fileset>
</path>
14)filelist节点:表示一个文件列表
- dir:表示文件目录
- files:用逗号分隔的一个文件列表
- refid:表示对某处定义的一个filelist引用
<filelist id="resourceFiles" dir="${res.src}" files="web.xml,application.xml" />
<filelist refid="resourceFiles" />
<filelist id="resourceFiles" dir="${res.src}">
<file name="web.xml" />
<file name="application.xml" />
</filelist>
15)fileset标签:表示一种类型的文件列表
- include:表示文件模式列表
- exclude:表示不包含这些模式的文件列表
<copy todir="${buildwar.dest}/WEB-INF/classes" overwrite="true">
<fileset dir="${build.bin}">
<include name="**/*.class" />
</fileset>
</copy>
<copy todir="${buildwar.dest}" overwrite="true">
<fileset dir="${webapp.dir}">
<exclude name="/WEB-INF/classes/**" />
</fileset>
</copy>
4. 使用Ant自动编译JavaWeb项目并打成war包发布到Tomcat中
Ant脚本build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="antwar" default="publish" basedir=".">
<!--打包生成war名字-->
<property name="war.name" value="Internationalisation" />
<!--java源文件路径-->
<property name="src.dir" value="${basedir}/src" />
<!--webapp路径-->
<property name="webapp.dir" value="${basedir}/WebContent" />
<!--jar包路径-->
<property name="lib.dir" value="${webapp.dir}/WEB-INF/lib" />
<!--编译源文件路径-->
<property name="build.bin" value="${basedir}/AntBuild/bin" />
<!--准备webapp文件路径-->
<property name="buildwar.dest" value="${basedir}/AntBuild/warsrc" />
<!--打包war文件路径-->
<property name="war.dest" value="${basedir}/AntBuild/war" />
<!--tomcat路径-->
<property name="tomcat.home" value="D:\\apache-tomcat-7.0.68" />
<!--classpath-->
<path id="classpath">
<fileset dir="${lib.dir}">
<inclde name="**/*.jar" />
</fileset>
<fileset dir="${tomcat.home}/lib" >
<include name="**/*.jar" />
</fileset>
</path>
<!--初始化-->
<target name="init">
<mkdir dir="${build.bin}" />
<mkdir dir="${buildwar.dest}" />
<mkdir dir="${war.dest}" />
<!--复制静态文件-->
<copy todir="${buildwar.dest}" overwrite="true">
<fileset dir="${webapp.dir}">
<exclude name="/WEB-INF/classes/**" />
</fileset>
</copy>
</target>
<!--复制项目中的其他的一些资源文件-->
<target name="copyResource" depends="compile">
<echo message="Copy resources:" />
<copy todir="${buildwar.dest}/WEB-INF/classes" overwrite="true">
<fileset dir="${basedir}/resources">
<include name="**/*.*" />
</fileset>
</copy>
</target>
<!--打war包-->
<target name="build.war" depends="copyResource">
<echo message="Build war:" />
<war warfile="${war.dest}/${war.name}.war" webxml="${buildwar.dest}/WEB-INF/web.xml">
<fileset dir="${buildwar.dest}" />
</war>
</target>
<!--发布到tomcat-->
<target name="publish" depends="build.war">
<!--删除tomcat已发布的项目文件-->
<delete dir="${tomcat.home}/webapps/${war.name}" />
<delete file="${tomcat.home}/webapps/${war.name}.war" />
<!--复制war文件到${tomcat.home}/webapps-->
<copy todir="${tomcat.home}/webapps" overwrite="true">
<fileset dir="${war.dest}">
<filename name="${war.name}.war" />
</fileset>
</copy>
<!--清除临时文件-->
<delete dir="${build.bin}" />
<delete dir="${buildwar.dest}" />
<delete dir="${war.dest}">
</target>
</project>
5. 使用Ant自动编译Java项目并打成jar包
项目结构:
project
—src
--------com.anyservice
---------------------MainClass.java
---------------------config_export.properties
—lib
<?xml version='1.0' encoding='utf-8'?>
<project name="export" default="all" basedir=".">
<!--1.初始化-->
<target name="init">
<!--设置属性-->
<property name="home" value="." />
<property name="class.version" value="1.8" />
<property name="cfg.jar" value="export.jar" />
<property name="cfg.zip" value="export.zip" />
<!--创建目录-->
<mkdir dir="${home}/build" />
<mkdir dir="${home}/build/classes" />
<!--时间戳-->
<tstamp>
<format property="TODAY" pattern="yyyy-MM-dd HH:mm:ss" />
</tstamp>
<!--第三方jar包的路径-->
<path id="lib-classpath">
<fileset dir="${home}/lib">
<include name="**/*.jar" />
</fileset>
</path>
</target>
<!--2.清理-->
<target name="clean" depends="init">
<delete dir="${home}/build" />
</target>
<!--3.编译-->
<target name="compile" depends="init">
<mkdir dir="${home}/build/classes" />
<javac srcdir="${home}/src" destdir="${home}/build/classes" target="${class.version}" source="${class.version}" includes="com/anyservice/**" encoding="UTF-8" debug="true" debuglevel="lines,vars,source" includeantruntime="on" >
<!--编译依赖的第三方jar包-->
<classpath refid="lib-classpath" />
</javac>
</target>
<!--4.构建jar-->
<target name="jar" depends="init,compile">
<!--复制配置文件到jar-->
<copy todir="${home}/build">
<fileset dir="${home}/src/com/anyservice">
<include name="config_export.properties" />
</fileset>
</copy>
<!--复制第三方jar包-->
<copy todir="${home}/build/lib">
<fileset dir="${home}/lib" />
</copy>
<!--第三方jar包路径转换成可被Class-Path引用的形式-->
<pathconvert property="quote.classpath" pathsep=" ">
<mapper>
<chainedmapper>
<!--jar包文件只留文件名,去掉目录信息-->
<flattenmapper />
<!--add lib/prefix-->
<globmapper from="*" to="lib/*" />
</chainedmapper>
</mapper>
<path refid="lib-classpath" />
</pathconvert>
<!-- build jar -->
<jar jarfile="${home}/build/${cfg.jar}">
<fileset dir="${home}/build/classes" />
<mainfest>
<attribute name="Target-Java" value="${class.version}" />
<attribute name="Build-Time" value="${TODAY}" />
<attribute name="Main-Class" value="com.anyservice.MainClass" />
<attribute name="Class-Path" value="${quote.classpath}" />
</mainfest>
</jar>
<!--delete classes-->
<delete dir="${home}/build/classes" />
</target>
<!--5.zip-->
<target name="zip" depends="jar">
<zip destfile="${home}/build/${cfg.zip}" basedir="${home}/build" encoding="UTF-8" />
</target>
<!--6.入口-->
<target name="all" depends="clean,zip" />
</project>
是打包入口
执行某个target前,会先执行其depends里依赖的target
打入第三方jar包,需要在MANIFEST.MF文件的Class-Path中加入相应路径
第三方jar包的路径需要利用pathconvert转换得到