Microsoft Word - ant.doc

Similar documents
Microsoft Word - ant.doc

1.JasperReport ireport JasperReport ireport JDK JDK JDK JDK ant ant...6

内 容 提 要 将 JAVA 开 发 环 境 迁 移 到 Linux 系 统 上 是 现 在 很 多 公 司 的 现 实 想 法, 而 在 Linux 上 配 置 JAVA 开 发 环 境 是 步 入 Linux 下 JAVA 程 序 开 发 的 第 一 步, 本 文 图 文 并 茂 地 全 程 指

Microsoft Word - 在VMWare-5.5+RedHat-9下建立本机QTopia-2.1.1虚拟平台a.doc

Microsoft Word - Hibernate与Struts2和Spring组合指导.doc

(TestFailure) JUnit Framework AssertionFailedError JUnit Composite TestSuite Test TestSuite run() run() JUnit

Java 1 Java String Date

内 容 简 介 本 书 是 一 本 关 于 语 言 程 序 设 计 的 教 材, 涵 盖 了 语 言 的 基 本 语 法 和 编 程 技 术, 其 中 包 含 了 作 者 对 语 言 多 年 开 发 经 验 的 总 结, 目 的 是 让 初 学 的 读 者 感 受 到 语 言 的 魅 力, 并 掌

Linux服务器构建与运维管理

2 Java 语 言 程 序 设 计 教 程 简 单 性 Java 语 言 的 语 法 与 C 语 言 和 C++ 语 言 很 接 近, 使 得 大 多 数 程 序 员 很 容 易 学 习 和 使 用 Java 另 一 方 面,Java 丢 弃 了 C++ 中 很 少 使 用 的 很 难


Java

输入 project name 选择完成

本章学习目标 小风 Java 实战系列教程 SpringMVC 简介 SpringMVC 的入门案例 SpringMVC 流程分析 配置注解映射器和适配器 注解的使用 使用不同方式的跳转页面 1. SpringMVC 简介 Spring web mvc

Microsoft Word - Learn Objective-C.doc

1 1 大概思路 创建 WebAPI 创建 CrossMainController 并编写 Nuget 安装 microsoft.aspnet.webapi.cors 跨域设置路由 编写 Jquery EasyUI 界面 运行效果 2 创建 WebAPI 创建 WebAPI, 新建 -> 项目 ->

附录J:Eclipse教程


无类继承.key

res/layout 目录下的 main.xml 源码 : <?xml version="1.0" encoding="utf 8"?> <TabHost android:layout_height="fill_parent" xml

使用MapReduce读取XML文件

Stateless Session Beans(无状态bean)的学习

提纲 1 2 OS Examples for 3

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基

对于部署 MOSS 工作流, 有下面这些步骤 1. 添加 DLL 文件到 GAC 中 2. 配置 feature.xml 和 workflow.xml 文件 3. 在服务器添加 Feature 文件夹, 复制相关文件 4. 利用 stsadm 命令部署并激活 Feature Step1 添加 DLL

epub83-1

D C 93 2

KillTest 质量更高 服务更好 学习资料 半年免费更新服务

H1428

Microsoft Word - 第5章.doc

Learning Java

OSWorkflow Documentation

XXXXXXXX

2 SGML, XML Document Traditional WYSIWYG Document Content Presentation Content Presentation Structure Structure? XML/SGML 3 2 SGML SGML Standard Gener

Hive:用Java代码通过JDBC连接Hiveserver

Microsoft Word - PHP7Ch01.docx

臺銀人壽「98年九至十一職等人員甄試」

Microsoft Word - 01.DOC

. Outline 编译 Linux 在 QEMU 模拟器上运行制作带 grub 启动的磁盘映像...1 编译 Linux 在 QEMU 模拟器上运行...2 制作带 grub 启动的磁盘映像

好文章 吳麗娟老師收集 85頁

<4D F736F F F696E74202D20C8EDBCFEB2E2CAD4D1A7CFB0D7CAC1CF2E BBCE6C8DDC4A3CABD5D>

雲端 Cloud Computing 技術指南 運算 應用 平台與架構 10/04/15 11:55:46 INFO 10/04/15 11:55:53 INFO 10/04/15 11:55:56 INFO 10/04/15 11:56:05 INFO 10/04/15 11:56:07 INFO

f2.eps

1

FileMaker 15 ODBC 和 JDBC 指南

2. AOP 底层技术实现 小风 Java 实战系列教程 关键词 : 代理模式 代理模型分为两种 : 1) 接口代理 (JDK 动态代理 ) 2) 子类代理 (Cglib 子类代理 ) 需求 :CustomerService 业务类, 有 save,update 方法, 希望在 save,updat

使用Spark SQL读取Hive上的数据

会计9

Java java.lang.math Java Java.util.Random : ArithmeticException int zero = 0; try { int i= 72 / zero ; }catch (ArithmeticException e ) { // } 0,

BPS 6.6 手工部署指南 (JBoss4) 手工部署 BPS( 单机 ) 手工部署包支持的 jboss 版本有 jboss ga 和 jboss ga 示例中的 jboss 版本为 jboss ga, 操作系统为 Solaris(IP:

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点

4.1 AMI MQSeries API AMI MQI AMI / / AMI JavaC C++ AMI / AMI AMI - / /

Microsoft Word - Personal Java.{...].p_3_.doc

OOP with Java 通知 Project 3 提交时间 3 月 29 日晚 9 点 Piazza Project 2 投票

2005 Sun Microsystems, Inc Network Circle, Santa Clara, CA U.S.A. Sun Sun Berkeley BSD UNIX X/Open Company, Ltd. / Sun Sun Microsystems Su

基于CDIO一体化理念的课程教学大纲设计

Kubenetes 系列列公开课 2 每周四晚 8 点档 1. Kubernetes 初探 2. 上 手 Kubernetes 3. Kubernetes 的资源调度 4. Kubernetes 的运 行行时 5. Kubernetes 的 网络管理理 6. Kubernetes 的存储管理理 7.

FileMaker 16 ODBC 和 JDBC 指南

嵌入式系统实验报告之一

Chapter 9: Objects and Classes

PowerPoint プレゼンテーション

Oracle Solaris Studio makefile C C++ Fortran IDE Solaris Linux C/C++/Fortran IDE "Project Properties" IDE makefile 1.

OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数

自动化接口

Partition Key: 字 符 串 类 型, 表 示 当 前 Entity 的 分 区 信 息 这 个 Property 对 于 Table Service 自 动 纵 向 和 横 向 扩 展 至 关 重 要 Row Key: 字 符 串 类 型, 在 给 定 Partition Key 的

Microsoft Word - linux命令及建议.doc

EJB-Programming-3.PDF

帝国CMS下在PHP文件中调用数据库类执行SQL语句实例

Business Objects 5.1 Windows BusinessObjects 1

「西醫基層總額支付委員會《第28次委員會議紀錄

EJB-Programming-4-cn.doc

untitled

在Spring中使用Kafka:Producer篇

华恒家庭网关方案

基于UML建模的管理管理信息系统项目案例导航——VB篇

untitled

提问袁小兵:

untitled

User’s Manual

目錄

WebSphere Studio Application Developer IBM Portal Toolkit... 2/21 1. WebSphere Portal Portal WebSphere Application Server stopserver.bat -configfile..

北 风 网 讲 师 原 创 作 品 ---- 仅 供 学 员 内 部 交 流 使 用 前 言 吾 尝 终 日 而 思 矣, 不 如 须 臾 之 所 学 也 ; 吾 尝 跂 而 望 矣, 不 如 登 高 之 博 见 也 登 高 而 招, 臂 非 加 长 也, 而 见

三种方法实现Hadoop(MapReduce)全局排序(1)

untitled

<4D F736F F D20C8EDBCFEA1B A1B33136BAC5A3BAB9D8D3DAB7A2B2BC C4EAC8EDBCFEB9A4B3CCCAB5D1B5D6AED0A3C4DABFC6D1D0CFEEC4BFB5C4CDA8D6AA2E646F63>

PowerPoint 演示文稿

1. 访 问 最 新 发 行 公 告 信 息 jconnect for JDBC 访 问 最 新 发 行 公 告 信 息 最 新 版 本 的 发 行 公 告 可 以 从 网 上 获 得 若 要 查 找 在 本 产 品 发 布 后 增 加 的 重 要 产 品 或 文 档 信 息, 请 访

Fun Time (1) What happens in memory? 1 i n t i ; 2 s h o r t j ; 3 double k ; 4 char c = a ; 5 i = 3; j = 2; 6 k = i j ; H.-T. Lin (NTU CSIE) Referenc

(6) 要 求 付 款 管 理 员 从 预 订 表 中 查 询 距 预 订 的 会 议 时 间 两 周 内 的 预 定, 根 据 客 户 记 录 给 满 足 条 件 的 客 户 发 送 支 付 余 款 要 求 (7) 支 付 余 款 管 理 员 收 到 客 户 余 款 支 付 的 通 知 后, 检

p.2 1 <HTML> 2 3 <HEAD> 4 <TITLE> </TITLE> 5 </HEAD> 6 7 <BODY> 8 <H3><B> </B></H3> 9 <H4><I> </I></H4> 10 </BODY> </HTML> 1. HTML 1. 2.

詞 彙 表 編 號 詞 彙 描 述 1 預 約 人 資 料 中 文 姓 名 英 文 姓 名 身 份 證 字 號 預 約 人 電 話 性 別 2 付 款 資 料 信 用 卡 別 信 用 卡 號 信 用 卡 有 效 日 期 3 住 房 條 件 入 住 日 期 退 房 日 期 人 數 房 間 數 量 入

( Version 0.4 ) 1

目 錄 版 次 變 更 記 錄... 2 原 始 程 式 碼 類 型 之 使 用 手 冊... 3 一 安 裝 軟 體 套 件 事 前 準 備... 3 二 編 譯 流 程 說 明

mvc

ebook60-13

Microsoft Word 電腦軟體設計.doc

Microsoft Word - 新1-12.doc

目 录 1. 硬 件 安 装 步 骤 云 端 加 密 键 盘 云 端 键 盘 加 密 串 接 器 软 件 安 装 步 骤 软 件 基 本 功 能 软 件 进 阶 使 用 说 明 选 单 说 明...

Transcription:

http://www.blogjava.net/dreamstone 1/32 1. Ant 介绍...4 1.1. 什么是 ant...4 1.2. 什么是构建...4 1.3. ant 的好处...4 1.4. ant 的兄弟 make...4 2. Ant 安装...5 2.1. 到 http://ant.apache.org/bindownload.cgi...5 2.2. 如图新增系统变量...5 2.3. 3 测试安装...6 3. 第一个 Ant 脚本...6 3.1. 使用 ant 来达成目的, 完成一件事情的实例...6 3.2. 然后用 ant 完成剩下的步骤...6 3.3. 解释上边的配置文件...7 4. 整合 ant...9 1, 自己重新写一个 build.xml, 这将是一个麻烦的事情...9 4.1. 举个例子 :...9 5. Ant 进阶...11 6. Ant 常用 task...14 6.1. 使用 classpath...14 6.2. 设置 classpath...14 6.3. 输出信息...15 6.3.1. 写法一...15 6.3.2. 写法二...15 6.3.3. 输出一段 xml...15 6.4. 引入一个 xml 文件...15 6.5. 拷贝文件...15 6.5.1. 拷贝一个文件...15 6.5.2. 拷贝一个文件到指定目录...15 6.5.3. 拷贝一个目录到另一个目录...15 6.5.4. 拷贝一个文件集合到一个目录...15 6.5.5. 拷贝一个文件集合到一个目录, 同时建立备份文件...16 6.5.6. 拷贝一个集合的文件到一个目录, 并替换掉 @ TITLE @...16 6.5.7. 拷贝一个目录下的东西到另一个目录下,(includes 加入,excludes 排除 )16 6.5.8. 拷贝一个文件...16 6.6. 删除文件 目录...16 6.6.1. 删除一个文件...16 6.6.2. 删除一个目录...16 6.6.3. 删除所有符合规则的文件 (.bak 文件 ) 包括子目录...16 6.6.4. 删除当前目录下所有的文件和目录, 包括当前目录...16 6.6.5. 删除当前目录下所有的文件和目录, 不包括当前目录...16 6.6.6. 删除当前目录下所有的 svn 相关文件...17 6.6.7. 删除文件目录树...17 6.7. 剪切文件...17 6.8. 重命名...17 http://www.blogjava.net/dreamstone 1/32

http://www.blogjava.net/dreamstone 2/32 6.9. 建立临时文件...17 6.10. Touch 的使用...17 6.10.1. 如果文件不存在, 创建文件, 如果存在, 更改最后访问时间为当前系统时间 17 6.10.2. 如果文件不存在, 创建文件, 更改最后访问时间为 06/28/2000 2:02 pm...17 6.10.3. 更改目录下所有文件最后访问时间为 06/28/2000 2:02 pm...17 6.11. Condition 的使用...18 6.12. 替换 replace...18 6.13. 调用 chmod...18 6.14. checksum MD5 运算...19 6.14.1. md5 文件, 然后把值放入 foo.bar.md5 属性...19 6.14.2. md5 文件, 然后把值放入 foobarmd5 属性...19 6.14.3. Md5 目录下的所有文件, 然后建立一个.md5 文件, 把所有的 md5 值放入 19 6.15. Available 的使用...19 6.15.1. 如果类存在, 则设置属性 Myclass.present 为 true, 如果没有就 false...19 6.15.2. 如果文件存在则设置属性 jaxp.jar.presen 为 true, 否则为 false...19 6.15.3. 如果目录存在, 则设置属性为 true, 否则为 false...19 6.15.4. 如果 classpath 下寻找 class, 如果存在则设置属性为 true, 否则为 false...19 6.15.5. 如果在 classpath 下发现文件则设置属性为 true 否则为 flase...19 6.16. 设置 property...20 6.16.1. 设置属性 name-value...20 6.16.2. 读取属性文件中的属性配置...20 6.16.3. 读取网络中的 property-set...20 6.16.4. 读取文件中的属性配置...20 6.16.5. 读取环境变量...20 6.16.6. 读取属性文件中的属性, 并作为全局引用...20 6.17. 出现一个错误...20 6.17.1. 显示错误方式一...20 6.17.2. 显示错误方式二...20 6.17.3. 如果这个属性不存在显示错误...20 6.17.4. 如果这个属性存在现实错误...20 6.17.5. 如果符合条件显示错误, 这里的条件是 ( 没有设置属性 )...20 6.18. 建立一个目录...20 6.19. 打 jar 包...21 6.20. 打 Ear 包...21 6.21. 执行程序...21 6.22. 运行 jar 包 :...21 6.22.1. 带参数执行...21 6.22.2. 或者设置一下运行的 jvm 的最大内存, 来运行...22 6.23. 编译程序...22 6.24. 制作 Javadoc...22 6.25. 定义一个新的 task 类库...22 6.26. 运行 sql...23 http://www.blogjava.net/dreamstone 2/32

http://www.blogjava.net/dreamstone 3/32 6.27. Filter 的使用...23 6.27.1. 把所有的 @year@ 替换成 2000...23 6.27.2. 替换属性文件中的内容...23 6.28. Length 的使用...23 6.28.1. 把字符串 foo 的长度保存到属性 "length.foo" 中...23 6.28.2. 把文件 bar 的长度保存到属性 " length.bar " 中...23 6.29. 输入 Input...23 6.30. FixCRCL 的使用...24 6.30.1. 替换所有的 eol 变成 lf, 删除所有的 eof...24 6.30.2. 替换 eol 成 crlf 设置 tab 的长度为 4...24 6.31. 发送邮件...24 6.32. 压缩 解压缩...24 6.32.1. 解压缩 zip 文件...24 6.32.2. 压缩 zip 文件...24 6.32.3. 打 tar 包...25 6.32.4. 解 tar 包...25 6.33. 打 war 包 :...25 6.34. antcall...25 6.34.1. 调用 target dosomethingelse...25 6.34.2. 拷贝父中的 path1, 然后再当前工程中命名为 path2...26 6.35. Ant 的使用...26 6.35.1. 调用目录 sub1/sub2/ 下的 build.xml...26 6.35.2. 同上, 不同的写法...26 6.35.3. 同上, 不同的写法...26 6.35.4. 调用指定文件中的指定 target (compile)...26 7. 在 ant 中控制流程 (if else )...27 8. 实例分析 :...27 9. 如何继续学习...31 10. Ant 使用 cvs 的实例...31 11. QA:...32 11.1. 如果执行 ant 过程中出现 Outofmemory 的错误怎么办?...32 http://www.blogjava.net/dreamstone 3/32

http://www.blogjava.net/dreamstone 4/32 1. Ant 介绍 1.1. 什么是 ant ant 是构建工具 1.2. 什么是构建 概念到处可查到, 形象来说, 你要把代码从某个地方拿来, 编译, 再拷贝到某个地方去 等等操作, 当然不仅与此, 但是主要用来干这个 1.3. ant 的好处 跨平台 -- 因为 ant 是使用 java 实现的, 所以它跨平台使用简单 -- 与 ant 的兄弟 make 比起来语法清晰 -- 同样是和 make 相比功能强大 --ant 能做的事情很多, 可能你用了很久, 你仍然不知道它能有多少功能 当你自己开发一些 ant 插件的时候, 你会发现它更多的功能 1.4. ant 的兄弟 make ant 做的很多事情, 大部分是曾经有一个叫 make 的所做的, 不过对象不同,make 更多应用于 c/c++,ant 更多应用于 Java 当然这不是一定的, 但大部分人如此 下边开始一步步的带你走进 ant 的世界 http://www.blogjava.net/dreamstone 4/32

http://www.blogjava.net/dreamstone 5/32 2. Ant 安装 2.1. 到 http://ant.apache.org/bindownload.cgi 下載 Ant, 我使用的版本是 1.70 解压缩下载文件到你的工作目录, 这里以 d:\ant_home 为例 2.2. 如图新增系统变量 新增系统变量 :ANT_HOME, 内容 :d:\ant_home\apache-ant-1.70 在 PATH 环境变量中加入 Ant 的 bin 目錄 :%ANT_HOME%\bin 如果要让 Ant 能支持 JUnit, 需要直接將 JUnit 的 junit.jar 放置在 Ant 的 lib 目錄, 并记得改变 CLASSPATH 中原先有关于 JUnit 的设定, 例如 :%ANT_HOME\lib\junit.jar, 虽然也有其它的方式可以設定, 但這是最快最簡單的方法 如果是 Windows 2000/XP, 请在 [ 系统内容 / 高级 / 环境变量 ] 中设置 [ 系统变量 ], 以完成以上的设定, 例如 : http://www.blogjava.net/dreamstone 5/32

http://www.blogjava.net/dreamstone 6/32 2.3. 3 测试安装 CMD 进入命令行界面, 运行 Ant 出现如下提示, 说明安装成功 E:\srcgen\webwork>ant Buildfile: build.xml does not exist! Build failed 3. 第一个 Ant 脚本 3.1. 使用 ant 来达成目的, 完成一件事情的实例 目的 : 编写一个程序 编译它们 把它打包成 jar 包 把他们放在应该放置的地方 运行它们我们用文本编辑器编写一个 HelloWorld 如下这里为了简单起见只写一个程序, 就是 HelloWorld.java 程序代码如下 : package test.ant; public class HelloWorld{ public static void main(string[] args){ System.out.println("Hello world1"); } }; 3.2. 然后用 ant 完成剩下的步骤 建立一个 build.xml 文件, 内容如下 <?xml version="1.0" encoding="utf-8"?> <project name="helloworld" default="run" basedir="."> <property name="src" value="src"/> <property name="dest" value="classes"/> <property name="hello_jar" value="hello1.jar"/> <target name="init"> <mkdir dir="${dest}"/> <target name="compile" depends="init"> <javac srcdir="${src}" destdir="${dest}"/> http://www.blogjava.net/dreamstone 6/32

http://www.blogjava.net/dreamstone 7/32 <target name="build" depends="compile"> <jar jarfile="${hello_jar}" basedir="${dest}"/> <target name="run" depends="build"> <java classname="test.ant.helloworld" classpath="${hello_jar}"/> <target name="clean"> <delete dir="${dest}" /> <delete file="${hello_jar}" /> <target name="rerun" depends="clean,run"> <ant target="clean" /> <ant target="run" /> </project> 3.3. 解释上边的配置文件 <?xml version="1.0" encoding="utf-8"?> build.xml 中的第一句话, 没有实际的意义, 指定一下 encoding, 几乎所有的 xml 的第一行 <project name="helloworld" default="run" basedir="."> </project> ant 的所有内容必须包含在这个里边,name 是你给它取的名字,basedir 故名思意就是工作的根目录. 代表当前目录 default 代表默认要做的事情 <property name="src" value="src"/> 类似程序中的变量, 为什么这么做想一下变量的作用 <target name="compile" depends="init"> <javac srcdir="${src}" destdir="${dest}"/> 把你想做的每一件事情写成一个 target, 它有一个名字,depends 是它所依赖的 target, 在执行这个 target 例如这里的 compile 之前 ant 会先检查 init 是否曾经被执行过, 如果执行过则直接直接执行 compile, 如果没有则会先执行它依赖的 target 例如这里的 init, 然后在执行这个 target 如我们的计划编译 : <target name="compile" depends="init"> <javac srcdir="${src}" destdir="${dest}"/> http://www.blogjava.net/dreamstone 7/32

http://www.blogjava.net/dreamstone 8/32 做 jar 包 : <target name="build" depends="compile"> <jar jarfile="${hello_jar}" basedir="${dest}"/> 运行 : <target name="run" depends="build"> <java classname="test.ant.helloworld" classpath="${hello_jar}"/> 为了不用拷贝, 我们可以在最开始定义好目标文件夹, 这样 ant 直接把结果就放在目标文件夹中了新建文件夹 : <target name="init"> <mkdir dir="${dest}"/> 为了更多一点的功能体现, 又加入了两个 target 删除生成的文件 <target name="clean"> <delete dir="${dest}" /> <delete file="${hello_jar}" /> 再次运行, 这里显示了如何在一个 target 里边调用其他的 target <target name="rerun" depends="clean,run"> <ant target="clean" /> <ant target="run" /> 好了, 解释完成了, 下边检验一下你的 ant 吧新建一个 src 的文件夹, 然后把 HelloWorld.java 按照包目录放进去做好 build.xml 文件在命令行下键入 ant, 你会发现一个个任务都完成了 每次更改完代码只需要再次键入 ant 有的时候我们可能并不想运行程序, 只想执行这些步骤中的某一两个步骤, 例如我只想重新部署而不想运行, 键入 ant build ant 中的每一个任务都可以这样调用 ant + target name 好了, 这样一个简单的 ant 任务完成了 http://www.blogjava.net/dreamstone 8/32

http://www.blogjava.net/dreamstone 9/32 4. 整合 ant 进一步学习一个稍微复杂一点点的 ant 在实际的工作过程中可能会出现以下一些情况, 一个项目分成很多个模块, 每个小组或者部门负责一个模块, 为了测试, 他们自己写了一个 build.xml, 而你负责把这些模块组合到一起使用, 写一个 build.xml 这个时候你有两种选择 : 1, 自己重新写一个 build.xml, 这将是一个麻烦的事情 2, 尽量利用他们已经写好的 build.xml, 减少自己的工作 4.1. 举个例子 : 假设你下边有三个小组, 每个小组负责一个部分, 他们分别有一个 src 和一个写好的 build.xml 这个时候你拿到他们的 src, 你需要做的是建立三个文件夹 src1,src2, src3 分别把他们的 src 和 build.xml 放进去, 然后写一个 build.xml <?xml version="1.0" encoding="utf-8"?> <project name="main" default="build" basedir="."> <property name="bin" value="${basedir}\bin" /> <property name="src1" value="${basedir}\src1" /> <property name="src2" value="${basedir}\src2" /> <property name="src3" value="${basedir}\src3" /> <target name="init"> <mkdir dir="${bin}" /> <target name="run"> <ant dir="${src1}" target="run" /> <ant dir="${src2}" target="run" /> <ant dir="${src3}" target="run" /> <target name="clean"> <ant dir="${src1}" target="clean" /> <ant dir="${src2}" target="clean" /> <ant dir="${src3}" target="clean" /> http://www.blogjava.net/dreamstone 9/32

http://www.blogjava.net/dreamstone 10/32 <target name="build" depends="init,call"> <copy todir="${bin}"> <fileset dir="${src1}"> <include name="*.jar" /> <fileset dir="${src2}"> <include name="*.jar" /> <fileset dir="${src3}"> <include name="*.jar" /> </copy> <target name="rebuild" depends="build,clean"> <ant target="clean" /> <ant target="build" /> </project> ok 你的任务完成了 http://www.blogjava.net/dreamstone 10/32

http://www.blogjava.net/dreamstone 11/32 5. Ant 进阶 上边你完成了任务, 但是你是否有些感触呢, 在那些 build.xml 中, 大多数是重复的, 而且更改一次目录需要更改不少东西 是否能让工作做的更好一点呢, 答案是肯定的 引入两个东西 : 1,propery 2,xml include 这两个东西都有一个功能, 就是能把 build.xml 中 <propery /> 中的内容分离出来, 共同使用 除此之外它们各有特点 : propery 的特点是维护简单, 只需要简单的键值对, 因为并不是所有人都喜欢 xml 的格式 xml include 的特点是不单可以提取出属性来, 连 target 也可以 还是以前的例子 : 例如我们想把 src1 src2 src3 这三个属性从 xml 中提出来, 可以新建一个文件叫 all.properties 里边的内容 src1=d:\\study\\ant\\src1 src2=d:\\study\\ant\\src2 src3=d:\\study\\ant\\src3 然后你的 build.xml 文件可以这样写, 别人只需要更改配置文件, 而不许要更改你的 build.xml 文件了 <?xml version="1.0" encoding="utf-8"?> <project name="main" default="build" basedir="."> <property file="all.properties" /> <property name="bin" value="${basedir}\bin" /> <target name="init"> <mkdir dir="${bin}" /> <target name="run"> <ant dir="${src1}" target="run" /> <ant dir="${src2}" target="run" /> <ant dir="${src3}" target="run" /> <target name="clean"> <ant dir="${src1}" target="clean" /> <ant dir="${src2}" target="clean" /> <ant dir="${src3}" target="clean" /> http://www.blogjava.net/dreamstone 11/32

http://www.blogjava.net/dreamstone 12/32 <target name="build" depends="init,call"> <copy todir="${bin}"> <fileset dir="${src1}"> <include name="*.jar" /> <fileset dir="${src2}"> <include name="*.jar" /> <fileset dir="${src3}"> <include name="*.jar" /> </copy> <target name="rebuild" depends="build,clean"> <ant target="clean" /> <ant target="build" /> <target name="test"> <ant dir="${src1}" target="test" /> <ant dir="${src2}" target="test" /> <ant dir="${src3}" target="test" /> </project> 如果你自己看的话你会看到这样一个 target <target name="test"> <ant dir="${src1}" target="test" /> <ant dir="${src2}" target="test" /> <ant dir="${src3}" target="test" /> 有的时候你想给每个小组的 build.xml 加入几个 target, 一种做法是每个里边写, 然后在这里调用但是有一种更好的方法 你可以写一个 include.xml 文件, 内容如下 <?xml version="1.0" encoding="utf-8"?> <property name="src" value="src"/> <property name="dest" value="classes"/> <target name="test" > <ant target="run" /> http://www.blogjava.net/dreamstone 12/32

http://www.blogjava.net/dreamstone 13/32 然后更改你三个小组的 build.xml 文件, 每个里边加入如下内容 <!--include a xml file,it can be common propery,can be also a target --> <!DOCTYPE project [ <!ENTITY share-variable SYSTEM "file:../include.xml"> ]> &share-variable; 变成如下的样子这个时候, 你只要在 include.xml 添加 propery, 添加 target, 三个 build.xml 会同时添加这些 propery 和 target 而且不会让三个组的 build.xml 变得更复杂 <?xml version="1.0" encoding="utf-8"?> <!--include a xml file,it can be common propery,can be also a target --> <!DOCTYPE project [ <!ENTITY share-variable SYSTEM "file:../include.xml"> ]> <project name="helloworld" default="run" basedir="."> <!--use the include --> &share-variable; <!--defined the property--> <!--via include <property name="src" value="src"/> <property name="dest" value="classes"/> --> <property name="hello_jar" value="hello1.jar"/> <!--define the op--> <target name="init"> <mkdir dir="${dest}"/> <target name="compile" depends="init"> <javac srcdir="${src}" destdir="${dest}"/> <target name="build" depends="compile"> <jar jarfile="${hello_jar}" basedir="${dest}"/> <target name="run" depends="build"> <java classname="test.ant.helloworld" classpath="${hello_jar}"/> <target name="clean"> <delete dir="${dest}" /> <delete file="${hello_jar}" /> http://www.blogjava.net/dreamstone 13/32

http://www.blogjava.net/dreamstone 14/32 <target name="rerun" depends="clean,run"> <ant target="clean" /> <ant target="run" /> </project> 6. Ant 常用 task 好了, 看完上边的内容, 你应该知道怎么构建一个 ant 的骨架, 但具体做起来才才发现很多东西不知道该如何写 下边介绍一下常用的 ant task 在 ant 手册中跟这些叫 core task 这里打乱一下顺序, 不按照文档中的顺序来介绍, 而是按照需求来介绍 6.1. 使用 classpath <target> <javac> <classpath refid="project.class.path"/> </javac> 6.2. 设置 classpath <classpath id= project.class.path > <pathelement path="${classpath}"/> <fileset dir="lib"> <include name="**/*.jar"/> <pathelement location="classes"/> <dirset dir="build"> <include name="apps/**/classes"/> <exclude name="apps/**/*test*"/> </dirset> <filelist refid="third-party_jars"/> </classpath> http://www.blogjava.net/dreamstone 14/32

http://www.blogjava.net/dreamstone 15/32 6.3. 输出信息 两种写法 6.3.1. 写法一 <echo message= xxx /> 6.3.2. 写法二 <echo>yyyy</echo> 6.3.3. 输出一段 xml <echoxml file="subbuild.xml"> <project default="foo"> <target name="foo"> <echo>foo</echo> </project> </echoxml> 6.4. 引入一个 xml 文件 <import file="../common-targets.xml"/> 6.5. 拷贝文件 6.5.1. 拷贝一个文件 <copy file="myfile.txt" tofile="mycopy.txt"/> 6.5.2. 拷贝一个文件到指定目录 <copy file="myfile.txt" todir="../some/other/dir"/> 6.5.3. 拷贝一个目录到另一个目录 <copy todir="../new/dir"> </copy> <fileset dir="src_dir"/> 6.5.4. 拷贝一个文件集合到一个目录 <copy todir="../dest/dir"> </copy> <fileset dir="src_dir"> <exclude name="**/*.java"/> <copy todir="../dest/dir"> </copy> <fileset dir="src_dir" excludes="**/*.java"/> http://www.blogjava.net/dreamstone 15/32

http://www.blogjava.net/dreamstone 16/32 6.5.5. 拷贝一个文件集合到一个目录, 同时建立备份文件 <copy todir="../backup/dir"> </copy> <fileset dir="src_dir"/> <globmapper from="*" to="*.bak"/> 6.5.6. 拷贝一个集合的文件到一个目录, 并替换掉 @ TITLE @ <copy todir="../backup/dir"> </copy> <fileset dir="src_dir"/> <filterset> <filter token="title" value="foo Bar"/> </filterset> 6.5.7. 拷贝一个目录下的东西到另一个目录下,(includes 加入,excludes 排除 ) <copydir src="${src}/resources" /> dest="${dist}" includes="**/*.java" excludes="**/test.java" 6.5.8. 拷贝一个文件 <copyfile src="test.java" dest="subdir/test.java"/> 6.6. 删除文件 目录拷贝中各种关于目录的操作都可以用在这里 6.6.1. 删除一个文件 <delete file="/lib/ant.jar"/> 6.6.2. 删除一个目录 <delete dir="lib"/> 6.6.3. 删除所有符合规则的文件 (.bak 文件 ) 包括子目录 <delete> <fileset dir="." includes="**/*.bak"/> </delete> 6.6.4. 删除当前目录下所有的文件和目录, 包括当前目录 <delete includeemptydirs="true"> <fileset dir="build"/> </delete> 6.6.5. 删除当前目录下所有的文件和目录, 不包括当前目录 <delete includeemptydirs="true"> <fileset dir="build" includes="**/*"/> </delete> http://www.blogjava.net/dreamstone 16/32

http://www.blogjava.net/dreamstone 17/32 6.6.6. 删除当前目录下所有的 svn 相关文件 ( 因为 svn 文件默认是 excludes 的, 所以这里要设置一下 ) <delete defaultexcludes="false"> </delete> <fileset dir="src" includes="**/.svn"/> 6.6.7. 删除文件目录树 <deltree dir="dist"/> 6.7. 剪切文件 <move todir="some/new/dir"> <fileset dir="my/src/dir"> <include name="**/*.jar"/> <exclude name="**/ant.jar"/> </move> 6.8. 重命名 <rename src="foo.jar" dest="ant-${version}.jar"/> 6.9. 建立临时文件 在目录 build 下, 建立文件名为 temp.file, 后缀为.xml 的文件 <tempfile property="temp.file" destdir="build" suffix=".xml"/> 6.10. Touch 的使用 6.10.1. 如果文件不存在, 创建文件, 如果存在, 更改最后访问时间为当前系统时间 <touch file="myfile"/> 6.10.2. 如果文件不存在, 创建文件, 更改最后访问时间为 06/28/2000 2:02 pm <touch file="myfile" datetime="06/28/2000 2:02 pm"/> 6.10.3. 更改目录下所有文件最后访问时间为 06/28/2000 2:02 pm <touch datetime="09/10/1974 4:30 pm"> <fileset dir="src_dir"/> </touch> http://www.blogjava.net/dreamstone 17/32

http://www.blogjava.net/dreamstone 18/32 6.11. Condition 的使用 有 <and>,<or>,<not> 等 tag <condition property="ismacosbutnotmacosx"> <and> <os family="mac"/> <not> <os family="unix"/> </not> </and> </condition> 6.12. 替换 replace <replace file="configure.sh" value="defaultvalue" propertyfile="source/name.properties"> <replacefilter token="@token1@"/> <replacefilter token="@token2@" value="value2"/> <replacefilter token="@token3@" property="property.key"/> </replace> 6.13. 调用 chmod <chmod perm="go-rwx" type="file"> <fileset dir="/web"> <include name="**/*.cgi"/> <include name="**/*.old"/> <dirset dir="/web"> <include name="**/private_*"/> </dirset> </chmod> http://www.blogjava.net/dreamstone 18/32

http://www.blogjava.net/dreamstone 19/32 6.14. checksum MD5 运算 6.14.1. md5 文件, 然后把值放入 foo.bar.md5 属性 <checksum file="foo.bar"/> 6.14.2. md5 文件, 然后把值放入 foobarmd5 属性 <checksum file="foo.bar" property="foobarmd5"/> 6.14.3. Md5 目录下的所有文件, 然后建立一个.md5 文件, 把所有的 md5 值放入 <checksum> <fileset dir="."> <include name="foo*"/> </checksum> 6.15. Available 的使用 6.15.1. 如果类存在, 则设置属性 Myclass.present 为 true, 如果没有就 false <available classname="org.whatever.myclass" property="myclass.present"/> 6.15.2. 如果文件存在则设置属性 jaxp.jar.presen 为 true, 否则为 false <property name="jaxp.jar" value="./lib/jaxp11/jaxp.jar"/> <available file="${jaxp.jar}" property="jaxp.jar.present"/> 6.15.3. 如果目录存在, 则设置属性为 true, 否则为 false <available file="/usr/local/lib" type="dir" property="local.lib.present"/> 6.15.4. 如果 classpath 下寻找 class, 如果存在则设置属性为 true, 否则为 false 在工程 tag 下定义 path, 在 target 中使用...in project... <property name="jaxp.jar" value="./lib/jaxp11/jaxp.jar"/> <path id="jaxp" location="${jaxp.jar}"/>...in target... <available classname="javax.xml.transform.transformer" classpathref="jaxp" property="jaxp11.present"/> 6.15.5. 如果在 classpath 下发现文件则设置属性为 true 否则为 flase <available property="have.extras" resource="extratasks.properties"> <classpath> <pathelement location="/usr/local/ant/extra.jar" /> </classpath> </available> http://www.blogjava.net/dreamstone 19/32

http://www.blogjava.net/dreamstone 20/32 6.16. 设置 property 6.16.1. 设置属性 name-value <property name="foo.dist" value="dist"/> 6.16.2. 读取属性文件中的属性配置 <property file="foo.properties"/> 6.16.3. 读取网络中的 property-set <property url="http://www.mysite.com/bla/props/foo.properties"/> 6.16.4. 读取文件中的属性配置 <property resource="foo.properties"/> 6.16.5. 读取环境变量 <property environment="env"/> 6.16.6. 读取属性文件中的属性, 并作为全局引用 <property file="/users/antoine/.ant-global.properties"/> 6.17. 出现一个错误 6.17.1. 显示错误方式一 <fail>something wrong here.</fail> 或者 6.17.2. 显示错误方式二 <fail message= ${ 属性 }. /> 6.17.3. 如果这个属性不存在显示错误 <fail unless="failcondition" message="unless Condition "/> 6.17.4. 如果这个属性存在现实错误 <fail if=" failcondition " message="if Condition "/> 6.17.5. 如果符合条件显示错误, 这里的条件是 ( 没有设置属性 ) <fail message="tag condition"> </fail> <condition> <not> <isset property=" failcondition "/> </not> </condition> 6.18. 建立一个目录 <mkdir dir="${dist}/lib"/> http://www.blogjava.net/dreamstone 20/32

http://www.blogjava.net/dreamstone 21/32 6.19. 打 jar 包 <jar destfile="${dist}/lib/app.jar" basedir="${build}/classes"/> 或者 <jar destfile="${dist}/lib/app.jar" basedir="${build}/classes" includes="mypackage/test/**" excludes="**/test.class" /> 6.20. 打 Ear 包 <ear destfile="build/myapp.ear" appxml="src/metadata/application.xml"> </ear> <fileset dir="build" includes="*.jar,*.war"/> 6.21. 执行程序 <target name="help"> <exec executable="cmd"> <arg value="/c"/> <arg value="ant.bat"/> <arg value="-p"/> </exec> 6.22. 运行 jar 包 : 6.22.1. 带参数执行 <java classname="test.main"> <arg value="-h"/> <classpath> <pathelement location="dist/test.jar"/> <pathelement path="/users/antoine/dev/asf/ant-core/bootstrap/lib/ant-launcher.jar /> </classpath> </java> http://www.blogjava.net/dreamstone 21/32

http://www.blogjava.net/dreamstone 22/32 6.22.2. 或者设置一下运行的 jvm 的最大内存, 来运行 <java classname="test.main" dir="${exec.dir}" jar="${exec.dir}/dist/test.jar" fork="true" failonerror="true" maxmemory="128m" > <arg value="-h"/> <classpath> <pathelement location="dist/test.jar"/> <pathelement path="/users/antoine/dev/asf/ant-core/bootstrap/lib/ant-launcher.jar /> </classpath> </java> 6.23. 编译程序 <javac srcdir="${src}" destdir="${build}" classpath="xyz.jar" debug="on" source="1.4" /> 6.24. 制作 Javadoc <javadoc... > <doclet name="thedoclet" path="path/to/thedoclet"> <param name="-foo" value="foovalue"/> <param name="-bar" value="barvalue"/> </doclet> </javadoc> 6.25. 定义一个新的 task 类库 <taskdef name="myjavadoc" classname="com.mydomain.javadoctask"/> http://www.blogjava.net/dreamstone 22/32

http://www.blogjava.net/dreamstone 23/32 6.26. 运行 sql <sql driver="org.database.jdbcdriver" url="jdbc:database-url" userid="sa" password="pass" > insert into table some_table values(1,2,3,4); truncate table some_other_table; </sql> 6.27. Filter 的使用 6.27.1. 把所有的 @year@ 替换成 2000 <filter token="year" value="2000"/> <copy todir="${dest.dir}" filtering="true"> <fileset dir="src"/> </copy> 6.27.2. 替换属性文件中的内容 <filter filtersfile="deploy_env.properties"/> 6.28. Length 的使用 6.28.1. 把字符串 foo 的长度保存到属性 "length.foo" 中 <length string="foo" property="length.foo" /> 6.28.2. 把文件 bar 的长度保存到属性 " length.bar " 中 <length file="bar" property="length.bar" /> 6.29. 输入 Input 提示消息 "Please enter db-username, 然后把用户的输入赋值给 db.user 如果没有输入则有默认值 Scott-Tiger <input message="please enter db-username:" addproperty="db.user" defaultvalue="scott-tiger" /> http://www.blogjava.net/dreamstone 23/32

http://www.blogjava.net/dreamstone 24/32 6.30. FixCRCL 的使用 6.30.1. 替换所有的 eol 变成 lf, 删除所有的 eof <fixcrlf srcdir="${src}" includes="**/*.sh" eol="lf" eof="remove" /> 6.30.2. 替换 eol 成 crlf 设置 tab 的长度为 4 <fixcrlf srcdir="${src}" includes="**/*.java" eol="crlf" tablength="4" /> 6.31. 发送邮件 <mail mailhost="smtp.myisp.com" mailport="1025" subject="test build"> <from address="config@myisp.com"/> <replyto address="me@myisp.com"/> <to address="all@xyz.com"/> <message>the ${buildname} nightly build has completed</message> <attachments> <fileset dir="dist"> <include name="**/*.zip"/> </attachments> </mail> 6.32. 压缩 解压缩 6.32.1. 解压缩 zip 文件 <unzip src="apache-ant-bin.zip" dest="${tools.home}"> </unzip> <patternset> <include name="apache-ant/lib/ant.jar"/> </patternset> <mapper type="flatten"/> 6.32.2. 压缩 zip 文件 <zip destfile="${dist}/manual.zip" /> basedir="htdocs/manual" includes="api/**/*.html" excludes="**/todo.html" http://www.blogjava.net/dreamstone 24/32

http://www.blogjava.net/dreamstone 25/32 6.32.3. 打 tar 包 <tar destfile="/users/antoine/dev/asf/ant-core/docs.tar"> <tarfileset dir="${dir.src}/docs" fullpath="/usr/doc/ant/readme" preserveleadingslashes="true"> <include name="readme.txt"/> </tarfileset> <tarfileset dir="${dir.src}/docs" prefix="/usr/doc/ant" preserveleadingslashes="true"> <include name="*.html"/> </tarfileset> </tar> 6.32.4. 解 tar 包 <untar src="tools.tar" dest="${tools.home}"/> 6.33. 打 war 包 : <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> 6.34. antcall 6.34.1. 调用 target dosomethingelse <target name="default"> <antcall target="dosomethingelse"> <param name="param1" value="value"/> </antcall> <target name="dosomethingelse"> <echo message="param1=${param1}"/> http://www.blogjava.net/dreamstone 25/32

http://www.blogjava.net/dreamstone 26/32 6.34.2. 拷贝父中的 path1, 然后再当前工程中命名为 path2 <antcall... > <reference refid="path1" torefid="path2"/> </antcall> 6.35. Ant 的使用 6.35.1. 调用目录 sub1/sub2/ 下的 build.xml <ant antfile="sub1/sub2/build.xml" /> 6.35.2. 同上, 不同的写法 <ant antfile="sub2/build.xml" dir="sub1" /> 6.35.3. 同上, 不同的写法 <ant antfile="build.xml" dir="sub1/sub2" /> 6.35.4. 调用指定文件中的指定 target (compile) <ant antfile="subproject/subbuild.xml" target="compile"/> http://www.blogjava.net/dreamstone 26/32

http://www.blogjava.net/dreamstone 27/32 7. 在 ant 中控制流程 (if else ) <?xml version="1.0" encoding="utf-8"?> <project basedir="." name="learn" default="run"> <property name="db.type" value="oracle" /> <import file="properties.xml" /> <taskdef resource="net/sf/antcontrib/antcontrib.properties" classpath="${ant-contrib.jar}" /> <target name="run"> <if> <equals arg1="${db.type}" arg2="mysql" /> <then> <echo message="the db is mysql" /> </then> <else> <echo message="the db is oralce" /> </else> </if> </project> 8. 实例分析 : 从开源框架中拿出一部分来分析一下 : 我接触的一些开源程序的 ant 中,appfuse 是比较复杂的,Jpetstore 是最简单的 这里拿一个最简单的出来, 然后一路注释过去 ( 想挑战一下的去看 appfuse 的 ) <project name="jpetstore" default="all" basedir="."> <! 定义属性 <property name="web" value="../web"/> <property name="src" value="../src"/> <property name="test" value="../test"/> <property name="lib" value="../lib"/> <property name="devlib" value="../devlib"/> <property name="wars" value="wars"/> <property name="warfile" value="${wars}/jpetstore.war"/> <property name="webapp" value="webapp"/> <property name="weblib" value="${webapp}/web-inf/lib/"/> <property name="webclasses" value="${webapp}/web-inf/classes/"/> <property name="reports" value="reports"/> <property name="junitreports" value="${reports}/junit/"/> <property name="coveragereports" value="${reports}/coverage/"/> http://www.blogjava.net/dreamstone 27/32

http://www.blogjava.net/dreamstone 28/32 <property name="work" value="work"/> <property name="classes" value="${work}/classes/"/> <property name="testclasses" value="${work}/testclasses/"/> <property name="instrumentedclasses" value="${work}/instrumentedclasses/"/> <! 定义 classpath <path id="classpath"> <pathelement location="${instrumentedclasses}"/> <pathelement location="${classes}"/> <pathelement location="${testclasses}"/> <pathelement location="${src}"/> <pathelement location="${test}"/> <fileset dir="${lib}" includes="**/*.jar"/> <fileset dir="${devlib}" includes="**/*.jar"/> </path> <! 引入新的 ant task 包, 可以使用一些 ant 默认没有的 tag 和 task <taskdef name="junit" classname="org.apache.tools.ant.taskdefs.optional.junit.junittask"/> <taskdef resource="emma_ant.properties" classpathref="classpath"/> <! 定义删除文件的 target, 清除 <target name="clean"> <delete dir="${reports}"/> <delete dir="${work}"/> <delete dir="${wars}"/> <delete dir="${webapp}"/> <delete file="coverage.ec"/> <delete> <fileset dir="${src}"> <include name="**/*.class"/> </delete> <delete> <fileset dir="${test}"> <include name="**/*.class"/> </delete> http://www.blogjava.net/dreamstone 28/32

http://www.blogjava.net/dreamstone 29/32 <! 创建所需的文件夹 <target name="prepare" depends="clean"> <mkdir dir="${classes}"/> <mkdir dir="${testclasses}"/> <mkdir dir="${instrumentedclasses}"/> <mkdir dir="${junitreports}"/> <mkdir dir="${coveragereports}"/> <mkdir dir="${webclasses}"/> <mkdir dir="${weblib}"/> <mkdir dir="${wars}"/> <! 编译 <target name="compile" depends="prepare"> <javac srcdir="${src}" destdir="${classes}" deprecation="on" debug="on"> <classpath refid="classpath"/> </javac> <javac srcdir="${test}" destdir="${testclasses}" deprecation="on" debug="on"> <classpath refid="classpath"/> </javac> <!--########### <target name="coverage.instrument" depends="compile"> <emma enabled="yes"> <instr instrpath="${classes}" destdir="${instrumentedclasses}" metadatafile="./coverage.ec" merge="true" > </instr> </emma> <! 测试 <target name="test" depends="coverage.instrument"> <junit printsummary="yes" haltonfailure="no"> <classpath refid="classpath"/> <formatter type="xml"/> <batchtest fork="yes" todir="${junitreports}"> <fileset dir="${test}"> <include name="**/*test*.java"/> <exclude name="**/alltests.java"/> </batchtest> </junit> http://www.blogjava.net/dreamstone 29/32

http://www.blogjava.net/dreamstone 30/32 <! 测试报告 <target name="test.report" depends="test" > <junitreport todir="${junitreports}"> <fileset dir="${junitreports}"> <include name="test-*.xml"/> <report format="frames" todir="${junitreports}"/> </junitreport> <target name="coverage.report" depends="test" > <emma enabled="yes"> <report sourcepath="${src}" sort="+block,+name,+method,+class" metrics="method:70,block:80,line:80,class:100" > <fileset dir="./"> <include name="*.ec"/> <html outfile="${coveragereports}/coverage.html" depth="method" columns="name,class,method,block,line" /> </report> </emma> <! 拷贝到一起 <target name="assemble" depends="test"> <copy todir="${webclasses}"> <fileset dir="${src}"> <exclude name="**/*.java"/> <exclude name="**/*.class"/> </copy> <copy todir="${webclasses}"> <fileset dir="${classes}"/> </copy> <copy todir="${weblib}"> <fileset dir="${lib}"/> </copy> <copy todir="${webapp}"> <fileset dir="${web}"/> </copy> http://www.blogjava.net/dreamstone 30/32

http://www.blogjava.net/dreamstone 31/32 <target name="assemblewebapp"> <copy todir="${webapp}"> <fileset dir="${web}"/> </copy> <! 打 war 包 <target name="war" depends="assemble"> <jar jarfile="${warfile}"> <fileset dir="${webapp}"> <include name="**/*"/> </jar> <target name="all" depends="test.report, coverage.report, war"/> </project> 9. 如何继续学习 掌握了上边的那些内容之后, 你就知道如何去写一个好的 ant, 但是你会发现当你真的想去做的时候, 你不能马上作出好的 build.xml, 因为你知道太少的 ant 的默认提供的命令. 这个时候如果你想完成任务, 并提高自己, 有很多办法 : 1, 很多开源的程序都带有 build.xml, 看看它们如何写的 2,ant 的 document, 里边详细列写了 ant 的各种默认命令, 及其丰富 3,google, 永远不要忘记它 ok, 在这之后随着你写的 ant build 越来越多, 你知道的命令就越多,ant 在你的手里也就越来越强大了 这个是一个慢慢积累的过程 10. Ant 使用 cvs 的实例 ant 的例子很好找, 各种开源框架都会带有一个 build.xml 仔细看看, 会有很大收获 另外一个经常会用到的, 但是在开远框架的 build.xml 一般没有的是 cvs 如果使用的是远程的 cvs, 可以这样使用 <?xml version="1.0" encoding="utf-8"?> <project> <property name="cvsroot" value=":pserver:wang:@192.168.1.2:/cvsroot"/> <property name="basedir" value="/tmp/testant/"/> <property name="cvs.password" value="wang"/> <property name="cvs.passfile" value="${basedir}/ant.cvspass"/> http://www.blogjava.net/dreamstone 31/32

http://www.blogjava.net/dreamstone 32/32 <target name="initpass"> <cvspass cvsroot="${cvsroot}" password="${cvs.password}" passfile="${cvs.passfile}"/> <target name="checkout" depends="initpass"> <cvs cvsroot="${cvsroot}" command="checkout" cvsrsh="ssh" package="myproject" dest="${basedir}" passfile="${cvs.passfile}"/> </project> 11. QA: 11.1. 如果执行 ant 过程中出现 Outofmemory 的错误怎么办? 答 : 加大内存, 设置环境变量 ANT_OPTS=-Xms128m -Xmx256m 12. 参考文献 : http://www.apache.org ant 官方手册, 文中大量引用了 ant 官方手册中的例子 http://www.blogjava.net/dreamstone 32/32