自动构建工具Ant的使用-笔记
第一:什么是Ant?
Apache Ant是一个基于Java的生成工具。据最初的创始人James Duncan Davidson的介绍,这个工具的名称是another neat tool(另一个整洁的工具)的首字母的缩写。
第二:到哪儿去找ant工具,地址:http://ant.apache.org/bindownload.cgi
第三:配置环境变量:如下图:
第四:用命令行测试下:
如果出现上述界面则证明Ant配置成功
第五:Ant的作用是什么?
生成工具在软件开发中用来将源代码和其他的输入文件转换为可执行文件的形式(也有可能转换为可安装的产品映像形式)。随着应 用程序的生产过程变得更加的复杂,确保在每次生成期间都使用精确相同的生成步骤,同时实现尽可能多的自动化,以便及时生产一致的生成版本,这就变得更加重 要。
Ant定义生成文件之间的依赖关系,它使用跨平台的Java类。使用Ant,就能够编写单个文件,这个生成文件在任何Java平台上都一致地操作(因为Ant本身也是使用Java语言来实现的),这就是Ant最大的优势
第六:初步使用,
例子:编写简单的build.xml(默认的,Ant会自动的在当前目录下去寻找这个文件,如果找的就去构建,如果找不到就会提示:build.xml does not exist!
在d盘下创建build.xml文件内容如下:
<?xml version="1.0" encoding="utf-8"?>
<project default="init">
<target name="init">
<mkdir dir="helloworld" />
</target>
</project>
意思是:在当前目录下创建一个名字为helloworld的目录,对应到windows磁盘就是一个文件夹
然后,运行ant:
看当前目录:
我们创建了一个helloworld这样的一个目录
第七:Ant生成文件解析
Ant没有定义自己的自定义语法;相反,它的生成文件是使用XML编写的。存在Ant能够理解的预定义XML元素,而且还可以定义新的元素来扩展Ant的功能。每个生成文件由单个project元素组成,该元素又包含一个或多个target元素。一个目标(target)是生成过程中已定义的一个步骤,它执行任意数量的操作,比如编译一组源文件。并且这些操作本身是由其他专用的任务标签执行的
顶级的project元素需要包含一个default属性,如果在Ant被调用时没有指定目标,这个属性将指定要执行的目标。然后需要使用target元素来定义该目标本身。
Ant中的属性类似编程语言中的变量,它们都具有名称和值。然而与通常的变量不同,一经设置,Ant中是属性就不可更改;它们是不可变的,就像Java语言中的String对象。这起初看起来似乎很有限制性,但这样是为了遵循Ant的简单原则:毕竟,它是一个生成工具,而非一种编程语言。如果尝试给某个现有的属性赋予一个新的值,这不会看作是一个错误,但是该属性仍然会保留其现有的值
定义与使用属性
<property name=”metal” value=”beryllium”/>
为了在生成文件的其他部分引用这个属性,使用以下语法:
${metal}
例如,为了使用这样一个值,它是另一个属性的值的组成部分,将标签写成下面这样
<property name=”metal-database” value=”${metal}.db”/>
属性经常用于引用文件系统上的文件或目录,但是对于使用不同路径分隔符(例如,/与|的平台来说,这样可能再跨越不同平台时导致问题。Ant的location属性专门设计用于以平台无关的方式包含文件系统路径。像下面这样使用location替代value:
<property name=”database-file” location=”archive/database/${metal}.db”/>
用于location属性的路径分隔字符将被转换为当前平台的正确格式;而且由于文件名是相对的,它被认为是相对于项目的基目录。我们同样可以容易地写为下面这样:
<property name=”database-file” location=”archive\database\${metal}.db”/>
这个标签的两个版本都会在不同的平台具有相同的行为
定义依赖关系:
生成一个项目一般需要许多步骤--例如首先要编译源代码,然后将它打包为Java归档文件(Java Archive File,JAR)。这其中许多步骤都具有清楚定义的顺序--例如,在编译器从源代码生成类文件之前,您不能打包类文件。与顺序指定target所不同的是,Ant采用一种更灵活的方法来定义依赖关系。每个目标的定义依据的是它能够执行之前必须完成的其他所有目标。这是使用target元素的depends属性来实现的
例如:
<target name=”init”/>
<target name=”preprocess” depends=”init”/>
<target name=”compile” depends=”init,preprocess”/>
<target name=”package” depends=”compile”/>
这种方法允许您执行项目任何阶段的生成过程;Ant会首先执行已定义的先决阶段。在上面的例子中,如果让Ant完成complie步骤,它将判断出需要首先执行init和和preprocess这两个目标。Init目标不依赖其他任何目标,因此它将首先被执行。然后Ant检查preprogress target,发现它依赖init目标;由于已经执行后者,Ant不会再次执行它,因此开始执行preprocess目标。最后可以执行compile任务本身。
注意目标出现在生成文件中的顺序并不重要:执行顺序是由depends属性唯一确定的。
第八:尝试在IDE里面是有
在工程的根目录下建议个build.xml
内容:
<?xml version="1.0" encoding="utf-8"?>
<project name="myAntProject" default="package" basedir=".">
<property name="hello" value="hello123"></property>
<property name="welcome" value="welcome123"></property>
<target name="init"/>
<target name="preprocess" depends="init">
<mkdir dir="${hello}"/>
<mkdir dir="${welcome}"/>
</target>
<target name="compile" depends="init,preprocess"/>
<target name="package" depends="compile"/>
</project>
跑一下:
生成hello123、和welcom123两个文件夹
备注:Ant还支持debug
从命令提示符调用Ant可以简单键入单独的Ant。如果这样做,Ant将使用默认的生成文件;该生成文件中指定的默认目录就是Ant尝试要生成的目标。还可以指定许多命令行选项,后面跟着任意数量的生成目录,Ant将按顺序生成这其中的每个目标,并在此过程中解决所有依赖关系
默认情况下,Ant寻找一个名为build.xml的文件。因此,如果你的生成文件使用这个名称,就不需要在命令行指定它。当然,有时使用具有其他名称的生成文件更方便,在那样的情况下,你需要对Ant使用-buildfie<file>参数(-f <file>是其简写形式)
另一个有用的选项是-D,它用于设置随后可以再生成文件中使用的属性。。这对于配置你想要的以某种方式开始的生成过程非常有用。例如,为了将name属性设置为某个特定的值,你会使用类似下面这样的选项:
--Dmetal!=beryllium
这个功能可用于覆盖生成文件中初始属性设置。正如前面指出过的,属性的值一经设置就不能改变。-D标志在读取生成文件中的任何信息之前设置某个属性;由于生成文件中的指派落在这个初始指派之后,因此它不会改变其值
编译java源代码
build.xml
<?xml version="1.0" encoding="utf-8"?>
<project name="myAntProject" default="package" basedir=".">
<property name="compile" value="compile"></property>
<target name="init"></target>
<target name="preprocess" depends="init">
<mkdir dir="${compile}"/>
</target>
<target name="compile" depends="init,preprocess"></target>
<target name="package" depends="compile"></target>
<target name="myCompile" depends="preprocess">
<javac srcdir="src" destdir="${compile}"></javac>
</target>
</project>
其他有用的属性包括
-classpath:等级于javac的-classpath选项。
-debug=”true”:指示编译器应该带调试信息编译源文件。
Javac任务的一个重要的特点在于,它仅编译那些它认为需要编译的源文件。如果某个类文件已经存在,并且对应的源文件自从该类文件生成以来还没改变过,那么该源文件就不会被重新编译。
Javac任务的输出显示了实际被编译的源文件的数目。
这种行为刻画了Ant的许多任务的特点:如果某个任务能够确定所请求的操作不需要执行,那么该操作就会被跳过。
创建JAR文件
在编译Java源文件之后,结果类文件通常被打包到一个JAR文件中,这个文件类似zip归档文件,它可以指定该JAR文件的属性
下面是Ant中jar任务的一个简单使用例子:
<jar destfile=”package.jar” basedir=”classes”/>
这将创建一个名为package.jar的jar文件,并把classes目录中所有文件添加到其中(JARwe文件能够包含任意类型的文件,而不只是类文件)。此处没有指定清单文件,因此Ant将提供一个基本的清单文件
Mainifest属性允许指定一个用作JAR文件的清单的文件。清单文件的内容还可以使用mainifest任务在生成文件中指定。这个任务能够向文件系统写入一个清单文件,或者能够实际嵌套在Jar之内,以便一次性地创建清单文件和JAR文件。
Build.xml
<?xml version="1.0" encoding="utf-8"?>
<project name="myAntProject" default="package" basedir=".">
<property name="compile" value="compile"></property>
<property name="dist" value="dist"></property>
<target name="init"></target>
<target name="preprocess" depends="init">
<mkdir dir="${compile}"/>
<mkdir dir="${dist}"/>
</target>
<target name="compile" depends="init,preprocess"></target>
<target name="package" depends="compile"></target>
<target name="myCompile" depends="preprocess">
<javac srcdir="src" destdir="${compile}">
</javac>
</target>
<target name="dist" depends="myCompile">
<jar destfile="${dist}/package.jar" basedir="${compile}"></jar>
</target>
</project>
生成双击运行的程序
新建一个类:
内容:
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Test3 {
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setSize(new Dimension(200,300));
frame.setBackground(new Color(200,200,200));
frame.setAlwaysOnTop(true);
frame.getContentPane().add(new JButton("Ant"));
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Build.xml
<?xml version="1.0" encoding="utf-8"?>
<project name="myAntProject" default="package" basedir=".">
<property name="compile" value="compile"></property>
<property name="dist" value="dist"></property>
<target name="init"></target>
<target name="preprocess" depends="init">
<mkdir dir="${compile}"/>
<mkdir dir="${dist}"/>
</target>
<target name="compile" depends="init,preprocess"></target>
<target name="package" depends="compile"></target>
<target name="myCompile" depends="preprocess">
<javac srcdir="src" destdir="${compile}">
</javac>
</target>
<target name="dist" depends="myCompile">
<jar destfile="${dist}/package.jar" basedir="${compile}">
<manifest>
<attribute name="Built-By" value="${user.name}"/>
<attribute name="Main-Class" value="Test3"/>
</manifest>
</jar>
</target>
</project>
MAINIFEST.MF文件:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.1
Created-By: 11.3-b02 (Sun Microsystems Inc.)
Built-By: Administrator
Main-Class: Test3
时间戳生成
-在生成环境中使用当前时间和日期,以某种方式标记某个生成任务的输出,以便记录它是何时生成的,这经常是可取的。这可能涉及编辑一个文件,以便插入一个字符串来指定日期和时间,或将这个信息合并到JAR或者zip文件的文件名中
-这种需要是通过简单但是非常有用的tstamp任务来解决的。这个任务通常在某次生成过程开始时调用,比如在一个init目标中。这个任务不需要属性,许多情况下只需要<tstamp/>就足够了
在调用tstamp任务之后,我们能够根据日期命名该JAR文件,如下所示:
<jar destfile=”package-${DSTAMP}.jar” basedir=”classes”/>
Build.xml
<?xml version="1.0" encoding="utf-8"?>
<project name="myAntProject" default="package" basedir=".">
<property name="compile" value="compile"></property>
<property name="dist" value="dist"></property>
<target name="init"></target>
<target name="preprocess" depends="init">
<mkdir dir="${compile}"/>
<mkdir dir="${dist}"/>
</target>
<target name="compile" depends="init,preprocess"></target>
<target name="package" depends="compile"></target>
<target name="myCompile" depends="preprocess">
<javac srcdir="src" destdir="${compile}">
</javac>
</target>
<target name="dist" depends="myCompile">
<tstamp></tstamp>
<jar destfile="${dist}/package-${DSTAMP}.jar" basedir="${compile}">
<manifest>
<attribute name="Built-By" value="${user.name}"/>
<attribute name="Main-Class" value="Test3"/>
</manifest>
</jar>
</target>
</project>
生成带时间戳的Jar包
创建和删除目录
-最基本的文件系统操作之一就是创建目录或文件夹。做这项工作的任务名称为mkdir
-<mkdir dir=”archive/metals/zinc”/>
-mkdir任务的另一个有用的特性是它的如下能力:在父目录还不存在时创建它们
-如果目标目录已经存在,mkdir任务不会发出错误消息,而只是假设它的工作已经完成,从而什么也不做
删除目录
-<delete dir=”archive/metals/zinc”/>
-这将删除指定的目录连同它包含的所有文件以及子目录。使用file属性而不是dir属性可以指定要删除的单个文件
复制移动文件目录
<copy file=”src/Test.java” tofile=”src/TestCopy.java”/>
还可以使用move来执行重命名操作而不是拷贝文件
<move file=”src/Test.java” tofile=”src/TestCopy.java”/>
另一个常用的文件系统操作是将文件复制或在移动到另一个目录
<copy file=”src/Test.java” todir=”archive”/>
<move file=”src/Test.java” tofile=”archive”/>
默认情况下,Ant仅输出它执行的移动和复制操作的摘要,包括诸如已移动或复制的文件的数量等信息。如果想看到更详细的信息,包括涉及的文件名称等,可以将verbose属性设置为true
创建和压缩zip文件
<zip destfile=”output.zip” basedir=”output”/>
解压缩和提取文件
<unzip src=”output.tar.gz” dest=”extnacDir”/>
替换文件中的标记
replace任务,它执行文件中的查找和替换操作
Token属性指定要查找的字符串,value属性指定一个新的字符串,查找到的标记字符串的所有实例都被替换为这个新的字符串。例如:
<replace file=”input.txt” token=”old” value=”new”/>
还有其他很多的功能,如模式匹配、与CVS版本控制结合等等的高端功能
--自定义属性
使用自定义任务来扩展ANT
我们将考察一个简单的自定义任务的构造过程。这个任务将对文件中的行执行顺序操作,并将排序后的行集写到一个新文件中
为实现一个简单的自定义任务,我们所需做的就是扩展org.apache.tools.ant.Task类,并重写execute()方法。
大多数任务,不过是核心任务还是自定义任务,都利用属性来控制它们的行为。对应这个简单的任务,我们需要一个属性来指定要排序的文件,需要另一个属性来指定排序内容的输出。我们把这两个属性分别叫做file和tofile
例子:
新建一个名称为:com.shengsiyuan.ant.tools.extend的包
新建类FileSorter:
package com.shengsiyuan.ant.tools.extend;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
public class FileSorter extends Task{
private File srcFile;
private File destFile;
public File getSrcFile() {
return srcFile;
}
public void setSrcFile(File srcFile) {
this.srcFile = srcFile;
}
public File getDestFile() {
return destFile;
}
public void setDestFile(File destFile) {
this.destFile = destFile;
}
@Override
public void execute() throws BuildException
{
try{
BufferedReader fromFile = new BufferedReader(new FileReader(srcFile));
BufferedWriter toFile = new BufferedWriter(new FileWriter(destFile));
List<String> list = new ArrayList<String>();
String line = fromFile.readLine();
while(line != null)
{
list.add(line);
line = fromFile.readLine();
}
Collections.sort(list);
for(ListIterator<String> li = list.listIterator();li.hasNext();){
String str = li.next();
toFile.write(str);
toFile.newLine();
}
fromFile.close();
toFile.close();
}catch(Exception ex){
ex.printStackTrace();
}
}
}
定义任务:
<taskdef name="myFileSorterExample" classname="com.shengsiyuan.ant.tools.extend.FileSorter" classpath="bin">
</taskdef>
使用自定义任务:
<target name="myFileSorter">
<myFileSorterExample srcFile="input.txt" destFile="output.txt"/>
</target>
Input.txt的内容:
模式匹配
可以对目录执行模式匹配。例如,模式src*/*.java将匹配带src前缀的任何目录中的所有Java文件。
还有另一种模式结构:**,它匹配任意数量的目录。例如,模式**/*.java将匹配当前目录结构下的所有Java文件。
<copy todir=”archive”>
-<fileset dir=”src”>
.<include name=”*.java”/>
-</fileset>
</copy>
fileset默认情况下包含指定src目录下的所有文件,因此为了仅选择Java文件,我们对模式使用一个include元素。类似地,我们可以对另一个模式添加一个exclude元素,从而潜在地排除include指定的匹配项。甚至可以指定多个include和exclude元素;这样将得到一组文件和目录,它们包含include模式的所有匹配项的并集,但排除了exclude模式的所有匹配项
自动构建工具Ant的使用-笔记的更多相关文章
- 项目管理及自动构建工具Maven
项目管理及自动构建工具Maven 一.Maven安装.目录结构.cmd命令1.下载安装apache-maven-3.2.3-bin.zip下载:http://maven.apache.org/down ...
- 关于node.js和npm,cnpm的安装记录以及gulp自动构建工具的使用
关于node.js和npm,cnpm的安装记录以及gulp自动构建工具的使用 工作环境:window下 在一切的最开始,安装node.js (中文站,更新比较慢http://nodejs.cn/) ...
- 自动构建工具Gulp
摘要: gulp与grunt一样,都是自动构建工具.和grunt相比它更突出一个流的概念,任务是一个接一个执行的.今天就分享如何用gulp做自动化. 安装: gulp也是基于node环境,所以安装g ...
- 构建工具 Ant、Maven和Gradle
构建工具的作用 依赖管理 测试,打包,发布 主流的构建工具 Ant:提供编译,测试,打包 Maven:在Ant的基础上提供了依赖管理和发布的功能 Gradle:在Maven的基础上使用Groovy管理 ...
- 跨平台自动构建工具v1.0.2 发布
XMake是一个跨平台自动构建工具,支持在各种主流平台上构建项目,类似cmake.automake.premake,但是更加的方便易用,工程描述语法更简洁直观,支持平台更多,并且集创建.配置.编译.打 ...
- 项目自动构建工具对比(Maven、Gradle、Ant)
Java世界中主要有三大构建工具:Ant.Maven和Gradle.经过几年的发展,Ant几乎销声匿迹.Maven也日薄西山,而Gradle的发展则如日中天. Maven的主要功能主要分为5点,分别是 ...
- java构建工具——ant使用
Ant是跨平台的构建工具,它可以实现项目的自动构建和部署等功能.在本文中,主要让读者熟悉怎样将Ant应用到Java项目中,让它简化构建和部署操作. 一.安装与部署 1.1 下载 下载地址:https: ...
- Java构建工具Ant小记(一)
Ant简介 Ant是基于java的构建工具.理论上来说它类似与make工具,但是却克服了make的一些固有的缺陷. 传统的Make是基于操作系统shell的构建工具,虽然也可以基于工作的os对make ...
- 项目构建工具ant的使用
ant是项目构建工具,以xml文件作为构建文件,在这个xml文件(默认是build.xml,当然也可以取其它名字)里我们可以定义多个目标,用我们期待的方式去构建项目,比如说编译,测试,发邮件等等. a ...
随机推荐
- 快速定位隐蔽的sql性能问题及调优【转载】
在前几天,有个开发同事问我一个问题,其实也算是技术救援,他说在有个job数据处理的频率比较高,在测试环境中很难定位出在哪有问题,而且速度也还能接 受,但是在生产环境中总是会慢一些,希望我能在测试环境中 ...
- debian下安装AMD驱动
参考:http://blog.sciencenet.cn/blog-296919-464464.html 去AMD官网下载对应的驱动: amd-driver-installer-catalyst-13 ...
- nyoj10 滑雪
dp[ i][j]=max(四个方向点)+1: 四个方向上的点应该存在,且大于i,j,表示以i,j开始的点最长路径,递归的结束条件不用判断,因为 dp[][]最大数位置肯定 直接结束,随后次大值肯定能 ...
- javaNIO(转载)
(一) Java NIO 概述 Java NIO 由以下几个核心部分组成: Channels Buffers Selectors 虽然Java NIO 中除此之外还有很多类和组件,但在我看来,Chan ...
- Java到底是不是一种纯面向对象语言?
本文由码农网 – Dee1024原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划! Java——是否确实的 “纯面向对象”?让我们深入到Java的世界,试图来证实它. 在我刚开始学习 J ...
- storm核心组件
Storm核心组件 了解 Storm 的核心组件对于理解 Storm 原理非常重要,下面介绍 Storm 的整体,然后介绍 Storm 的核心. Storm 集群由一个主节点和多个工作节点组成.主节点 ...
- hdoj 3572 Task Schedule【建立超级源点超级汇点】
Task Schedule Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- 【三支火把】---一份程序看懂C程序printf()的几种常用用法
闲来继续巩固我的学习之路,今天略微整理了一下,C程序中Printf()的一些常用用法,虽然自己以前好像会,但是不够系统,今天大致整理了一些,先贴上来看看,以后在看到其他,继续补充,希望能帮到一些像我一 ...
- Redis: OOM command not allowed when used memory > ‘maxmemory
Redis: OOM command not allowed when used memory > ‘maxmemory’ 解决方式: $ vim /etc/redis/6903.conf ma ...
- hdu 1039 Easier Done Than Said? 字符串
Easier Done Than Said? Time Limi ...