接触ant也有一段时间了,为了以后更好的利用ant,今天就做一个小小的总结吧。
Ant具有 编译 Java程序,同时产生 javadoc,生成一个 Jar 或 war文件,实现文件的副本等一些功能,这些功能只需要通过build.xml配置文件定义一序列的target即可。在Eclipse集成环境下可以很方便的使用ant管理工程。直接在build.xml文件上右键即可。如图所示:
当然了,这是由于Eclipse集成了ant,所以可以如此的方便。如果我们要单独的使用ant,还要下载ant包并做一些简单的配置才能使用。
使用ant可分为以下步骤:下载ant包,配置ant,编写build.xml配置文件
下载ant包:
我上传了一个1.8版本的ant包,需要的话可以下载。ant-1.8.2.zip
解压后有如下目录结构:
配置:
因为我们是在cmd窗口下执行ant命令的,所以我们必须在环境变量path后添加上图bin目录的绝对路径,类似于这样:...;E:\java\jar_source\jar\apache-ant-1.8.2\bin
在cmd窗口下执行ant命令:
如果是这样的话,那就是配置好了,它提示找不到build.xml而不是找不到ant命令。
我们需要到build.xml文件所在目录的上一级目录执行ant命令才可以,这个后面会细说。
编写build.xml文件:
先看一个例子,后面讲起来就不会那么抽象了。
<?xml version="1.0" encoding="utf-8"?>
<project name="anttest" default="compile" basedir=".">
<property name="build.dir" value="${basedir}/build"/>
<property name="build.src" value="${basedir}/build/src"/>
<property name="build.webinf" value="${basedir}/build/WEB-INF"/>
<property name="build.des" value="${basedir}/build/WEB-INF/classes"/>
<target name="init">
<tstamp/>
<mkdir dir="${build.dir}"/>
<mkdir dir="${build.src}"/>
<mkdir dir="${build.webinf}"/>
<mkdir dir="${build.des}"/>
<copy todir="${build.dir}">
<fileset dir="${basedir}">
<include name="*.jsp"/>
<include name="bookstore/*.jsp"/>
<include name="simpledemo/*.jsp"/>
<include name="simpledemo/*.html"/>
<include name="src/**"/>
<include name="tagjsp/*.jsp"/>
<include name="WEB-INF/**"/>
<exclude name="build.xml"/>
</fileset>
</copy>
</target>
<target name="compile" depends="init" >
<property name="environment" value="env"/>
<property name="servletapi" value="${env.CATALINA_HOME}/lib/servlet-api.jar"/>
<javac srcdir="${build.src}" destdir="${build.des}" classpath="${servletapi}"/>
</target>
</project>
首先,是一个<project>根元素,project 可以包含的元素有:property、path、taskdef、target、task。具体如下:
project 可以包含 0 到多个 property,property 用于设置属性值;
project 可以包含 0 到多个 path,path 用于设置环境变量;
project 可以包含 0 到多个 taskdef, taskdef 用于预定义任务。 Ant 默认定义了一些任务,也可以在这里添加自定义的;
project 可以包含 0 到多个 target, 用于定义任务目标。 target 可以包含 0 到多个 task,task 用于执行一个任务操作;
project 也可以直接包含 task,在每次编译时都会执行该任务。
下面详细讲解这些元素。
project:
配置文件只包含一个顶级元素 project,project 有三个属性,如:<project name="anttest" default="compile" basedir=".">
name:项目名称,可以没有
default:当没有指定 target 时使用的默认 target,必须有
basedir:用于计算所有其他路径的基路径。该属性可以被 basedir property 覆盖。当覆盖时,该属性被忽略。如果属性和 basedir都没有设定,就使用 build.xml文件的父目
录,这个属性也不是必须的
property:
类似于编程语言中的变量吧,定义<property>是为了方便后面target的编写。如:<property name="build.dir" value="${basedir}/build"/>
另外说下,ant编译时可以使用的属性值有三部分:<property>定义的,java中System.getProperty("...")可以得到的(如os.name),还有就是ant内置的属性(不常用,不说
了)
path:
通过path可以包含一批路径,每一个path有一个id属性,使用时引用该id即可,如:
<path id="tomcat.test.classpath">
<pathelement location="${tomcat.build}/webapps/examples/WEB-INF/classes"/>
<pathelement location="${test.classes}"/>
<pathelement location="${junit.jar}"/>
<pathelement location="${hamcrest.jar}"/>
<pathelement location="${easymock.jar}"/>
<pathelement location="${cglib.jar}"/>
<pathelement location="${objenesis.jar}"/>
<path refid="compile.classpath" />
<path refid="tomcat.classpath" />
</path>
可以看到,path有子元素<pathelement>,此外还可以有<fileset>子元素,这个后面再说。<path>还可以引用别的<path>,如上所示
target:
通过<target>定义要执行的任务,使用depends属性来实现<target>之间的依赖关系。被依赖的任务先执行,所有的任务最多被执行一次。
<target>有如下5个属性:
name:target 的名字,这个是必须的
depends:用逗号分隔的 target 的名字列表,也就是依赖表,这个可以没有
if:执行 target 所需要设定的属性名,这个可以没有
unless:执行 target 需要清除设定的属性名,这个可以没有
description:关于 target 功能的简短描述,这个也不是必须的
如:
<target name="validate-eoln" depends="build-prepare,compile-prepare">...</target>
task:
task是一段可执行的代码,ant内置了一些task,方便用户使用,主要包括如下几类:
文件路径操作:mkdir、copy、delete、move
Java 相关:javac、java
打包相关:jar、war、ear
时间戳:tstamp
执行 SQL:sql
发送邮件:mail
详细说说几个常用的:
<mkdir>:创建一个目录,如果父目录不存在,则父目录也会被创建,如:<mkdir dir="${tomcat.output}/res/checkstyle"/>
<copy>:复制文件或文件夹,可以单个,也可以多个。如:
<copy todir="${tomcat.classes}" encoding="ISO-8859-1">
<fileset dir="java">
<include name="**/*.properties"/>
<include name="**/*.dtd"/>
<include name="**/*.tasks"/>
<include name="**/*.xsd"/>
<include name="**/*.xml"/>
</fileset>
</copy>
或者:
<copy tofile="${tomcat.build}/webapps/docs/appdev/sample/build.xml"
file="webapps/docs/appdev/build.xml.txt"/>
其中**表示文件夹下所有的文件,*则是可以匹配任何文件名,所以上面的<copy>表示将java文件夹下的指定格式的文件复制到指定文件夹。也可以指定哪些文件不要复制,用<exclude>元素就可以了。
<delete>:与copy相对应了。如:
<delete dir="lib"/>
<delete>
<fileset dir="." includes="**/*.bak"/>
</delete>
<move>:移动或重命名一组文件,用法和copy相似了。
<javac>:编译一组java源代码。如:
<javac srcdir="webapps/examples/WEB-INF/classes"
destdir="${tomcat.build}/webapps/examples/WEB-INF/classes"
debug="${compile.debug}"
classpath="${tomcat.classes}"
excludes="**/CVS/**,**/.svn/**"
</javac>
指定源文件位置,目标文件(class文件)存放位置,debug属性用于决定是否要输出debug信息,classpath属性则是指定编译时要用到的其他类文件。exclude指定哪些不要编译。
以下是javac的参数:
<javac>任务和javac命令是相似,它编译两种类型的java文件:
(1) 没有被编译的java文件
(2) 曾经编译过,但是class文件版本和当前对应的java文件版本不匹配的java文件。
1) javac命令支持的参数: AttributesDescription
srcdir: 必须的,除非嵌套有<src>标签。包含源文件的文件夹
bootclasspath: 编译过程中需要导入class文件会被导入
bootclasspathref: 编译过程中需要引用的class文件夹目录
classpath: The class path to use. 文件夹中class会被导入的jar包
classpathref: 文件夹中class文件会被引用的jar包
compiler: 指定要使用的编译器。如果未设置该特性,将使用 build.compiler 属性的值(如果设置)。否则,将使用当前 JVM 的默认编译器。
例子:设置环境变量 JIKESHOME 为jdk 的路径,设置 ANT_OPTS=-Dbuild.compiler=jdk,将 jdk 路径添加到系统 PATH 中, 然后在所有的ant任务就默认使用 jdk了, 如果你想在单个工程中使用 ant, 就不要添加 ANT_OPTS 环境变量, 只需要修改 build.xml 中 javac 标签中的 compiler 为 jdk.
debug: 当值未为true时产生调试信息
debuglevel: 相当于命令行中要追加到 -g 命令行开关后面的关键字列表。这将会被除 modern 和 classic(ver >= 1.2) 以外的所有实现忽略。合法值是 none 或下列关键字的逗号分隔列表:lines、vars 和 source。如果不指定 debuglevel,则默认情况下,将不会在 -g 的后面追加任何关键字。如果不打开 debug,该特性将被忽略。
depend: 这个任务依赖的任务。当运行这个任务时,首先按照顺序依次执行完依赖的任务,如果出错将停止执行
deprecation: 假如为真,将会给出不建议使用的API,默认值false
destdir: 编译后文件存放的目标文件夹,默认是当前文件夹。
encoding: 指定编码格式
excludes: 必须排除的文件模式的列表,以逗号或空格分隔。如果忽略,将不会排除任何文件(默认排除文件除外)。
excludesfile: 该文件的每一行都将作为一个 exclude 模式。
extdirs: Specifies an alternative location of installed extensions that overrides the default.
failonerror: 指定 clientgen Ant 任务在出现错误的情况下是否继续执行。 此特性的有效值为 True 或 False。默认值为 True,这意味着即使遇到错误也要继续执行。
fork: 为true时在外部启用一个新的JDK 编译器进程执行编译。默认值是true,应用在需要配置编译器运行时环境时
includeantruntime: 指出是否应在类路径中包括 Ant 运行时程序库,默认为 yes。
includejavaruntime: 指出是否应在类路径中包括来自执行 JVM 的默认运行时程序库,默认为 no。
includes: 必须包括的文件模式的列表,以逗号或空格分隔。如果忽略,将包括所有文件。
includesfile: 文件名。该文件的每一行都将作为一个 include 模式。
listfiles: 为真时显示被编译文件列表,默认为 false
memoryinitialsize 如果 javac 在外部运行,则是底层 JVM 的初始内存大小;否则将被忽略。默认为标准 JVM 内存设置。(例如:83886080、81920k 或 80m)
memorymaximumsize: 如果 javac 在外部运行,则是底层JVM 的最大内存大小;否则将被忽略。默认为标准 JVM 内存设置。(例如:83886080、81920k 或 80m)
nowarn: 为真时将忽略所有警告信息
optimize: 指出是否应该用优化方式编译源代码,默认为 off。
source: 假如设置为1.6,将激活断言。默认是1.3
sourcepath: 指定源资源文件夹。默认指向srcdir
sourcepathref: 指定你想引用资源
target: Specifies the VM version to generate class files for (for example, 1.1 or 1.3).
verbose: 控制生成消息的输出量。
<java>:执行类文件,如:
<java classname="test.Main">
<classpath>
<pathelement location="dist/test.jar"/>
<pathelement path="${java.class.path}"/>
</classpath>
</java>
<jar>:将一组文件打包,如:
<jar destfile="${dist}/lib/app.jar"
basedir="${build}/classes"
includes="mypackage/test/**"
excludes="**/Test.class"
manifest="my.mf"
/>
其中manifest属性用于指定自己编写manifest文件,而不是由系统生成。
<war>:<jar>的扩展,用于打包web应用,如:
<war destfile="myapp.war" webxml="src/metadata/myapp.xml">
<fileset dir="src/html/myapp"/>
<fileset dir="src/jsp/myapp"/>
<lib dir="thirdparty/libs">
<exclude name="jdbc1.jar"/>
</lib>
<classes dir="build/main"/>
<zipfileset dir="src/graphics/images/gifs"
prefix="images"/>
</war>
<ear>:用于打包企业应用,如:
<ear destfile="${build.dir}/myapp.ear"
appxml="${src.dir}/metadata/application.xml">
<fileset dir="${build.dir}" includes="*.jar,*.war"/>
</ear>
<tstamp>:用于产生时间格式,并放入ant属性中,具体有什么用处目前还不太清楚,如:
<tstamp>
<format property="year" pattern="yyyy" locale="en"/>
<format property="today" pattern="MMM d yyyy" locale="en"/>
<format property="today-iso-8601" pattern="yyyy-MM-dd" locale="en"/>
<format property="tstamp" pattern="hh:mm:ss"/>
</tstamp>
<sql>:连接数据库,如:
<sql
driver="org.gjt.mm.mysql.Driver"
url="jdbc:mysql://localhost:3306/mydb"
userid="root"
password="root"
src="data.sql"
/>
<sql
driver="org.database.jdbcDriver"
url="jdbc:database-url"
userid="sa"
password="pass"
src="data.sql"
rdbms="oracle"
version="8.1."
>
</sql>
前者为mysql,后者为oracle。
build.xml的讲解就到这里吧。