Apache Ant

Table of Contents

1. Ant 简介

Apache Ant 是一种基于 Java 的构件工具,它可以实现项目的自动构建和部署等功能。Ant 脚本采用 XML 格式编写,默认的文件名为 build.xml。

参考:http://ant.apache.org/manual/index.html

2. Buildfile 结构

Apache Ant’s buildfiles are written in XML. Each buildfile contains one project and at least one (default) target. Targets contain task elements. When starting Ant, you can select which target(s) you want to have executed.

下面是一个简单的 Buildfile:

<project name = "Hello World Project" default = "target1">       <!-- 这是project -->
   <target name = "target1">                                     <!-- 这是target -->
      <echo>Hello World - Welcome to Apache Ant!</echo>          <!-- 这是task -->
      <echo>This is ${ant.version}</echo>                        <!-- 这是task -->
   </target>
</project>
$ ant target1
Buildfile: /Users/cig01/test/build.xml

target1:
     [echo] Hello World - Welcome to Apache Ant!
     [echo] This is Apache Ant(TM) version 1.10.1 compiled on February 2 2017

BUILD SUCCESSFUL
Total time: 0 seconds

由于默认 target 为 target1,所以直接执行 ant 也得到上面的输出。

2.1. 基本概念

2.1.1. Projects

每一个 Buildfile 包含一个 project。一个 project 有下面三个属性:

Table 1: Attribute of project
Attribute Description
name the name of the project.
default the default target to use when no target is supplied.
basedir the base directory from which all path calculations are done. This attribute might be overridden by setting the "basedir" property beforehand. When this is done, it must be omitted in the project tag. If neither the attribute nor the property have been set, the parent directory of the buildfile will be used. A relative path is resolved relative to the directory containing the build file.

2.1.2. Targets

A target is a set of tasks you want to be executed.

2.1.3. Tasks

A task is a piece of code that can be executed.

参考:Overview of Apache Ant Tasks

2.2. 用 Ant 编译你的 Hello world 程序

创建目录 src/sample:

$ mkdir -p src/sample

在目录 src/sample 中创建如下 Java 程序 HelloWorld.java:

package sample;

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}

参考:Tutorial: Hello World with Apache Ant

2.2.1. 手工编译测试

编译及测试过程如下:

$ javac -sourcepath src -d build/classes src/sample/HelloWorld.java    # 编译为.class文件
$ jar cfm build/jar/HelloWorld.jar myManifest -C build/classes .       # 生成HelloWorld.jar
$ java -jar build/jar/HelloWorld.jar                                   # 测试生成的jar文件
Hello World

2.2.2. 用 Ant 编译测试

准备如下 build.xml 文件:

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

    <target name="clean">
        <delete dir="build"/>
    </target>

    <target name="compile">
        <mkdir dir="build/classes"/>
        <javac srcdir="src" destdir="build/classes"/>
    </target>

    <target name="jar" depends="compile">
        <mkdir dir="build/jar"/>
        <jar destfile="build/jar/HelloWorld.jar" basedir="build/classes">
            <manifest>
                <attribute name="Main-Class" value="sample.HelloWorld"/>
            </manifest>
        </jar>
    </target>

    <target name="run" depends="jar">
        <java jar="build/jar/HelloWorld.jar" fork="true"/>
    </target>

    <target name="main" depends="clean,run"/>

</project>

ant 编译测试如下:

$ ant
Buildfile: /Users/cig01/test/build.xml

clean:

compile:
    [mkdir] Created dir: /Users/cig01/test/build/classes
    [javac] /Users/cig01/test/build.xml:9: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
    [javac] Compiling 1 source file to /Users/cig01/test/build/classes

jar:
    [mkdir] Created dir: /Users/cig01/test/build/jar
      [jar] Building jar: /Users/cig01/test/build/jar/HelloWorld.jar

run:
     [java] Hello World

main:

BUILD SUCCESSFUL
Total time: 0 seconds

2.2.3. 编译依赖第三方库的程序

在实际开发中,我们往往会依赖于第三方库。假如有程序:

package sample;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld {
  public static void main(String[] args) {
    Logger logger = LoggerFactory.getLogger(HelloWorld.class);
    logger.info("Hello World");
  }
}

如何用 Ant 编译依赖第三方库的程序呢?

首先,我们要把程序依赖的第三方库以及第三方库本身的依赖库全部准备好(如果使用 maven 就不用这么麻烦了),假设第三方库及其依赖都位于目录 lib 下。如:

$ ls lib/
slf4j-api-1.7.12.jar    slf4j-simple-1.7.12.jar

在编译时,需要使用 Task javac 的 classpath 属性或者 classpathref 属性来指定第三方库的位置。相应的 build.xml 文件为:

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

    <path id="classpath">
        <fileset dir="lib" includes="**/*.jar"/>
    </path>

    ......

    <target name="compile">
        <mkdir dir="build/classes"/>
        <javac srcdir="src" destdir="build/classes" classpathref="classpath"/>
    </target>

    ......

    <target name="run" depends="jar">
        <java fork="true" classname="sample.HelloWorld">
            <classpath>
                <path refid="classpath"/>
                <path location="build/jar/HelloWorld.jar"/>
            </classpath>
        </java>
    </target>

    ......

</project>

参考:http://ant.apache.org/manual/tutorial-HelloWorldWithAnt.html#ext-libs

Author: cig01

Created: <2017-01-07 Sat>

Last updated: <2017-12-13 Wed>

Creator: Emacs 27.1 (Org mode 9.4)