`
aerchi
  • 浏览: 425398 次
  • 性别: Icon_minigender_1
  • 来自: 昆明
文章分类
社区版块
存档分类
最新评论

一个适合初学者的Ant教程

 
阅读更多

一个适合初学者的Ant教程

一,构建ant环境

要使用ant首先要构建一个ant环境,步骤很简单:

1),安装jdk,设置JAVA_HOME ,PATH ,CLASS_PATH(这些应该是看这篇文章的人应该知道的)

2),下载ant 地址www.apache.org找一个你喜欢的版本,或者干脆最新的版本

3),解压ant 你得到的是一个压缩包,解压缩它,并把它放在一个尽量简单的目录,例如D:\ant-1.6虽然你不一 定要这么做,但这么做是有好处的。

4),设置ANT_HOME PATH中添加ANT_HOME目录下的bin目录

5),测试一下你的设置,开始-->运行-->cmd进入命令行-->键入 ant 回车,如果看到

Buildfile: build.xml does not exist!

Build failed

那么恭喜你你已经完成ant的设置

二,体验ant

就像每个语言都有HelloWorld一样,一个最简单的应用能让人感受一下Ant

1,首先你要知道你要干什么,我现在想做的事情是:

编写一些程序

编译它们

把它打包成jar包

把他们放在应该放置的地方

运行它们

这里为了简单起见只写一个程序,就是HelloWorld.java程序代码如下:

package test.ant;

public class HelloWorld{

public static void main(String[] args){

System.out.println("Hello world1");

}

};

2,为了达到上边的目的,你可以手动的用javac 、copy 、jar、java来完成,但是考虑一下如果你有成百上千个类,在多次调试,部署的时候,一次次的javac 、copy、jar、java那将是一份辛苦的工作。现在看看ant怎么优雅的完成它们。

要运行ant需要有一个build.xml虽然不一定要叫这个名字,但是建议你这么做

下边就是一个完整的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>

<target name="compile" depends="init">

<javac srcdir="${src}" destdir="${dest}"/>

</target>

<target name="build" depends="compile">

<jar jarfile="${hello_jar}" basedir="${dest}"/>

</target>

<target name="run" depends="build">

<java classname="test.ant.HelloWorld" classpath="${hello_jar}"/>

</target>

<target name="clean">

<delete dir="${dest}" />

<delete file="${hello_jar}" />

</target>

<target name="rerun" depends="clean,run">

<ant target="clean" />

<ant target="run" />

</target>

</project>

解释:

<?xml version="1.0" encoding="UTF-8" ?>

build.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>

把你想做的每一件事情写成一个target ,它有一个名字,depends是它所依赖的target,在执行这个target 例如这里的compile之前ant会先检查init是否曾经被执行过,如果执行过则直接直接执行compile,如果没有则会先执行它依赖的target例如这里的init,然后在执行这个target

如我们的计划

编译:

<target name="compile" depends="init">

<javac srcdir="${src}" destdir="${dest}"/>

</target>

做jar包:

<target name="build" depends="compile">

<jar jarfile="${hello_jar}" basedir="${dest}"/>

</target>

运行:

<target name="run" depends="build">

<java classname="test.ant.HelloWorld" classpath="${hello_jar}"/>

</target>

为了不用拷贝,我们可以在最开始定义好目标文件夹,这样ant直接把结果就放在目标文件夹中了

新建文件夹:

<target name="init">

<mkdir dir="${dest}"/>

</target>

为了更多一点的功能体现,又加入了两个target

删除生成的文件

<target name="clean">

<delete dir="${dest}" />

<delete file="${hello_jar}" />

</target>

再次运行,这里显示了如何在一个target里边调用其他的target

<target name="rerun" depends="clean,run">

<ant target="clean" />

<ant target="run" />

</target>

好了,解释完成了,下边检验一下你的ant吧

新建一个src的文件夹,然后把HelloWorld.java按照包目录放进去

做好build.xml文件

在命令行下键入ant ,你会发现一个个任务都完成了。每次更改完代码只需要再次键入ant

有的时候我们可能并不想运行程序,只想执行这些步骤中的某一两个步骤,例如我只想重新部署而不想运行,键入

ant build

ant中的每一个任务都可以这样调用ant + target name

好了,这样一个简单的ant任务完成了。

ANT教程

技术应用 2009-11-02 01:06 阅读18 评论0 字号: 大大 中中 小小 第一部分

本文以最新发布的Ant 1.5.1为例,介绍这款优秀的Build工具的安装配置、基本应用和一些高级话题。最新的Ant下载地址是 http://jakarta.apache.org/ant/ 。

Ant是一种基于Java的Build工具。理论上来说,它有些类似于C中的make,但比make优越。现在存在的大多数Build工具,如make、gnumake、nmake、jam等都存在这样或那样的不足,比如依赖于特定的平台、配置文件过于复杂或者对格式无法检查而容易出错等。与这些工具相比较,Ant的两个特性决定了它是一款优秀的Build工具:

1. 基于Java的实现。具有良好的跨平台性,同时可以通过增加新的Java类来扩展Ant的功能,而无需去了解不同平台上不同的脚本语言。

2.基于XML的配置文件。Ant以XML树来描述Target/Task的关系,文件结构清晰、易读易写,并且利用XML对格式的控制来避免由于配置文件的错误造成的Build操作失败。

安装与配置

Ant的安装非常简单,把从网上下载的jakarta-ant-1.5.1-bin.zip解开到一个目录下即可(以下假定安装在目录D:\jakarta-ant-1.5.1)。接下来需要进行环境变量配置:SET ANT_HOME=D:\jakarta-ant-1.5.1 //注意是Ant的安装目录,不是bin子目录

SET PATH=%PATH%;%ANT_HOME%\bin;

在配置环境变量之前,请确认已经正确设置了JAVA_HOME系统变量。输入ant命令,看到如下输出说明已成功安装了Ant工具:

Buildfile: build.xml does not exist!

Build failed

提示信息表明在当前目录不存在build.xml配置文件,但这本身已经说明Ant成功运行了。

快速入门

下面用一个最简单也是最经典的例子-HelloWorld来感受一下Ant吧。

//HelloWorld.java

package com.sharetop.antdemo;

public class HelloWorld {

public static void main( String args[] ) {

System.out.println("Hello world. ");

}

}

要让Ant编译这个文件,首先需要编写一个Build配置文件。在一般情况下,这个文件被命名为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="hello.jar" />

<target name="init">

<mkdir dir="${dest}"/>

</target>

<target name="compile" depends="init">

<javac srcdir="${src}" destdir="${dest}"/>

</target>

<target name="build" depends="compile">

<jar jarfile="${hello_jar}" basedir="${dest}"/>

</target>

<target name="run" depends="build">

<java classname="com.sharetop.antdemo.HelloWorld" classpath="${hello_jar}"/>

</target>

</project>

来看一下这个文件的内容,它描述了以下信息:工程的名字为HelloWorld,工程有四个target,分别是init、compil、build和run,缺省是run。compile只有一个任务javac,源文件位于src目录下,输出的类文件要放在classes目录下。build的任务是jar,生成的jar文件为hello.jar,它打包时以classes为根目录。而run则是执行这个HelloWorld类,用hello.jar作为classpath。这四个target之间有一个依赖关系,这种关系用depends来指定。即如果Target A依赖于Target B,那么在执行Target A之前会首先执行Target B。所以从下面运行缺省Target(run)的输出看,这四个Target的执行顺序是:init→compile→build→run。文件目录结构如图1所示。HelloWorld.java文件在src\com\sharetop\antdemo子目录下。

图1 ant_demo应用的目录结构

在命令行输入命令:ant,然后运行,可以看到如下输出:

如果配置文件名不是build.xml,比如是build_front.xml,那么,可以使用-buildfile命令参数指定:

G:\myDoc\ant_demo>ant -buildfile build_front.xml

也可以单独执行指定的某个target,比如,只编译不打包执行,可以使用下面输入命令即可:

G:\myDoc\ant_demo>ant compile

在相应的目录下会找到编译出的HelloWorld.class文件。

再看看上面的build.xml配置文件,文件开头定义了3个属性,分别指定了源文件输出路径、类文件输出路径和生成的Jar文件名,后面对这些路径的引用都通过一个${property name}来引用。所以,要注意这样一个原则“目录的定义与目录的引用应该分开”。

第二部分

基本应用

建立工程的目录

一般要根据工程的实际情况来建立工程的目录结构。但是,有一些比较通用的组织形式可供参考,比如所有的jakarta项目都使用类似的目录结构。下面让我们来看一下这种目录结构的特点。

表1

目录 文件

bin 公共的二进制文件,以及运行脚本

build 临时创建的文件,如类文件等

dist 目标输出文件,如生成Jar文件等。

doc/javadocs 文档。

lib 需要导出的Java包

src 源文件

对于一个简单的工程,一般包括表1的几个目录。其中bin、lib、doc和src目录需要在CVS的控制之下。当然在这样的目录结构上,也可以做一些调整,例如,可以建立一个extra目录来放置需要发布的Jar文件、Inf文件及图像文件等。同样,如果开发Web应用可以建立一个Web目录放置JSP、HTML等文件。

如果我们开发的是一个比较复杂的项目,包括多个子项目,并且各个子项目是由不同的开发人员来完成的,那么要如何来设计它的目录结构?首先有一点是需要确定的,不同的子项目应该拥有不同的Build文件,并且整个项目也应该有一个总的Build文件。可以通过Ant任务或是AntCall任务调用子项目的Build文件,如下例:

<target name="core" depends="init">

<ant dir="components" target="core"/>

<ant dir="waf/src" target="core"/>

<ant dir="apps" target="core"/>

</target>

在各个子项目的耦合不是非常紧密的情况下,各个子项目应该有各自独立的目录结构,也就是说它们可以有自己的src、doc、build、dist等目录及自己的build.xml文件,但是可以共享lib和bin目录。而对于那些耦合紧密的子项目,则推荐使用同一个src目录,但是不同的子项目有不同的子目录,各个子项目的build.xml文件可以放在根目录下,也可以移到各个子项目的目录下。

编写Build文件

要用好Ant工具,关键是要编写一个build.xml文件。要编写出一个结构良好、灵活可扩展的Build文件,有两个问题要考虑,一是了解Build文件的基本结构,二是了解Ant定义的大量任务。

Ant的Build文件是一个标准的XML文件,它包含一个根节点Project,每个Project定义了至少一个或多个Target,每个Target又是一系列Task的集合。它们之间的关系如图2所示。

图2 build.xml文件的结构

每个Task是一段可被执行的代码,比如,前例中的javac、jar就是两个最常用的Task。Ant定义了大量的核心Task,我们要考虑的第二个问题正是如何去掌握这大量的Task。其实唯一的方法就是边学习边实践,这方面最好的参考就是官方的Ant使用手册。

外部文件的使用

使用外部的Property文件可以保存一些预设置的公共属性变量。这些属性可以在多个不同的Build文件中使用。

可以将一个外部的XML文件导入Build文件中,这样多个项目的开发者可以通过引用来共享一些代码,同样,这也有助于Build文件的重用,示例代码如下所示:

<!DOCTYPE project [

<!ENTITY share-variable SYSTEM "file:../share-variable.xml">

<!ENTITY build-share SYSTEM "file:../build-share.xml">

]>

<project name="main" default="complie" basedir=".">

&share-variable;

&build-share;

... ...

在J2EE项目中的应用

只要掌握了Ant的使用方法,在J2EE项目中的应用与在其它项目中的应用并没有太大的不同,但是仍有几点是需要注意的。

一是要清楚War和Jar文件的目录结构,主要是War的配置文件web.xml文件的位置和EJB的配置文件(ejb-jar.xml和weblogic-ejb-jar.xml等)的位置,在调用Jar任务打包文件时一定要记得把它们也包含进来。一般在编译之前就要注意把这些需打包的文件拷入相应目录下。二是在J2EE项目中可能会涉及到一些特殊的任务,比如在Weblogic中会调用ejbc预编译EJB的代码存根,或者需要在Ant中同时发布Jar到相应的服务器中等。可以用两种途径实现这些任务,一是扩展Ant任务实现这些任务,二是直接用Java任务来执行这些命令。下面是打包、发布一个EJB的build.xml配置文件片断,代码如下:

<target name="deploy_HelloEJB" depends="compile">

<delete dir="${temp}/ejb_make"/> <!-- 首先删除临时目录 -->

<delete file="${temp}/helloEJB.jar"/>

<!-- 删除WebLogic域中老版本的EJB -->

<delete file="${weblogic.deploy.dest}/helloEJB.jar"/>

<!-- 创建META-INF目录,放置ejb-jar.xml和weblogic-ejb-jar.xml -->

<mkdir dir="${temp}/ejb_make/META-INF"/>

<!-- 拷贝ejb-jar.xml和weblogic-ejb-jar.xml 到临时目录-->

<copy todir="${temp}/ejb_make/META-INF">

<fileset dir="etc/baseinfo">

<include name="*.xml"/>

</fileset>

</copy>

<!-- 拷贝所有的helloEJB类到临时目录 -->

<copy todir="${temp}/ejb_make/">

<fileset dir="${dest.classes}/"> <!-- dest.classes是输出的类文件目录 -->

<include name="${dest.classes}/helloEJB/**"/>

</fileset>

</copy>

<!-- 将所有这些文件打包成helloEJB.jar -->

<jar jarfile="${temp}/helloEJB.jar" basedir="${temp}/ejb_make"/>

<!-- 进行weblogic.ejbc编译 -->

<java classpath="${wl_cp}" classname="weblogic.ejbc" fork="yes" >

<classpath>

<fileset dir="lib">

<include name="*.jar" />

</fileset>

</classpath>

<arg value="${temp}/helloEJB.jar" />

<arg value="${temp}/helloEJB_deploy.jar" />

</java>

<!-- 拷贝/发布到WebLogic的{DOMAIN}\applications目录 -->

<copy file="${temp}/helloEJB_deploy.jar" todir="${weblogic.deploy.dest}"/>

</target>

用Ant配合JUnit实现单元测试

Ant 提供了JUnit任务,可以执行单元测试代码。如何使用JUnit,以及如何编写测试用例(TestCase),感兴趣的读者可以参阅JUnit的相关文档。在Ant中使用JUnit的方法非常简单,首先需要把junit.jar拷入ANT_HOME\lib下,确认在这个目录下有optional.jar,因为JUnit是Ant的扩展任务,需要引用这个扩展包。然后就是在Build文件中加入JUnit的任务,代码如下:

<target name="run" depends="client">

<junit printsummary="yes" fork="yes" haltonfailure="yes">

<classpath>

<pathelement location="client.jar" />

</classpath>

<formatter type="plain" />

<test name="com.sharetop.antdemo.HelloWorldTest" />

</junit>

</target>

高级话题

为Ant开发扩展任务

为Ant实现扩展任务其实是非常容易的,只需按照以下几个步骤即可:

1. 创建一个Java类继承org.apache.tools.ant.Task类;

2. 对每个属性实现set方法。Ant会根据需要自动完成类型转换;

3. 如果扩展的任务需要嵌套其它的Task,那么这个Java类必需实现接口org.apache.tools.ant.TaskContainer;

4. 如果扩展的任务要支持Text,需要增加一个方法void addText(String);

5. 对每个嵌套的元素,实现create、add 或 addConfigured 方法;

6. 实现public void execute方法;

7. 在build.xml文件中使用 <taskdef> 来引用自定义的Task。

下面以一个简单的例子来说明如何为Ant增加一个hello任务,它可以连续打印多条信息,打印的次数由属性count指定,而打印的内容则由它内嵌的一个helloinfo任务的message属性指定,看上去这非常类似JSP中自定义标签的一些概念,实现代码如下:

//HelloInfoTask.java

package com.sharetop.antdemo;

import org.apache.tools.ant.*;

public class HelloInfoTask {

private String msg;

public void execute() throws BuildException {

System.out.println(msg);

}

public void setMessage(String msg) {

this.msg = msg;

}

}

下面是外部Task类的代码:

//HelloTask.java

package com.sharetop.antdemo;

import org.apache.tools.ant.*;

public class HelloTask extends Task implements org.apache.tools.ant.TaskContainer

{

private Task info;

private int count;

public void execute() throws BuildException {

for(int i=0;i<count;i++)

info.execute();

}

public void setCount(int c){

this.count=c;

}

public void addTask(Task t){

this.info=t;

}

}

实现了这两个Task,在build.xml文件中定义它的task name,就可以在Target中执行它了。如果你不想使用 <taskdef> 标签来定义Task,也可以通过修改default.properties文件来实现引入新Task,这个文件位于org.apache.tools.ant.taskdefs 包里。下例是一个使用 标签来引入新Task的Build文件部分:

<target name="hello" depends="client">

<taskdef name="hello"

classname="com.sharetop.antdemo.HelloTask" classpath="client.jar"/>

<taskdef name="helloinfo"

classname="com.sharetop.antdemo.HelloInfoTask" classpath="client.jar"/>

<hello count="3" >

<helloinfo message="hello world" />

</hello>

</target>

第三部分ant打ear包的详细步骤

ant打ear包的详细步骤

技术应用 2009-11-02 12:26 阅读21 评论0 字号: 大大 中中 小小 用一个简单的ejb3.0示例记录ant打ear包的过程

源码下载

环境:

apache-ant-1.6.5

jboss-4.2.1.GA

jboss-annotations-ejb3.jar

jboss-ejb3.jar

jboss-ejb3x.jar

最后三个包在jboss里有.

1,建ejb3.0项目

session bean接口:HelloWorld

public interface HelloWorld {

public String sayHello(String name);

}

实现类:HelloWorldBean

@Stateless

@Remote ({HelloWorld.class})

public class HelloWorldBean implements HelloWorld {

public String sayHello(String name) {

//org.apache.commons.collections,这里假设用到了其它包中的类

CollectionUtils c=new CollectionUtils();

//org.apache.commons.lang

StringUtils s=new StringUtils();

return "hello,i am "+name;

}

}

调用session bean的jsp:

<%

//org.apache.commons.collections,这里假设用到了其它包中的类

CollectionUtils c=new CollectionUtils();

//org.apache.commons.lang

StringUtils s=new StringUtils();

%>

<%

Properties props = new Properties();

props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");

props.setProperty("java.naming.provider.url", "localhost:1099");

props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");

InitialContext ctx;

try {

ctx = new InitialContext(props);

HelloWorld helloworld = (HelloWorld) ctx.lookup("myproject/HelloWorldBean/remote");

out.println(helloworld.sayHello("mashiguang"));

} catch (NamingException e) {

out.println(e.getMessage());

}

%>

把一些公用的jar包都放到ear下,而不是分别在ejb jar包和war包里,减少jar包的冗余.

<project name="ear" default="deploy" basedir=".">

<property environment="env" />

<property name="app.dir" value="${basedir}" />

<property name="src.dir" value="${app.dir}\src" />

<property name="classes.dir" value="${app.dir}\build\classes" />

<property name="webcontent.dir" value="${app.dir}\WebContent" />

<property name="jboss.home" value="${env.JBOSS_HOME}" />

<property name="jboss.server.config" value="default" />

<path id="build.classpath" description="编译时classpath">

<fileset dir="${webcontent.dir}\WEB-INF\lib">

<include name="*.jar" />

</fileset>

<pathelement location="${classes.dir}" />

</path>

<target name="prepare" depends="clean" description="创建classes文件夹">

<mkdir dir="${classes.dir}" />

</target>

<target name="compile" depends="prepare" description="编绎">

<javac srcdir="${src.dir}" destdir="${classes.dir}" debug="on" deprecation="on" optimize="off" includes="**">

<classpath refid="build.classpath" />

</javac>

</target>

<target name="sessionInterface" depends="compile" description="创建session bean接口包">

<jar destfile="${app.dir}/interface.jar">

<fileset dir="${classes.dir}">

<include name="com/mashiguang/ejb3/*.class" />

</fileset>

</jar>

</target>

<target name="ejb_jar" depends="sessionInterface" description="创建ejb jar包">

<jar destfile="${app.dir}/ejb.jar">

<fileset dir="${classes.dir}">

<include name="com/mashiguang/ejb3/impl/**" />

</fileset>

<manifest>

<attribute name="Class-Path" value="interface.jar commons-collections-3.2.jar commons-lang-2.3.jar"/>

</manifest>

</jar>

</target>

<target name="web-war" depends="ejb_jar" description="创建WEB发布包">

<war destfile="${app.dir}/web.war" webxml="${webcontent.dir}/WEB-INF/web.xml">

<fileset dir="${webcontent.dir}">

<include name="*.jsp"/>

<exclude name="WEB-INF/web.xml"/>

<exclude name="WEB-INF/lib/**"/>

</fileset>

<manifest>

<attribute name="Class-Path" value="interface.jar commons-collections-3.2.jar commons-lang-2.3.jar"/>

</manifest>

</war>

</target>

<target name="ear" depends="web-war" description="创建WEB发布包">

<ear destfile="${app.dir}/myproject.ear" appxml="${src.dir}/META-INF/application.xml">

<fileset dir="${app.dir}">

<include name="ejb.jar"/>

<include name="web.war"/>

<include name="interface.jar"/>

</fileset>

<fileset dir="${webcontent.dir}/WEB-INF/lib" >

<include name="commons*.jar"/>

</fileset>

</ear>

</target>

<target name="deploy" depends="ear">

<copy file="${app.dir}/myproject.ear" todir="${jboss.home}/server/${jboss.server.config}/deploy" />

</target>

<target name="clean">

<delete>

<fileset dir="${app.dir}">

<include name="ejb.jar"/>

<include name="web.war"/>

<include name="interface.jar"/>

</fileset>

</delete>

<delete dir="${classes.dir}" />

<!-- -->

<delete file="${jboss.home}/server/${jboss.server.config}/deploy/myproject.ear" />

</target>

</project>

Ant学习教程 http://www.uml.org.cn/j2ee/j2ee091302.htm

Ant实践

eric

目录

1. Ant是什么?

2. 安装Ant

3. 运行Ant

4. 编写build.xml

5. 内置task(internet)

6. EAR task(internet)

7. WAR task(internet)

8. JUnit task(internet)

1. Ant是什么?

Ant是一种基于Java的build工具。理论上来说,它有些类似于(Unix)C中的make ,但没有make的缺陷。

既然我们已经有了make, gnumake, nmake, jam以及其他的build工具为什么还要要一种新的build工具呢?因为Ant的原作者在多种(硬件)平台上开发软件时,无法忍受这些工具的限制和不便。类似于make的工具本质上是基于shell(语言)的:他们计算依赖关系,然后执行命令(这些命令与你在命令行敲的命令没太大区别)。这就意味着你可以很容易地通过使用OS特有的或编写新的(命令)程序扩展该工具;然而,这也意味着你将自己限制在了特定的OS,或特定的OS类型上,如Unix。

Makefile也很可恶。任何使用过他们的人都碰到过可恶的tab问题。Ant的原作者经常这样问自己:“是否我的命令不执行只是因为在我的tab前有一个空格?!!”。类似于jam的工具很好地处理了这类问题,但是(用户)必须记住和使用一种新的格式。

Ant就不同了。与基于shell命令的扩展模式不同,Ant用Java的类来扩展。(用户)不必编写shell命令,配置文件是基于XML的,通过调用target树,就可执行各种task。每个task由实现了一个实现了特定Task接口的对象来运行。(如果你对Ant一点概念都没有的话,可能看不懂这一节,没有关系,后面会对target,task做详细的介绍。你如果没有太多的时间甚至可以略过这一节,然后再回来浏览一下这里的介绍,那时你就会看懂了。同样,如果你对make之类的工具不熟悉也没关系,下面的介绍根本不会用到make中的概念。)

必须承认,这样做,在构造shell命令时会失去一些特有的表达能力。如`find . -name foo -exec rm {}`,但却给了你跨平台的能力-你可以在任何地方工作。如果你真的需要执行一些shell命令,Ant有一个<exec> task,这个task允许执行特定OS上的命令。

返回

2. 安装Ant

由于Ant是一个Open Source的软件,所以有两种安装Ant的方式,一种是用已编译好的binary 文件安装Ant,另一种是用源代码自己build Ant。

binary 形式的Ant可以从http://jakarta.apache.org/builds/ant/release/v1.4.1/bin下载。如果你希望你能自己编译Ant,则可从 http://jakarta.apache.org/builds/ant/release/v1.4.1/src。注意所列出的连接都是最新发行版的Ant。如果你读到此文时,发现已经有了更新的版本,那么请用新版本。如果你是一个疯狂的技术追求者,你也可以从Ant CVS repository下载最新版本的Ant。

系统需求

要想自己build Ant。你需要一个JAXP兼容的XML解析器(parser)放在你的CLASSPATH系统变量中。

binary 形式的Ant包括最新版的Apache Crimson XML解析器。你可以从http://java.sun.com/xml/ 得到更多的关于JAXP的信息。如果你希望使用其他的JAXP兼容的解析器。你要从Ant的lib目录中删掉jaxp.jar以及crimson.jar。然后你可将你心爱的解析器的jar文件放到Ant的lib目录中或放在你的CLASSPATH系统变量中。

对于当前版本的Ant,需要你的系统中有JDK,1.1版或更高。未来的Ant版本会要求使用JDK 1.2或更高版本。

安装Ant

binary 版的Ant包括三个目录:bin, docs 和lib。只有bin和lib目录是运行Ant所需的。要想安装Ant,选择一个目录并将发行版的文件拷贝到该目录下。这个目录被称作ANT_HOME。

在你运行Ant之前需要做一些配置工作。

将bin目录加入PATH环境变量。

设定ANT_HOME环境变量,指向你安装Ant的目录。在一些OS上,Ant的脚本可以猜测ANT_HOME(Unix和Windos NT/2000)-但最好不要依赖这一特性。

可选地,设定JAVA_HOME环境变量(参考下面的高级小节),该变量应该指向你安装JDK的目录。

注意:不要将Ant的ant.jar文件放到JDK/JRE的lib/ext目录下。Ant是个应用程序,而lib/ext目录是为JDK扩展使用的(如JCE,JSSE扩展)。而且通过扩展装入的类会有安全方面的限制。

可选Task

Ant支持一些可选task。一个可选task一般需要额外的库才能工作。可选task与Ant的内置task分开,单独打包。这个可选包可以从你下载Ant的同一个地方下载。目前包含可选task的jar文件名叫jakarta-ant-1.4.1-optional.jar。这个jar文件应该放到Ant安装目录的lib目录下。

每个可选task所需的外部库可参看依赖库小节。这些外部库可以放到Ant的lib目录下,这样Ant就能自动装入,或者将其放入环境变量中。

Windows

假定Ant安装在c:\ant\目录下。下面是设定环境的命令:

set ANT_HOME=c:\ant

set JAVA_HOME=c:\jdk1.2.2

set PATH=%PATH%;%ANT_HOME%\bin

Unix (bash)

假定Ant安装在/usr/local/ant目录下。下面是设定环境的命令:

export ANT_HOME=/usr/local/ant

export JAVA_HOME=/usr/local/jdk-1.2.2

export PATH=${PATH}:${ANT_HOME}/bin

高级

要想运行Ant必须使用很多的变量。你至少参考需要下面的内容:

Ant的CLASSPATH必须包含ant.jar以及你所选的JAXP兼容的XML解析器的jar文件。

当你需要JDK的功能(如javac或rmic task)时,对于JDK 1.1,JDK的classes.zip文件必须放入CLASSPATH中;对于JDK 1.2或JDK 1.3,则必须加入tools.jar。如果设定了正确的JAVA_HOME环境变量,Ant所带的脚本,在bin目录下,会自动加入所需的JDK类。

当你执行特定平台的程序(如exec task或cvs task)时,必须设定ant.home属性指向Ant的安装目录。同样,Ant所带的脚本利用ANT_HOME环境变量自动设置该属性。

Building Ant

要想从源代码build Ant,你要先安装Ant源代码发行版或从CVS中checkout jakarta-ant模块。

安装好源代码后,进入安装目录。

设定JAVA_HOME环境变量指向JDK的安装目录。要想知道怎么做请参看安装Ant小节。

确保你已下载了任何辅助jar文件,以便build你所感兴趣的task。这些jar文件可以放在CLASSPATH中,也可以放在lib/optional目录下。参看依赖库小节可知不同的task需要那些jar文件。注意这些jar文件只是用作build Ant之用。要想运行Ant,你还要像安装Ant小节中所做的那样设定这些jar文件。

现在你可以build Ant了:

build -Ddist.dir=<directory_to_contain_Ant_distribution> dist (Windows)

build.sh -Ddist.dir=<directory_to_contain_Ant_distribution> dist (Unix)

这样就可你指定的目录中创建一个binary版本。

上面的命令执行下面的动作:

如果有必要可以bootstrap Ant的代码。bootstrap 包括手工编辑一些Ant代码以便运行Ant。bootstrap 用于下面的build步骤。

向build脚本传递参数以调用bootstrap Ant。参数定义了Ant的属性值并指定了Ant自己的build.xml文件的"dist" target。

大多数情况下,你不必直接bootstrap Ant,因为build脚本为你完成这一切。运行bootstrap.bat (Windows) 或 bootstrap.sh (UNIX) 可以build一个新的bootstrap版Ant。

如果你希望将Ant安装到ANT_HOME目录下,你可以使用:

build install (Windows)

build.sh install (Unix)

如果你希望跳过冗长的Javadoc步骤,可以用:

build install-lite (Windows)

build.sh install-lite (Unix)

这样就只会安装bin和lib目录。

注意install和install-lite都会覆盖ANT_HOME中的当前Ant版本。

依赖库

如果你需要执行特定的task,你需要将对应的库放入CLASSPATH或放到Ant安装目录的lib目录下。注意使用mapper时只需要一个regexp库。同时,你也要安装Ant的可选jar包,它包含了task的定义。参考上面的安装Ant小节。

Jar Name Needed For Available At

An XSL transformer like Xalan or XSL:P style task http://xml.apache.org/xalan-j/index.html or http://www.clc-marketing.com/xslp/

jakarta-regexp-1.2.jar regexp type with mappers jakarta.apache.org/regexp/

jakarta-oro-2.0.1.jar regexp type with mappers and the perforce tasks jakarta.apache.org/oro/

junit.jar junit tasks www.junit.org

stylebook.jar stylebook task CVS repository of xml.apache.org

testlet.jar test task java.apache.org/framework

antlr.jar antlr task www.antlr.org

bsf.jar script task oss.software.ibm.com/developerworks/projects/bsf

netrexx.jar netrexx task www2.hursley.ibm.com/netrexx

rhino.jar javascript with script task www.mozilla.org

jpython.jar python with script task www.jpython.org

netcomponents.jar ftp and telnet tasks www.savarese.org/oro/downloads

返回

3. 运行Ant

运行Ant非常简单,当你正确地安装Ant后,只要输入ant就可以了。

没有指定任何参数时,Ant会在当前目录下查询build.xml文件。如果找到了就用该文件作为buildfile。如果你用 -find 选项。Ant就会在上级目录中寻找buildfile,直至到达文件系统的根。要想让Ant使用其他的buildfile,可以用参数 -buildfile file,这里file指定了你想使用的buildfile。

你也可以设定一些属性,以覆盖buildfile中指定的属性值(参看property task)。可以用 -Dproperty=value 选项,这里property是指属性的名称,而value则是指属性的值。也可以用这种办法来指定一些环境变量的值。你也可以用property task来存取环境变量。只要将 -DMYVAR=%MYVAR% (Windows) 或 -DMYVAR=$MYVAR (Unix) 传递给Ant -你就可以在你的buildfile中用${MYVAR}来存取这些环境变量。

还有两个选项 -quite,告诉Ant运行时只输出少量的必要信息。而 -verbose,告诉Ant运行时要输出更多的信息。

可以指定执行一个或多个target。当省略target时,Ant使用标签<project>的default属性所指定的target。

如果有的话,-projecthelp 选项输出项目的描述信息和项目target的列表。先列出那些有描述的,然后是没有描述的target。

命令行选项总结:

ant [options] [target [target2 [target3] ...]]

Options:

-help print this message

-projecthelp print project help information

-version print the version information and exit

-quiet be extra quiet

-verbose be extra verbose

-debug print debugging information

-emacs produce logging information without adornments

-logfile file use given file for log output

-logger classname the class that is to perform logging

-listener classname add an instance of class as a project listener

-buildfile file use specified buildfile

-find file search for buildfile towards the root of the filesystem and use the first one found

-Dproperty=value set property to value

例子

ant

使用当前目录下的build.xml运行Ant,执行缺省的target。

ant -buildfile test.xml

使用当前目录下的test.xml运行Ant,执行缺省的target。

ant -buildfile test.xml dist

使用当前目录下的test.xml运行Ant,执行一个叫做dist的target。

ant -buildfile test.xml -Dbuild=build/classes dist

使用当前目录下的test.xml运行Ant,执行一个叫做dist的target,并设定build属性的值为build/classes。

文件

在Unix上,Ant的执行脚本在做任何事之前都会source(读并计算值)~/.antrc 文件;在Windows上,Ant的批处理文件会在开始时调用%HOME%\antrc_pre.bat,在结束时调用%HOME%\antrc_post.bat。你可以用这些文件配置或取消一些只有在运行Ant时才需要的环境变量。看下面的例子。

环境变量

包裹脚本(wrapper scripts)使用下面的环境变量(如果有的话):

JAVACMD Java可执行文件的绝对路径。用这个值可以指定一个不同于JAVA_HOME/bin/java(.exe)的JVM。

ANT_OPTS 传递给JVM的命令行变量-例如,你可以定义属性或设定Java堆的最大值

手工运行Ant

如果你自己动手安装(DIY)Ant,你可以用下面的命令启动Ant:

java -Dant.home=c:\ant org.apache.tools.ant.Main [options] [target]

这个命令与前面的ant命令一样。选项和target也和用ant命令时一样。这个例子假定你的CLASSPATH包含:

ant.jar

jars/classes for your XML parser

the JDK's required jar/zip files

返回

4. 编写build.xml

Ant的buildfile是用XML写的。每个buildfile含有一个project。

buildfile中每个task元素可以有一个id属性,可以用这个id值引用指定的任务。这个值必须是唯一的。(详情请参考下面的Task小节)

Projects

project有下面的属性:

Attribute Description Required

name 项目名称. No

default 当没有指定target时使用的缺省target Yes

basedir 用于计算所有其他路径的基路径。该属性可以被basedir property覆盖。当覆盖时,该属性被忽略。如果属性和basedir property都没有设定,就使用buildfile文件的父目录。 No

项目的描述以一个顶级的<description>元素的形式出现(参看description小节)。

一个项目可以定义一个或多个target。一个target是一系列你想要执行的。执行Ant时,你可以选择执行那个target。当没有给定target时,使用project的default属性所确定的target。

Targets

一个target可以依赖于其他的target。例如,你可能会有一个target用于编译程序,一个target用于生成可执行文件。你在生成可执行文件之前必须先编译通过,所以生成可执行文件的target依赖于编译target。Ant会处理这种依赖关系。

然而,应当注意到,Ant的depends属性只指定了target应该被执行的顺序-如果被依赖的target无法运行,这种depends对于指定了依赖关系的target就没有影响。

Ant会依照depends属性中target出现的顺序(从左到右)依次执行每个target。然而,要记住的是只要某个target依赖于一个target,后者就会被先执行。

<target name="A"/>

<target name="B" depends="A"/>

<target name="C" depends="B"/>

<target name="D" depends="C,B,A"/>

假定我们要执行target D。从它的依赖属性来看,你可能认为先执行C,然后B,最后A被执行。错了,C依赖于B,B依赖于A,所以先执行A,然后B,然后C,最后D被执行。

一个target只能被执行一次,即时有多个target依赖于它(看上面的例子)。

如果(或如果不)某些属性被设定,才执行某个target。这样,允许根据系统的状态(java version, OS, 命令行属性定义等等)来更好地控制build的过程。要想让一个target这样做,你就应该在target元素中,加入if(或unless)属性,带上target因该有所判断的属性。例如:

<target name="build-module-A" if="module-A-present"/>

<target name="build-own-fake-module-A" unless="module-A-present"/>

如果没有if或unless属性,target总会被执行。

可选的description属性可用来提供关于target的一行描述,这些描述可由-projecthelp命令行选项输出。

将你的tstamp task在一个所谓的初始化target是很好的做法,其他的target依赖这个初始化target。要确保初始化target是出现在其他target依赖表中的第一个target。在本手册中大多数的初始化target的名字是"init"。

target有下面的属性:

Attribute Description Required

name target的名字 Yes

depends 用逗号分隔的target的名字列表,也就是依赖表。 No

if 执行target所需要设定的属性名。 No

unless 执行target需要清除设定的属性名。 No

description 关于target功能的简短描述。 No

Tasks

一个task是一段可执行的代码。

一个task可以有多个属性(如果你愿意的话,可以将其称之为变量)。属性只可能包含对property的引用。这些引用会在task执行前被解析。

下面是Task的一般构造形式:

<name attribute1="value1" attribute2="value2" ... />

这里name是task的名字,attributeN是属性名,valueN是属性值。

有一套内置的(built-in)task,以及一些可选task,但你也可以编写自己的task。

所有的task都有一个task名字属性。Ant用属性值来产生日志信息。

可以给task赋一个id属性:

<taskname id="taskID" ... />

这里taskname是task的名字,而taskID是这个task的唯一标识符。通过这个标识符,你可以在脚本中引用相应的task。例如,在脚本中你可以这样:

<script ... >

task1.setFoo("bar");

</script>

设定某个task实例的foo属性。在另一个task中(用java编写),你可以利用下面的语句存取相应的实例。

project.getReference("task1").

注意1:如果task1还没有运行,就不会被生效(例如:不设定属性),如果你在随后配置它,你所作的一切都会被覆盖。

注意2:未来的Ant版本可能不会兼容这里所提的属性,因为很有可能根本没有task实例,只有proxies。

Properties

一个project可以有很多的properties。可以在buildfile中用property task来设定,或在Ant之外设定。一个property有一个名字和一个值。property可用于task的属性值。这是通过将属性名放在"${"和"}"之间并放在属性值的位置来实现的。例如如果有一个property builddir的值是"build",这个property就可用于属性值:${builddir}/classes。这个值就可被解析为build/classes。

内置属性

如果你使用了<property> task 定义了所有的系统属性,Ant允许你使用这些属性。例如,${os.name}对应操作系统的名字。

要想得到系统属性的列表可参考the Javadoc of System.getProperties。

除了Java的系统属性,Ant还定义了一些自己的内置属性:

basedir project基目录的绝对路径 (与<project>的basedir属性一样)。

ant.file buildfile的绝对路径。

ant.version Ant的版本。

ant.project.name 当前执行的project的名字;由<project>的name属性设定.

ant.java.version Ant检测到的JVM的版本; 目前的值有"1.1", "1.2", "1.3" and "1.4".

例子

<project name="MyProject" default="dist" basedir=".">

<!-- set global properties for this build -->

<property name="src" value="."/>

<property name="build" value="build"/>

<property name="dist" value="dist"/>

<target name="init">

<!-- Create the time stamp -->

<tstamp/>

<!-- Create the build directory structure used by compile -->

<mkdir dir="${build}"/>

</target>

<target name="compile" depends="init">

<!-- Compile the java code from ${src} into ${build} -->

<javac srcdir="${src}" destdir="${build}"/>

</target>

<target name="dist" depends="compile">

<!-- Create the distribution directory -->

<mkdir dir="${dist}/lib"/>

<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->

<jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/>

</target>

<target name="clean">

<!-- Delete the ${build} and ${dist} directory trees -->

<delete dir="${build}"/>

<delete dir="${dist}"/>

</target>

</project>

Token Filters

一个project可以有很多tokens,这些tokens在文件拷贝时会被自动扩展,这要求在支持这一行为的task中选择过滤拷贝功能。这一功能可用filter task在buildfile中设定。

既然这很可能是一个有危害的行为,文件中的tokens必须采取@token@的形式,这里token是filter task中设定的token名。这种token语法与其他build系统执行类似filtering的语法相同,而且与大多数的编程和脚本语言以及文档系统并不冲突,

注意:如果在一个文件中发现了一个@token@形式的token,但没有filter与这个token关连,则不会发生任何事;因此,没有转义方法-但只要你为token选择合适的名字,就不会产生问题。

警告:如果你在拷贝binary文件时打开filtering功能,你有可能破坏文件。这个功能只针对文本文件。

Path-like Structures

你可以用":"和";"作为分隔符,指定类似PATH和CLASSPATH的引用。Ant会把分隔符转换为当前系统所用的分隔符。

当需要指定类似路径的值时,可以使用嵌套元素。一般的形式是

<classpath>

<pathelement path="${classpath}"/>

<pathelement location="lib/helper.jar"/>

</classpath>

location属性指定了相对于project基目录的一个文件和目录,而path属性接受逗号或分号分隔的一个位置列表。path属性一般用作预定义的路径--其他情况下,应该用多个location属性。

为简洁起见,classpath标签支持自己的path和location属性。所以:

<classpath>

<pathelement path="${classpath}"/>

</classpath>

可以被简写作:

<classpath path="${classpath}"/>

也可通过<fileset>元素指定路径。构成一个fileset的多个文件加入path-like structure的顺序是未定的。

<classpath>

<pathelement path="${classpath}"/>

<fileset dir="lib">

<include name="**/*.jar"/>

</fileset>

<pathelement location="classes"/>

</classpath>

上面的例子构造了一个路径值包括:${classpath}的路径,跟着lib目录下的所有jar文件,接着是classes目录。

如果你想在多个task中使用相同的path-like structure,你可以用<path>元素定义他们(与target同级),然后通过id属性引用--参考Referencs例子。

path-like structure可能包括对另一个path-like structurede的引用(通过嵌套<path>元素):

<path id="base.path">

<pathelement path="${classpath}"/>

<fileset dir="lib">

<include name="**/*.jar"/>

</fileset>

<pathelement location="classes"/>

</path>

<path id="tests.path">

<path refid="base.path"/>

<pathelement location="testclasses"/>

</path>

前面所提的关于<classpath>的简洁写法对于<path>也是有效的,如:

<path id="tests.path">

<path refid="base.path"/>

<pathelement location="testclasses"/>

</path>

可写成:

<path id="base.path" path="${classpath}"/>

命令行变量

有些task可接受参数,并将其传递给另一个进程。为了能在变量中包含空格字符,可使用嵌套的arg元素。

Attribute Description Required

value 一个命令行变量;可包含空格字符。 只能用一个

line 空格分隔的命令行变量列表。

file 作为命令行变量的文件名;会被文件的绝对名替代。

path 一个作为单个命令行变量的path-like的字符串;或作为分隔符,Ant会将其转变为特定平台的分隔符。

例子

<arg value="-l -a"/>

是一个含有空格的单个的命令行变量。

<arg line="-l -a"/>

是两个空格分隔的命令行变量。

<arg path="/dir;/dir2:\dir3"/>

是一个命令行变量,其值在DOS系统上为\dir;\dir2;\dir3;在Unix系统上为/dir:/dir2:/dir3 。

References

buildfile元素的id属性可用来引用这些元素。如果你需要一遍遍的复制相同的XML代码块,这一属性就很有用--如多次使用<classpath>结构。

下面的例子:

<project ... >

<target ... >

<rmic ...>

<classpath>

<pathelement location="lib/"/>

<pathelement path="${java.class.path}/"/>

<pathelement path="${additional.path}"/>

</classpath>

</rmic>

</target>

<target ... >

<javac ...>

<classpath>

<pathelement location="lib/"/>

<pathelement path="${java.class.path}/"/>

<pathelement path="${additional.path}"/>

</classpath>

</javac>

</target>

</project>

可以写成如下形式:

<project ... >

<path id="project.class.path">

<pathelement location="lib/"/>

<pathelement path="${java.class.path}/"/>

<pathelement path="${additional.path}"/>

</path>

<target ... >

<rmic ...>

<classpath refid="project.class.path"/>

</rmic>

</target>

<target ... >

<javac ...>

<classpath refid="project.class.path"/>

</javac>

</target>

</project>

所有使用PatternSets, FileSets 或 path-like structures嵌套元素的task也接受这种类型的引用。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics