使用Ant,第1部分:将Ant脚本引入Java项目

时间:2022-09-11 08:48:04

核心概念,简单任务,项目集成和异常处理

简介


Apache Ant是一种基于Java 语言的构建工具,它已经出现了好几年了,并且现在已经成为了实际意义上的构建 Java 项目的标准了。Ant 是用 Java 语言编写的,并且具有良好的扩展性,允许用户在它的特性上进行软件的构建并可以容易的与其他的工具和系统以各种方式进行有效的集成。语言编写的,并且具有良好的扩展性,允许用户在它的特性上进行软件的构建并可以容易的与其他的工具和系统以各种方式进行有效的集成。因为 Ant 最初是为构建 Java 应用而设计的,因此它能够理解 Java 的领域,并知道如何使用它。因为 Java 平台, Ant 也是跨平台的,这就意味这你在一个平台上创建的构建文件可以在不作任何改动的情况下运行在其他支持 Java 的平台上。

基础知识


在深入研究有趣的Ant内容之前,我们先了解一些基础知识,如何安装Ant,以及如何使其正常运行。首先从 Apache Ant 官网下载 (http://ant.apache.org/bindownload.cgi) ,然后解压文件,放到指定的系统目录中,其次设定好相应的环境变量 (可以参考官网Installing Ant  http://ant.apache.org/manual/index.html 相关介绍),最后添加需要的可选库。这里需要了解的是一些IDE,例如Eclipse可以不需要设置Path,而是通过IDE相关设置将Ant添加到Path中。

Windows安装过程(以笔者的安装过程为例)

下载apache-ant-1.8.4-bin.zip到本地硬盘,解压之后将文件夹放到C: 根目录下(c:/apache-ant-1.8.4),这个目录就是Ant的主目录。将主目录中的bin (c:/apache-ant-1.8.4/bin)目录添加到Path属性中,这样就可以在命令行中调用ant命令,ANT_HOME是批处理文件所在目录的上级目录,我就设定为c:/apache-ant-1.8.4。现在许多工具已经集成了特定版本的Ant,一些操作系统甚至默认的已经安装了Ant。所以,你的系统中可能已经安装了Ant。

可以通过ant -version 和 ant –diagnostics 来确定是否安装成功。注意:不推荐你设置CLASSPATH来运行Ant命令。如果任何版本的Ant可以从CLASSPATH加载 ,这时就会由于加载了不兼容的类而产生许多错误。

Ant核心概念

  1. XML:所有的 Ant 构建都是被一个 XML 格式的构建文件 (等价于一个 "Makefile" 文件) 驱动的。缺省的情况下,这个文件叫作 build.xml,并放在项目的根目录下。然而,你也可以在项目中包含任意命名的一系列的构建文件。 Ant 允许你调用或者将这些文件串在一起,比如,你想要递归的构建一个包含多个项目的目录结构。
  2. 陈述式语法:构建文件短小精悍,且易于理解。构建文件总是引用一个单一的项目,例如一个应用。项目有一系列能够被调用的目标(targets)。这些目标是构建过程的核心部分(比如,编译、测试、产生分发文件和部署)。每一个目标被顺序的调用。
  3. 工程(project):每个构建文件包含一个工程(project)
  4. 目标(target):每一个工程包含若干个目标(target)
  5. 依赖(depends):目标可以依赖(depends)于其它的目标
  6. 任务(task):目标包含任务(task)

Ant 一个典型的示例

下面是一个典型的部署项目的例子,学习这个例子之前先弄清楚一个概念,构建文件的概念视图:工程包含一个目标的集合,在每个目标里面是任务的声明,他们是对Ant用于构建该目标行为的说明,目标生成一个依赖关系图表来声明该目标的依赖关系,当执行一个目标时,必须先执行它们依赖的目标。

图1. Ant构建文件的概念视图示例

使用Ant,第1部分:将Ant脚本引入Java项目

清单1. 一个典型的构建文件

<xml version="1.0" ?>
<project name="DemoProject" default="deploy">
  <property name="dir.src" value="src"/>
  <property name="dir.build" value="build"/>
  <property name="dir.dist" value="dist"/>

  <target name="init">
    <mkdir dir="${dir.build}" />
    <mkdir dir="${dir.dist}" />
  </target>

  <target name="compile" depends="init" >
    <javac srcdir="${dir.src}" destdir="${dir.build}"/>
  </target>

  <target name="doc" depends="init" >
    <javadoc destdir="${dir.build}" sourcepath="${dir.src}" packagenames="org.*" />
  </target>
  
  <target name="deploy" depends="compile,doc" >
    <jar destfile="${dir.dist}/project.jar" basedir="${dir.build}"/>
    <ftp server="" userid="" password="">
      <fileset dir="${dir.dist}"/>
    </ftp>
  </target>
</project>

该示例的构建过程如下:

0. 初始化 1. 编译 2. 生成JavaDoc 3.打包 4.上传到FTP (其中第3、4步结合到一起叫部署) 。

注意:

  1. Ant的简单任务(<mkdir>)都是由Java类库来实现相应的功能的。而一些复杂的任务<ftp>,<junit>还需要第三方库的支持。
  2. 在执行Ant构建脚本时,你可以使用命令行传入一个.properties属性文件(或者在Ant脚本中直接引入),属性文件中可以定义任务运行时需要的参数。
  3. Ant的一个强大之处在于它总能工作。只要正确的指定构建文件,Ant就能计算出目标的依赖性,并且按照正确的顺序调用目标。目标通过任务按序执行,而任务自身处理其文件依赖性以及实际的操作来完成工作。因为每个任务通常都是在高层陈述,所以一两行XML语句经常就已经足够描述任务的内容。

Ant - Java项目集成


1. 创建一个Java工程,名为DemoProject,工程中源文件和目标文件是分开的,分别为文件夹src和bin,然后创建一个Java类文件,类名为AntDemoTest.java

  清单2. AntDemoTest 源代码

package com.test;

public class AntDemoTest {
  public static void main(String[] args) {
    for (int i = 0; i < args.length; i++) {
      System.out.println(args[i]);
    }
  }
}

2. 在工程的根路径下创建一个构建文件build.xml

  清单 3. build.xml 文件内容

<?xml version="1.0" encoding="UTF-8"?>
<project name="DemoProject" default="archive">
  <property name="dir.src" value="src"/>
  <property name="dir.build" value="build"/>
  <property name="dir.build.classes" value="build/classes"/>
  <property name="dir.dist" value="dist"/>
  
  <target name="init">
    <mkdir dir="${dir.build.classes}" />
    <mkdir dir="${dir.dist}" />
  </target>
  
  <target name="compile" depends="init" >
    <javac srcdir="${dir.src}" destdir="${dir.build.classes}"/>
  </target>
  
  <target name="archive" depends="compile" >
    <jar destfile="${dir.dist}/project.jar" basedir="${dir.build.classes}" />
  </target>
  
  <target name="clean" depends="init">
    <delete dir="${dir.build}" />
    <delete dir="${dir.dist}" />
  </target>
</project>

目标init 包含两个任务<mkdir>,用于创建输出文件夹;目标compile包含一个任务<javac>,用于编译源文件并将编译后的文件放置到输出文件夹里面;目标archive包含一个任务<jar>,用于打包;目标clean包含两个任务<clean>,用于删除输出文件夹。这里目标compile和clean都是依赖于目标init的,而目标archive则是依赖于compile的。

3. 在命令行运行ant脚本

  图2:命令行运行ant脚本

使用Ant,第1部分:将Ant脚本引入Java项目

注意:此处 ant 等价于 ant archive,因为在构建文件中,我们定义了default="archive"

4. 查看 DemoProject文件夹,你会发现多出了build以及dist文件夹,如此你已经成功的运行了Ant脚本。

进一步拓展


构建失败了怎么办?

首先有可能是XML语法书写不正确(将<target>写成<targe>),或者在任务执行过程中出现了错误(.java文件中包含编译错误),或者任务名称书写错误(将<javac>写成<javacc>)等等。写XML时一定要细心,一些IDE已经有验证功能,可以很好的防止书写的错误。一旦出现错误了,可以使用 ant –verbose 或者 ant –debug 来获取更加详细的构建信息,以解决问题。

图3:命令行运行ant -debug

使用Ant,第1部分:将Ant脚本引入Java项目

Ant当构建完成一次以后,再次执行构建会发生什么?

图4:连续构建效果

使用Ant,第1部分:将Ant脚本引入Java项目

实际上第二次运行构建时,目标都没有进行任何工作。由于所有的任务都检查了它们的依赖关系:<mkdir>没有创建目录因为已经存在;<javac>比较了源文件和类文件的时间戳;<jar>比较了要被加入文件与已经存在文件的时间。只有更新的时候才进行任务执行。

Ant是如何处理命令行上的多个目标?

图5:Ant 处理命令行上多个目标

使用Ant,第1部分:将Ant脚本引入Java项目

Ant依次执行每个目标和其依赖目标,即Ant的执行顺序是init compile init compile archive,虽然这样看起来增加了额外的工作,但是通过上面的执行过程就会发现,由于其依赖性检查的阻止,第二次的init和compile并未真正的执行,执行时间与直接执行archive的时间是一样的。

Ant 是如何运行程序的?

要运行上面编译出来的文件,不但可以在命令行里面直接使用java命令,也可以在构建文件build.xml中添加一个task来运行。

清单 4. 在build.xml 文件中添加程序运行目标

<target name="execute" depends="compile">
    <java classname="com.test.AntDemoTest" classpath="${dir.build.classes}">
      <arg value="hello"/>
      <arg value="world"/>
      <arg file="."/>
    </java>
  </target>

注意:最后一个参数是file=”.”,表示传入的参数是一个目录,为文件绝对路径。

图6:Ant执行execute目标

使用Ant,第1部分:将Ant脚本引入Java项目

Ant 一些常用的命令行

图7:Ant命令行选项

使用Ant,第1部分:将Ant脚本引入Java项目

当有多个构建文件时,指定构建文件:

  ant –buildfile build.xml compile

控制提示信息量:

  ant –quite (安静模式,没有任何输出)

  ant –emaces (简单模式,不显示任务名称)

获取项目信息

  ant -projecthelp

编写Ant脚本时可以使用到的格式

<?xml version="1.0" encoding="UTF-8"?>
<project name="vmness-acrm" default="help">

  <property name="dir.src" value="src"/>
  <property name="dir.build" value="build"/>
  <property name="dir.build.classes" value="${dir.build}/classes"/>
  <property name="dir.dist" value="dist"/>
  <!-- 加载project.properties文件-->
  <loadproperties srcFile="project.properties" />
  <!-- 加载./build文件目录下的build.xml构建文件-->
  <import file="./build/build.xml" />

  <target name="help">
    <!-- displays starts at col 13
          |13                                                           80| -->
    <echo>VMNess ACRM Ant Build. Available targets:</echo>
    <echo>   help:      Displays this help.</echo>
    <echo>   clean:     Removes output files created by other targets.</echo>
    <echo>              The 'all' target can be used to clean dependencies</echo>
    <echo>              (tested projects and libraries)at the same time</echo>
    <echo>              using: 'ant all clean'</echo>
  </target>
</project>

可以参考Android内置的build.xml

结束语


这篇教程已经介绍了Ant的入门级知识。你已经看到如何在Java 项目中集成Ant以及Ant的边边角角,后面两个教程将陆续介绍Ant使用的中级和高级教程。

作者QQ:1321518080