Ant 简明教程

Ant - Quick Guide

Ant - Introduction

ANT 代表 Another Neat 工具。它是一种来自计算机软件开发公司 Apache 的基于 Java 的构建工具。在深入了解 Apache Ant 的细节之前,让我们首先理解为什么我们需要一个构建工具。

Need for a Build Tool

通常,开发人员将大量时间花在执行构建和部署等平凡任务上,其中包括−

  1. Compiling the code

  2. Packaging the binaries

  3. 将二进制文件部署到测试服务器

  4. Testing the changes

  5. 将代码从一个位置复制到另一个位置

为了自动化和简化上述任务,Apache Ant 非常有用。它是一种可以从命令行执行的操作系统构建和部署工具。

History of Apache Ant

Ant 最初是由软件开发人员 James Duncan Davidson 创建的,他也是 web 服务器应用程序 Tomcat 的最初创建者。

Ant 最初用于构建 Tomcat,并作为 Tomcat 发行版的一部分进行捆绑。

它的诞生源于与 Apache Make 工具相关的复杂性和问题。

它于 2000 年作为 Apache 中的一个独立项目进行了推广。截至 2021 年 10 月,Apache Ant 的最新版本为 1.10.12

Features of Apache Ant

Apache Ant 的功能如下所示 −

  1. 它是当前最完整的 Java 编程和部署工具。

  2. 它与平台无关,并且可以处理特定于平台的属性,例如文件分隔符。

  3. 可以借助“触摸”命令来对其执行特定于平台的任务,例如修改文件修改时间。

  4. Ant 脚本使用纯 XML 来编写。如果您已经熟悉 XML,您可以相当快地学习 Ant。

  5. Ant 擅长自动化复杂重复的任务。

  6. Ant 提供预定义任务的一份长列表。

  7. Ant 提供一个界面来开发自定义任务。

  8. Ant 可以轻松从命令行调用并且可以与很多免费和商业 IDE 相集成。

Ant - Environment Setup

Apache Ant 以 Apache 软件许可证分发,该许可证是开源计划认证的、成熟的开源许可证。

最新版本的 Apache Ant, 包括了它的全源代码、类文件和文档,可以在 https://ant.apache.org 找到。

Installing Apache Ant

我们假设您已经下载并安装了 Java 开发工具包 (JDK)。如果没有,请按照 file:///C:/java/java_environment_setup.htm 的说明进行操作。

  1. 确保 JAVA_HOME 环境变量设置为您的 JDK 所安装到的文件夹。

  2. https://ant.apache.org 下载二进制文件。

  3. 使用 Winzip、winRAR、7-zip 或类似工具将 zip 文件解压缩到 c:\folder 之类的方便位置中。

  4. 创建一个名为 ANT_HOME 的新环境变量,它指向 Ant 安装文件夹。这儿这个文件夹是 c:\apache-ant-1.10.12-bin 文件夹。

  5. 将 Apache Ant 批处理文件路径附加到 PATH 环境变量。在我们的案例中,就是 c:\apache-ant-1.10.12-bin\bin 文件夹。

Verifying the Installation

在计算机中验证 Apache Ant 的安装是否成功,请在命令提示符中键入 ant。

您应当看到以下输出结果:

C:\>ant -version
Apache Ant(TM) version 1.10.12 compiled on October 13 2021

如果您没有看到以上输出结果,请验证您是否已经正确地按照安装步骤操作。

Installing Eclipse

本教程还涵盖了 Ant 和 Eclipse 集成开发环境 (IDE) 的集成。因此,如果您没有安装 Eclipse,请下载并安装 Eclipse。

Steps to install Eclipse

  1. www.eclipse.org 下载最新的 Eclipse 二进制文件。

  2. 将 Eclipse 二进制文件解压缩到方便的位置,比如 c:\folder。

  3. Run Eclipse from c:\eclipse\eclipse.exe.

Ant - Build Files

通常,Ant 构建文件名为 build.xml ,它应当放在项目的基本目录中。然而,对文件名或它的位置没有限制。您可以自由地使用其它文件名或将构建文件保存在其它位置。

为了进行这个练习,在计算机中任意位置创建一个名为 build.xml 的文件,它的内容如下:

<?xml version="1.0"?>
   <project name="Hello World Project" default="info">
   <target name="info">
      <echo>Hello World - Welcome to Apache Ant!</echo>
   </target>
</project>

请注意,xml 声明之前不应有空行或空格。如果您允许空行或空格,那么在执行 ant 构建时,会导致以下错误信息:

The processing instruction target matching "[xX][mM][lL]" is not allowed.
All build files require the project element and at least one target element.

XML 元素 project 有三个属性,如下:

Sr.No

Attributes & Description

1

name 项目名称。(可选)

2

default 构建脚本的默认目标。一个项目可以包含任何数量的目标。此属性指定应该视为默认值的目标。(强制)

3

basedir 基本目录(或)项目的根文件夹。(可选)

目标是您要作为一个单元运行的任务集合。在我们的示例中,我们有一个简单的目标,为用户提供信息消息。

目标可以依赖于其他目标。例如, deploy 目标可能依赖于程序包目标, package 目标可能依赖于编译目标,依此类推。依赖项使用 depends 属性表示。

例如 -

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

   ....
</target>
<target name="package" depends="clean,compile">
   ....
</target>
<target name="clean" >
   ....
</target>
<target name="compile" >
   ....
</target>

目标元素具有以下属性:

Sr.No

Attributes & Description

1

name 目标的名称(必需)

2

depends 此目标所依赖的所有目标的逗号分隔列表。(可选)

3

description 目标的简要说明。(可选)

4

if 允许基于条件属性的真实性执行目标。(可选)

5

unless 将目标添加到指定的扩展点的依赖项列表中。扩展点类似于目标,但它没有任何任务。(可选)

上述示例中的 echo 任务是一个打印消息的简单任务。在我们的示例中,它打印消息 Hello World

要运行蚂蚁构建文件,请打开命令提示符并导航到 build.xml 所在的文件夹,然后键入 ant info 。你也可以键入 ant 。两者都会起作用,因为 info 是构建文件中的默认目标。

你应该看到以下输出:

C:\>ant
Buildfile: C:\build.xml

info: [echo] Hello World - Welcome to Apache Ant!

BUILD SUCCESSFUL
Total time: 0 seconds

C:\>

Ant - Property Task

Ant 构建文件以 XML 编写,这不允许您像在您喜欢的编程语言中那样声明变量。不过,您可能已经想象到了,如果 Ant 允许声明变量(如项目名称、项目源目录等),那将很有用。

Ant 使用 property 元素,它允许你指定属性。这允许属性在不同的构建或不同的环境中更改。

Ant Properties

默认情况下,Ant 提供了以下预定义的属性,这些属性可以在构建文件中使用:

Sr.No

Properties & Description

1

ant.file 构建文件的完整位置。

2

ant.version Apache Ant 安装的版本。

3

basedir 构建的 basedir,如 project 元素的 basedir 属性中指定。

4

ant.java.version Ant 使用的 JDK 版本。

5

ant.project.name 项目名称,如 project 元素的 name 属性中指定。

6

ant.project.default-target 当前项目的默认目标。

7

ant.project.invoked-targets 在当前项目中调用的目标的逗号分隔列表。

8

ant.core.lib Ant jar 文件的完整位置。

9

ant.home Ant 安装的主目录。

10

ant.library.dir Ant 库文件的主目录,通常是 ANT_HOME/lib 文件夹。

Ant 也使系统属性(示例:file.separator)可用于构建文件。

除了以上内容,用户可以使用 property 元素定义附加的属性。

以下示例展示了如何定义一个名为 sitename 的属性:

<?xml version="1.0"?>
<project name="Hello World Project" default="info">

   <property name="sitename" value="www.tutorialspoint.com"/>
   <target name="info">
      <echo>Apache Ant version is ${ant.version} - You are at ${sitename} </echo>
   </target>
</project>

在上述构建文件上运行 Ant 会生成以下输出:

C:\>ant
Buildfile: C:\build.xml

info: [echo] Apache Ant version is Apache Ant(TM) version 1.10.12
   compiled on October 13 2021 - You are at www.tutorialspoint.com

BUILD SUCCESSFUL
Total time: 0 seconds
C:\>

Ant - Property Files

如果只需使用少数几个属性,则直接在构建文件中设置属性就足够了。但是,对于大型项目而言,将属性存储在单独的属性文件中有意义。

Benefits

将属性存储在单独的文件中会带来以下好处:

  1. 它允许你对同一构建文件进行重复使用,针对不同的执行环境使用不同的属性设置。例如,可以在 DEV、TEST 和 PROD 环境中分别维护构建属性文件。

  2. 在你事先不知道某个属性的值(在特定环境中)时,这非常有用。这允许你在属性值已知,其他环境中执行构建。

没有硬性规定,但通常属性文件被命名为 build.properties ,并与 build.xml 文件放在一起。你可以根据部署环境创建多个构建属性文件,比如 build.properties.devbuild.properties.test

构建属性文件的文本内容与规范的 java 属性文件类似。它们每行包含一个属性。每个属性由名称和值对表示。

名称和值对用等号 (=) 符号分隔。强烈建议使用正确的注释为这些属性做注解。使用井号 (#) 字符列出注释。

以下示例展示了一个 build.xml 文件及其关联 build.properties 文件−

build.xml

以下是针对 build.xml 文件的示例。

<?xml version="1.0"?>
<project name="Hello World Project" default="info">
   <property file="build.properties"/>
      <target name="info">
         <echo>Apache Ant version is ${ant.version} - You are at ${sitename} </echo>
      </target>
</project>

build.properties

以下是针对 build.properties 文件的示例 −

# The Site Name
sitename=www.tutorialspoint.com
buildversion=3.3.2

在上述示例中, sitename 是映射到网站名称的自定义属性。您可以用这种方式声明任意数量的自定义属性。

上述示例中列出的另一个自定义属性是 buildversion ,它在这种情况下指代构建版本。

除上述内容外,Ant 内含若干预定义构建属性,已在上一部分中列出,但在此再次列出以供参考。

Sr.No

Properties & Description

1

ant.file 构建文件的完整位置。

2

ant.version Apache Ant 安装的版本。

3

basedir 构建的 basedir,如 project 元素的 basedir 属性中指定。

4

ant.java.version Ant 使用的 JDK 版本。

5

ant.project.name 项目名称,如 project 元素的 name 属性中指定。

6

ant.project.default-target 当前项目的默认目标。

7

ant.project.invoked-targets 在当前项目中调用的目标的逗号分隔列表。

8

ant.core.lib Ant jar 文件的完整位置。

9

ant.home Ant 安装的主目录。

10

ant.library.dir Ant 库文件的主目录,通常是 ANT_HOME/lib 文件夹。

本章展示的示例使用了 ant.version 内置属性。

Ant - Data Types

Ant 提供了许多预定义的数据类型。不要将术语“数据类型”与编程语言中可用的数据类型混淆。相反,将它们视为已经内置到产品中的服务集。

Data Types in Ant

Apache Ant 提供了以下数据类型。

Fileset

文件集数据类型表示一组文件。它用作过滤器,用于包括或排除与特定模式匹配的文件。

例如,请参阅以下代码。此处,src 属性指向项目的源文件夹。

<fileset dir="${src}" casesensitive="yes">
   <include name="**/*.java"/>
   <exclude name="**/*Stub*"/>
</fileset>

文件集选择源文件夹中的所有 .java 文件,但那些包含单词“Stub”的文件除外。对文件集应用区分大小写的过滤器,这意味着不会从文件集排除名为 Samplestub.java 的文件。

Pattern set

模式集是一种模式,允许根据某些模式轻松过滤文件或文件夹。可以使用以下元字符创建模式:

  1. ?- 仅匹配一个字符。

  2. - 匹配零个或多个字符。

  3. **- 递归匹配零个或多个目录。

以下示例描述了模式集的用法。

<patternset id="java.files.without.stubs">
   <include name="src/**/*.java"/>
   <exclude name="src/**/*Stub*"/>
</patternset>

然后可以将模式集与文件集一起重新使用,如下所示:

<fileset dir="${src}" casesensitive="yes">
   <patternset refid="java.files.without.stubs"/>
</fileset>

File list

文件列表数据类型与文件集类似,但存在以下差异:

  1. 它包含明确命名的文件列表,并且不支持通配符。

  2. 此数据类型可应用于现有或不存在的文件。

让我们看一下文件列表数据类型的以下示例。在此处,属性 webapp.src.folder 指向项目的 Web 应用程序源文件夹。

<filelist id="config.files" dir="${webapp.src.folder}">
   <file name="applicationConfig.xml"/>
   <file name="faces-config.xml"/>
   <file name="web.xml"/>
   <file name="portlet.xml"/>
</filelist>

Filter set

通过将 filterset 数据类型与 copy 任务一起使用,可以使用替换值替换与模式匹配的所有文件中特定的文本。

一个常见的例子是在发布说明文件中追加版本号,如下面的代码所示。

<copy todir="${output.dir}">
   <fileset dir="${releasenotes.dir}" includes="**/*.txt"/>
   <filterset>
      <filter token="VERSION" value="${current.version}"/>
   </filterset>
</copy>

在上面提到的代码中:

  1. 属性 output.dir 指向项目的输出文件夹。

  2. 属性 releasenotes.dir 指向项目的发布说明文件夹。

  3. 属性 current.version 指向项目的当前版本文件夹。

  4. 顾名思义,copy 任务用于将文件从一个位置复制到另一个位置。

Path

path 数据类型通常用于表示类路径。路径中的条目使用分号或冒号分隔。但是,这些字符会在运行时被执行系统的路径分隔符字符替换。

类路径被设置为项目中 jar 文件和类的列表,如下面的示例所示。

<path id="build.classpath.jar">
   <pathelement path="${env.J2EE_HOME}/${j2ee.jar}"/>
   <fileset dir="lib">
      <include name="**/*.jar"/>
   </fileset>
</path>

在上面给出的代码中:

  1. 属性 env.J2EE_HOME 指向环境变量 J2EE_HOME

  2. 属性 j2ee.jar 指向 J2EE 基本文件夹中的 J2EE jar 文件名称。

Ant - Building Projects

既然我们已学习了 Ant 中的数据类型,是时候将这份知识付诸实践了。我们将在本章中构建一个项目。本章的目标是构建一个 Ant 文件,编译 Java 类并将其置于 WEB-INF\classes 文件夹中。

考虑以下项目结构:

  1. 数据库脚本存储在 db 文件夹中。

  2. java 源代码存储在 src 文件夹中。

  3. 图像、js、META-INF 和样式 (css) 存储在 war 文件夹中。

  4. Java Server Pages (JSP) 存储在 jsp 文件夹中。

  5. 第三方 jar 文件存储在 lib 文件夹中。

  6. java 类文件存储在 WEB-INF\classes 文件夹中。

该项目构成了本教程其余部分的 Hello World 传真应用程序。

C:\work\FaxWebApplication>tree
Folder PATH listing
Volume serial number is 00740061 EC1C:ADB1
C:.
+---db
+---src
. +---faxapp
. +---dao
. +---entity
. +---util
. +---web
+---war
   +---images
   +---js
   +---META-INF
   +---styles
   +---WEB-INF
      +---classes
      +---jsp
      +---lib

以下是该项目所需的 build.xml 。让我们逐件考虑。

<?xml version="1.0"?>
<project name="fax" basedir="." default="build">
   <property name="src.dir" value="src"/>
   <property name="web.dir" value="war"/>
   <property name="build.dir" value="${web.dir}/WEB-INF/classes"/>
   <property name="name" value="fax"/>

   <path id="master-classpath">
      <fileset dir="${web.dir}/WEB-INF/lib">
         <include name="*.jar"/>
      </fileset>
      <pathelement path="${build.dir}"/>
   </path>

   <target name="build" description="Compile source tree java files">
      <mkdir dir="${build.dir}"/>
      <javac destdir="${build.dir}" source="1.5" target="1.5">
         <src path="${src.dir}"/>
         <classpath refid="master-classpath"/>
      </javac>
   </target>

   <target name="clean" description="Clean output directories">
      <delete>
         <fileset dir="${build.dir}">
            <include name="**/*.class"/>
         </fileset>
      </delete>
   </target>
</project>

首先,让我们为源文件、Web 和构建文件夹声明一些属性。

<property name="src.dir" value="src"/>
<property name="web.dir" value="war"/>
<property name="build.dir" value="${web.dir}/WEB-INF/classes"/>

在上述示例中,

  1. src.dir 指的是项目的源文件夹,其中可以找到 java 源文件。

  2. web.dir 指的是项目的 Web 源文件夹,可以在其中找到 JSP、web.xml、css、javascript 和其他与 Web 相关的文件。

  3. build.dir 指的是项目编译的输出文件夹。

属性可以引用其他属性。如上述示例所示, build.dir 属性引用 web.dir 属性。

在此示例中, src.dir 指的是项目的源文件夹。

我们项目的默认目标是 compile 目标。但首先,让我们看一下 clean 目标。

正如名称所示,clean 目标将删除构建文件夹中的文件。

<target name="clean" description="Clean output directories">
   <delete>
      <fileset dir="${build.dir}">
         <include name="**/*.class"/>
      </fileset>
   </delete>
</target>

master-classpath 保存类路径信息。在这种情况下,它包括构建文件夹中的类和 lib 文件夹中的 jar 文件。

<path id="master-classpath">
   <fileset dir="${web.dir}/WEB-INF/lib">
      <include name="*.jar"/>
   </fileset>
   <pathelement path="${build.dir}"/>
</path>

最后,构建目标用于构建文件。

首先,如果构建目录不存在,我们将创建它,然后执行 javac 命令(指定 jdk1.5 作为目标编译)。我们向 javac 任务提供源文件夹和类路径,并要求它将类文件放入构建文件夹中。

<target name="build" description="Compile main source tree java files">
   <mkdir dir="${build.dir}"/>
   <javac destdir="${build.dir}" source="1.5" target="1.5"
      debug="true" deprecation="false" optimize="false" failonerror="true">

      <src path="${src.dir}"/>
      <classpath refid="master-classpath"/>
   </javac>
</target>

在此文件中执行 Ant 会编译 Java 源文件,并将类放入构建文件夹中。

运行 Ant 文件后,会产生以下结果 −

C:\>ant
Buildfile: C:\build.xml

BUILD SUCCESSFUL
Total time: 6.3 seconds

文件会编译并在 build.dir 文件夹中以 build 文件夹中放置。

Ant - Build Documentation

文档在任何项目中都是必不可少的。文档在项目的维护中发挥了重要作用。Java 通过使用内置 javadoc 工具简化了文档的编写。Ant 通过按需生成文档,进一步简化了这一过程。

众所周知,javadoc 工具非常灵活,并允许使用许多配置选项。Ant 通过 javadoc 任务公开这些配置选项。如果您不熟悉 javadoc,建议您从这篇 Java 文档教程开始学习。

以下部分列出了 Ant 中使用的一些最常见的 javadoc 选项。

Attributes

源可以通过 sourcepathsourcepathrefsourcefiles 指定。

  1. sourcepath 用于指向源文件所在的文件夹(例如 src 文件夹)。

  2. sourcepathref 用于引用 path 属性引用的路径(例如,delegates.src.dir)。

  3. 当您希望将各个文件指定为逗号分隔的列表时,请使用 sourcefiles

目标路径是使用 destdir 文件夹指定的(例如 build.dir)。

您可以通过指定要包含的程序包名称来过滤 javadoc 任务。这是通过使用 packagenames 属性(逗号分隔的程序包文件列表)来实现的。

您可以过滤 javadoc 进程,以仅显示 public、private、package 或 protected 类和成员。这是通过使用 privatepublicpackageprotected 属性实现的。

您还可以通过使用相应属性来告诉 javadoc 任务包含作者和版本信息。

您还可以使用 group 属性对包进行分组,以便于导航。

Putting it all together

让我们继续 Hello world 传真应用程序的主题,并向传真应用程序项目添加文档目标。

下面给出了项目中使用的一个 javadoc 任务示例。在此示例中,我们指定 javadoc 使用 src.dir 作为源目录,使用 doc 作为目标。

我们还自定义了显示在 java 文档页面上的窗口标题、页眉和页脚信息。

此外,我们还创建了三个组:

  1. 第一个组是我们源文件夹中的实用程序类,

  2. 一个用于用户界面类,

  3. 一个用于数据库相关类。

你可能会注意到,data 包组有两个包——faxapp.entity 和 faxapp.dao。

<target name="generate-javadoc">
   <javadoc packagenames="faxapp.*" sourcepath="${src.dir}"
      destdir="doc" version="true" windowtitle="Fax Application">
      <doctitle><![CDATA[= Fax Application =]]></doctitle>
      <bottom>
         <![CDATA[Copyright © 2011. All Rights Reserved.]]>
      </bottom>
      <group title="util packages" packages="faxapp.util.*"/>
      <group title="web packages" packages="faxapp.web.*"/>
      <group title="data packages" packages="faxapp.entity.*:faxapp.dao.*"/>
   </javadoc>
   <echo message="java doc has been generated!" />
</target>

让我们执行 javadoc Ant 任务。它会在 doc 文件夹中生成并放置 java 文档文件。

javadoc target 执行时,它会生成以下结果 −

C:\>ant generate-javadoc
Buildfile: C:\build.xml

java doc has been generated!

BUILD SUCCESSFUL
Total time: 10.63 second

java 文档文件现在存在于 doc 文件夹中。

通常,javadoc 文件在发行或包目标中生成。

Ant - Creating JAR files

在编译完 java 源文件后的下一个逻辑步骤,就是构建 java 存档,即 Java 存档 (JAR) 文件。用 Ant 创建 JAR 文件非常容易,只需要 jar 任务。

Attributes

jar 任务常用的属性如下 −

Sr.No

Attributes & Description

1

basedir 输出 JAR 文件的基本目录。默认情况下,此目录设置为项目的基本目录。

2

compress 建议 Ant 在创建 JAR 文件时压缩该文件。

3

keepcompression 虽然 compress 属性适用于单个文件,但是 keepcompression 属性会执行同样的操作,但它适用于整个文档。

4

destfile 输出 JAR 文件的名称。

5

duplicate 当找到重复文件时,建议 Ant 执行什么操作。你可以添加、保留或让重复文件失败。

6

excludes 建议 Ant 不要在包中包含这些逗号分隔的文件列表。

7

excludesfile 与上述相同,不同之处在于排除文件是使用模式指定的。

8

inlcudes Inverse of excludes.

9

includesfile Inverse of excludesfile.

10

update 建议 Ant 覆盖已生成的 JAR 文件中的文件。

续我们的 Hello World 传真应用程序项目,让我们添加一个新目标来生成 jar 文件。

但是在这样做之前,我们考虑一下给定以下 jar 任务。

<jar destfile="${web.dir}/lib/util.jar"
   basedir="${build.dir}/classes"
   includes="faxapp/util/**"
   excludes="**/Test.class"
/>

在这里, web.dir 属性指向 Web 源文件的路径。在我们的案例中,这会放置 util.jar 的位置。

此示例中的 build.dir 属性指向 build 文件夹,此文件夹中可以找到 util.jar 的类文件。

在此示例中,我们使用 faxapp.util. * 包中的类创建了一个名为 util.jar 的 jar 文件。但是,我们会排除以 Test 名称结尾的类。输出 jar 文件将被放置在 Web 应用程序 lib 文件夹中。

如果我们要使 util.jar 成为可执行 jar 文件,需要使用带有 Main-Class 元属性的 manifest

因此,上面的示例将更新如下:

<jar destfile="${web.dir}/lib/util.jar"
   basedir="${build.dir}/classes"
   includes="faxapp/util/**"
   excludes="**/Test.class" class="ts"
   <manifest class="ts"
      <attribute name="Main-Class" value="com.tutorialspoint.util.FaxUtil"/>
   </manifest class="ts"
</jar class="ts"

要执行 jar 任务,请将其包装到目标内,最常见的是 build 或 package 目标,然后执行它们。

<target name="build-jar" class="ts"
<jar destfile="${web.dir}/lib/util.jar"
   basedir="${build.dir}/classes"
   includes="faxapp/util/**"
   excludes="**/Test.class" class="ts"
   <manifest class="ts"
      <attribute name="Main-Class" value="com.tutorialspoint.util.FaxUtil"/>
   </manifest class="ts"
</jar class="ts"
</target class="ts"

在此文件中运行 Ant 会为我们创建 util.jar 文件。

运行 Ant 文件后,会产生以下结果 −

C:\ class="ts"ant build-jar
Buildfile: C:\build.xml

BUILD SUCCESSFUL
Total time: 1.3 seconds

util.jar 文件现在放置在输出文件夹中。

Ant - Create WAR Files

使用 Ant 创建 Web 归档 (WAR) 文件极其简单,且与创建 JAR 文件任务非常类似。毕竟,WAR 文件与 JAR 文件一样,都只是另一个 ZIP 文件。

WAR 任务是 JAR 任务的一个扩展,但它有一些不错的补充内容,可以操作进入 WEB-INF/classes 文件夹的内容,并生成 web.xml 文件。WAR 任务对于指定 WAR 文件的特定布局非常有用。

由于 WAR 任务是 JAR 任务的扩展,因此 JAR 任务的所有属性都适用于 WAR 任务。

Sr.No

Attributes & Description

1

webxml web.xml 文件的路径。

2

lib 用于指定进入 WEB-INF\lib 文件夹的内容的分组。

3

classes 用于指定进入 WEB-INF\classes 文件夹的内容的分组。

4

metainf 指定用于生成 MANIFEST.MF 文件的指令。

继续我们的 Hello World Fax Application 项目,让我们添加一个新目标以生成 jar 文件。但在添加目标之前,让我们考虑一下 war 任务。

考虑以下示例 −

<war destfile="fax.war" webxml="${web.dir}/web.xml">
   <fileset dir="${web.dir}/WebContent">
      <include name="**/*.*"/>
   </fileset>
   <lib dir="thirdpartyjars">
      <exclude name="portlet.jar"/>
   </lib>
   <classes dir="${build.dir}/web"/>
</war>

如同之前的示例中提到的, web.dir 变量指源 web 文件夹,即包含 JSP、CSS、javascript文件等的文件夹。

build.dir 变量指输出文件夹。此处可以找到 WAR 软件包的类。通常情况下,类将被捆绑到 WAR 文件的 WEB-INF/classes 文件夹中。

在此示例中,我们创建一个名为 fax.war 的 war 文件。WEB.XML 文件是从 web 源文件夹获取的。web 下的“WebContent”文件夹中的所有文件都会被复制到 WAR 文件中。

WEB-INF/lib 文件夹使用 thirdpartyjars 文件夹中的 jar 文件填充。然而,我们排除了 portlet.jar,因为它已经出现在应用程序服务器的 lib 文件夹中。最后,我们从 build 目录的 web 文件夹中复制所有类,并将它们放入 WEB-INF/classes 文件夹中。

将 war 任务包装在 Ant 目标(通常是软件包)中并运行它。这将在指定位置创建 WAR 文件。

完全有可能嵌套类、lib、metainf 和 webinf 目录,以便他们居住在项目结构中任何地方的分散文件夹中。但是,最佳实践建议您的 Web 项目的 Web 内容结构应类似于 WAR 文件的结构。Fax 应用程序项目使用此基本原则概述了其结构。

要执行 war 任务,请将其包装在目标(最常见的是 build 或软件包目标)中,然后运行它们。

<target name="build-war">
   <war destfile="fax.war" webxml="${web.dir}/web.xml">
   <fileset dir="${web.dir}/WebContent">
      <include name="**/*.*"/>
   </fileset>
   <lib dir="thirdpartyjars">
      <exclude name="portlet.jar"/>
   </lib>
   <classes dir="${build.dir}/web"/>
   </war>
</target>

在此文件中运行 Ant 将为我们创建 fax.war 文件。

运行 Ant 文件后,会产生以下结果 −

C:\>ant build-war
Buildfile: C:\build.xml

BUILD SUCCESSFUL
Total time: 12.3 seconds

fax.war 文件现在放置在输出文件夹中。war 文件的内容将如下所示 −

fax.war:
   +---jsp This folder contains the jsp files
   +---css This folder contains the stylesheet files
   +---js This folder contains the javascript files

   +---images This folder contains the image files
   +---META-INF This folder contains the Manifest.Mf
   +---WEB-INF
      +---classes This folder contains the compiled classes
      +---lib Third party libraries and the utility jar files
      WEB.xml Configuration file that defines the WAR package

Ant - Packaging Applications

我们已零散地了解了 Hello World Fax Web 应用程序中使用 Ant 的不同方面。

现在,是时候将所有内容放在一起,以创建一个完整而全面的 build.xml 文件了。考虑 build.propertiesbuild.xml 文件如下:

build.properties

build.properties 文件中的内容如下。

deploy.path=c:\tomcat6\webapps

build.xml

build.xml 文件如下:

<?xml version="1.0"?>

<project name="fax" basedir="." default="usage">
   <property file="build.properties"/>
   <property name="src.dir" value="src"/>
   <property name="web.dir" value="war"/>
   <property name="javadoc.dir" value="doc"/>
   <property name="build.dir" value="${web.dir}/WEB-INF/classes"/>
   <property name="name" value="fax"/>

   <path id="master-classpath">
      <fileset dir="${web.dir}/WEB-INF/lib">
         <include name="*.jar"/>
      </fileset>
      <pathelement path="${build.dir}"/>
   </path>

   <target name="javadoc">
      <javadoc packagenames="faxapp.*" sourcepath="${src.dir}"
         destdir="doc" version="true" windowtitle="Fax Application">
      <doctitle><![CDATA[<h1>= Fax Application =</h1>]]></doctitle>
      <bottom><![CDATA[Copyright © 2011. All Rights Reserved.]]></bottom>
      <group title="util packages" packages="faxapp.util.*"/>
      <group title="web packages" packages="faxapp.web.*"/>
      <group title="data packages" packages="faxapp.entity.*:faxapp.dao.*"/>
      </javadoc>
   </target>

   <target name="usage">
      <echo message=""/>
      <echo message="${name} build file"/>
      <echo message="-----------------------------------"/>
      <echo message=""/>
      <echo message="Available targets are:"/>
      <echo message=""/>
      <echo message="deploy --> Deploy application as directory"/>
      <echo message="deploywar --> Deploy application as a WAR file"/>
      <echo message=""/>
   </target>

   <target name="build" description="Compile main source tree java files">
      <mkdir dir="${build.dir}"/>
      <javac destdir="${build.dir}" source="1.5"
         target="1.5" debug="true"
         deprecation="false" optimize="false" failonerror="true">
         <src path="${src.dir}"/>
         <classpath refid="master-classpath"/>
      </javac>
   </target>
   <target name="deploy" depends="build" description="Deploy application">

   <copy todir="${deploy.path}/${name}" preservelastmodified="true">
      <fileset dir="${web.dir}">
         <include name="**/*.*"/>
      </fileset>
   </copy>
   </target>

   <target name="deploywar" depends="build" description="Deploy application as a WAR file">
      <war destfile="${name}.war" webxml="${web.dir}/WEB-INF/web.xml">
         <fileset dir="${web.dir}">
            <include name="**/*.*"/>
         </fileset>
      </war>
      <copy todir="${deploy.path}" preservelastmodified="true">
         <fileset dir=".">
            <include name="*.war"/>
         </fileset>
      </copy>
   </target>

   <target name="clean" description="Clean output directories">
      <delete>
         <fileset dir="${build.dir}">
            <include name="**/*.class"/>
         </fileset>
      </delete>
   </target>
</project>

在上述示例中,

  1. 我们首先在构建属性文件中将 Tomcat 中的 webapps 文件夹路径声明为 deploy.path 变量。

  2. 我们还在 src.dir 变量中声明 Java 文件的源文件夹。

  3. 然后,我们在 web.dir 变量中声明 Web 文件的源文件夹。 javadoc.dir 是用于存储 Java 文档的文件夹, build.dir 是用于存储构建输出文件的路径。

  4. 之后,我们声明 Web 应用程序的名称,在我们的案例中它是 fax

  5. 我们还定义了主类路径,该路径包含项目 WEB-INF/lib 文件夹中存在的 JAR 文件。

  6. 我们还将 build.dir 中存在的类文件包括在主类路径中。

  7. Javadoc 目标会生成项目所需的 javadoc,而 usage 目标用于打印构建文件中存在的通用目标。

上面的示例展示了两个部署目标 − deploydeploywar .

部署目标从 Web 目录将文件复制到部署目录,同时保留上次修改的时间戳。这对于部署到支持热部署的服务器时非常有用。

clean 目标清除先前构建的所有文件。

deploywar 目标构建 war 文件,然后将 war 文件复制到应用程序服务器的部署目录。

Ant - Deploying Applications

在之前的章节中,我们学习了如何打包应用程序并将其部署到文件夹中。

本章中,我们将 Web 应用程序直接部署到应用程序服务器的部署文件夹中,然后添加一些 Ant 目标来启动和停止服务。

我们继续使用 Hello World fax Web 应用程序。这是上一章的继续;新组件在 bold 中突出显示。

build.properties

build.properties 的文件如下 −

# Ant properties for building the springapp
appserver.home=c:\\install\\apache-tomcat-7.0.19

# for Tomcat 5 use $appserver.home}/server/lib
# for Tomcat 6 use $appserver.home}/lib
appserver.lib=${appserver.home}/lib

deploy.path=${appserver.home}/webapps

tomcat.manager.url=https://www.tutorialspoint.com:8080/manager
tomcat.manager.username=tutorialspoint
tomcat.manager.password=secret

build.xml

build.xml 的文件如下 −

<?xml version="1.0"?>

<project name="fax" basedir="." default="usage">
   <property file="build.properties"/>
   <property name="src.dir" value="src"/>
   <property name="web.dir" value="war"/>
   <property name="javadoc.dir" value="doc"/>
   <property name="build.dir" value="${web.dir}/WEB-INF/classes"/>
   <property name="name" value="fax"/>

   <path id="master-classpath">
      <fileset dir="${web.dir}/WEB-INF/lib">
         <include name="*.jar"/>
      </fileset>
   <pathelement path="${build.dir}"/>
   </path>

   <target name="javadoc">
      <javadoc packagenames="faxapp.*" sourcepath="${src.dir}"
         destdir="doc" version="true" windowtitle="Fax Application">
         <doctitle><![CDATA[<h1>= Fax Application=</h1>]]></doctitle>
         <bottom><![CDATA[Copyright © 2011. All Rights Reserved.]]></bottom>
         <group title="util packages" packages="faxapp.util.*"/>
         <group title="web packages" packages="faxapp.web.*"/>
         <group title="data packages" packages="faxapp.entity.*:faxapp.dao.*"/>
      </javadoc>
   </target>

   <target name="usage">
      <echo message=""/>
      <echo message="${name} build file"/>
      <echo message="-----------------------------------"/>
      <echo message=""/>
      <echo message="Available targets are:"/>
      <echo message=""/>
      <echo message="deploy --> Deploy application as directory"/>
      <echo message="deploywar --> Deploy application as a WAR file"/>
      <echo message=""/>
   </target>


   <target name="build" description="Compile main source tree java files">
      <mkdir dir="${build.dir}"/>
      <javac destdir="${build.dir}" source="1.5" target="1.5" debug="true"
         deprecation="false" optimize="false" failonerror="true">
         <src path="${src.dir}"/>
         <classpath refid="master-classpath"/>
      </javac>
   </target>

   <target name="deploy" depends="build" description="Deploy application">
      <copy todir="${deploy.path}/${name}" preservelastmodified="true">
         <fileset dir="${web.dir}">
            <include name="**/*.*"/>
         </fileset>
      </copy>
   </target>

   <target name="deploywar" depends="build" description="Deploy application as a WAR file">
      <war destfile="${name}.war" webxml="${web.dir}/WEB-INF/web.xml">
         <fileset dir="${web.dir}">
            <include name="**/*.*"/>
         </fileset>
      </war>
      <copy todir="${deploy.path}" preservelastmodified="true">
         <fileset dir=".">
            <include name="*.war"/>
         </fileset>
      </copy>
   </target>

   <target name="clean" description="Clean output directories">
      <delete>
         <fileset dir="${build.dir}">
            <include name="**/*.class"/>
         </fileset>
      </delete>
   </target>
   <!-- ============================================================ -->
   <!-- Tomcat tasks -->
   <!-- ============================================================ -->

   <path id="catalina-ant-classpath">
   <!-- We need the Catalina jars for Tomcat -->
   <!-- * for other app servers - check the docs -->
      <fileset dir="${appserver.lib}">
         <include name="catalina-ant.jar"/>
      </fileset>
   </path>

   <taskdef name="install" classname="org.apache.catalina.ant.InstallTask">
      <classpath refid="catalina-ant-classpath"/>
   </taskdef>
   <taskdef name="reload" classname="org.apache.catalina.ant.ReloadTask">
      <classpath refid="catalina-ant-classpath"/>
   </taskdef>
   <taskdef name="list" classname="org.apache.catalina.ant.ListTask">
      <classpath refid="catalina-ant-classpath"/>
   </taskdef>
   <taskdef name="start" classname="org.apache.catalina.ant.StartTask">
      <classpath refid="catalina-ant-classpath"/>
   </taskdef>
   <taskdef name="stop" classname="org.apache.catalina.ant.StopTask">
      <classpath refid="catalina-ant-classpath"/>

   </taskdef>

   <target name="reload" description="Reload application in Tomcat">

      <reload url="${tomcat.manager.url}"username="${tomcat.manager.username}"
      password="${tomcat.manager.password}" path="/${name}"/>
   </target>
</project>

在本示例中,我们使用 Tomcat 作为我们的应用程序服务器。

首先,在构建属性文件中,我们定义了一些附加属性,如下所示 −

  1. appserver.home 指向 Tomcat 应用程序服务器的安装路径。

  2. appserver.lib 指向 Tomcat 安装文件夹中的库文件。

  3. deploy.path 变量现在指向 Tomcat 中的 Web 应用程序文件夹。

Tomcat 中的应用程序可以通过 Tomcat 管理器应用程序停止和启动。管理员应用程序的 URL、用户名和密码同时也指定在 build.properties 文件中。

接下来,我们声明一个新的 CLASSPATH,其中包含 catalina-ant.jar 。通过 Apache Ant 执行 Tomcat 任务需要此 jar 文件。

Tasks

catalina-ant.jar 提供了以下任务 −

Sr.No

Properties & Description

1

InstallTask 安装 Web 应用程序。类名:org.apache.catalina.ant.InstallTask

2

ReloadTask 重新加载 Web 应用程序。类名:org.apache.catalina.ant.ReloadTask

3

ListTask 列出所有 Web 应用程序。类名:org.apache.catalina.ant.ListTask

4

StartTask1 启动 Web 应用程序。类名:org.apache.catalina.ant.StartTask

5

StopTask 停止 Web 应用程序。类名:org.apache.catalina.ant.StopTask

6

ReloadTask 在不停止的情况下重新加载 Web 应用程序。类名:org.apache.catalina.ant.ReloadTask

重新加载任务需要以下附加参数:

  1. 管理器的应用程序 URL。

  2. 用于重新启动 Web 应用程序的用户名。

  3. 用于重新启动 Web 应用程序的密码。

  4. 要重新启动的 Web 应用程序名称。

让我们发出 deploy-war 命令以将 Webapp 复制到 Tomcat Webapps 文件夹,然后让我们重新加载传真 Web 应用程序。以下结果是运行 Ant 文件的结果:

C:\>ant deploy-war
Buildfile: C:\build.xml

BUILD SUCCESSFUL
Total time: 6.3 seconds

C:\>ant reload
Buildfile: C:\build.xml

BUILD SUCCESSFUL
Total time: 3.1 seconds

一旦运行了上述任务,Web 应用程序将部署并且 Web 应用程序将重新加载。

Ant - Executing Java code

您可以使用 Ant 来执行 Java 代码。在以下示例中,Java 类接收一个参数(管理员的电子邮件地址)并发送电子邮件。

public class NotifyAdministrator {
   public static void main(String[] args) {
      String email = args[0];
      notifyAdministratorviaEmail(email);
      System.out.println("Administrator "+email+" has been notified");
   }
   public static void notifyAdministratorviaEmail(String email {
      //......
   }
}

这是一个简单的构建,它执行该 Java 类。

<?xml version="1.0"?>
<project name="sample" basedir="." default="notify">
   <target name="notify">
      <java fork="true" failonerror="yes" classname="NotifyAdministrator">
         <arg line="admin@test.com"/>
      </java>
   </target>
</project>

当构建执行时,它将生成以下结果:

C:\>ant
Buildfile: C:\build.xml

notify: [java] Administrator admin@test.com has been notified

BUILD SUCCESSFUL
Total time: 1 second

在此示例中,Java 代码执行简单的操作,即发送电子邮件。我们可以使用内置于 Ant 任务中的任务来执行此操作。

但是,现在您有了想法,您可以扩展您的构建文件以调用执行复杂操作的 Java 代码。例如:加密您的源代码。

Ant - Eclipse Integration

如果您已经下载并安装了 Eclipse,您几乎不用做任何事情就可以开始。Eclipse 与 Ant 插件捆绑在一起,开箱即用。

按照如下简单步骤,可将 Ant 集成到 Eclipse 中。

  1. 确保 build.xml 是您 Java 项目的一部分,且不位于项目外部某个位置。

  2. 遵照 Window → Show View → Other → Ant → Ant 来启用 Ant View。

  3. 打开 Project Explorer,将 build.xml 拖到 Ant View 中。

您的 Ant 视口与此给定视口类似 −

eclipse ant

点击 target,build/clean/usage 将使用 target 运行 Ant。

点击“传真”将执行默认 target - usage

Ant Eclipse 插件还带有适合编辑 build.xml 的好编辑器。该编辑器了解 build.xml 架构并且可以帮助您完成代码。

要使用 Ant 编辑器,请右键单击您的 build.xml(从 Project Explorer 中),并选择用 > Ant Editor 打开。Ant 编辑器应类似于:

ant editor

Ant 编辑器在右侧列出 target。target 列表用作书签,以允许您直接跳到特定 target 编辑中。

Ant - JUnit Integration

JUnit 是基于 Java 开发的常用单元测试框架。它易于使用和扩展。有许多可用 JUnit 扩展。如果您不熟悉 JUnit,则应从 www.junit.org 下载它并阅读其手册。

本章介绍如何使用 Ant 执行 JUnit 测试。Ant 的使用通过 JUnit 任务变得简单。

JUnit 任务的属性如下所示 −

Sr.No

Properties & Description

1

dir 从何处调用 VM。当禁用分叉时,此项将被忽略。

2

jvm 用于调用 JVM 的命令。当禁用分叉时,此项将被忽略。

3

fork 在单独的 JVM 中运行测试。

4

errorproperty 如果有 JUnit 错误,则设置属性的名称。

5

failureproperty 如果有 JUnit 故障,则设置属性的名称。

6

haltonerror 在发生测试错误时停止执行。

7

haltonfailure 在发生故障时停止执行。

8

printsummary 建议 Ant 为每个测试显示简单统计数据。

9

showoutput 建议 Ant 将输出发送到其日志和格式化程序。

10

tempdir Ant 将使用到的临时文件的路径。

11

timeout 退出运行时间超过此设置(以毫秒为单位)的测试。

让我们继续 Hello World 传真 Web 应用程序的主题,并添加 JUnit 目标。

以下示例显示了一个简单的 JUnit 测试执行 −

<target name="unittest">
   <junit haltonfailure="true" printsummary="true">
      <test name="com.tutorialspoint.UtilsTest"/>
   </junit>
</target>

此示例显示在 com.tutorialspoint.UtilsTest junit 类上执行 JUnit。

运行以上代码将产生以下输出 −

test:
[echo] Testing the application
[junit] Running com.tutorialspoint.UtilsTest
[junit] Tests run: 12, Failures: 0, Errors: 0, Time elapsed: 16.2 sec
BUILD PASSED

Ant - Extending Ant

Ant 附带一组预定义的任务,但是您可以创建自己的任务,如下例所示:

自定义 Ant 任务应扩展 org.apache.tools.ant.Task 类并且应扩展 execute() 方法。

以下是一个简单的示例 −

package com.tutorialspoint.ant;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.BuildException;
public class MyTask extends Task {
   String message;
   public void execute() throws BuildException {
      log("Message: " + message, Project.MSG_INFO);
   }
   public void setMessage(String message) {
      this.message= message;
   }
}

如欲执行自定义任务,您需要将以下内容添加到 Hello World 传真 Web 应用程序 −

<target name="custom">
   <taskdef name="custom" classname="com.tutorialspoint.ant.MyTask" />
   <custom message="Hello World!"/>
</target>

执行上述自定义任务将打印消息“Hello World!”

c:\>ant custom
test:
[custom] Message : Hello World!
elapsed: 0.2 sec
BUILD PASSED

这仅是一个简单的示例。Ant 允许充分发挥其性能,助您提升构建和部署流程。

ANT - Using Token Filter

Ant 过滤器允许为当前项目设置一个标记过滤器。一个标记会用 @ 符号分隔,并且可以用属性文件读取。

Steps

  1. Step 1 − 使用 @@ 定义一个标记。

This is a sample text written in @year@.
  1. Step 2 − 设置过滤器。

<filter token="year" value="2021"/>
  1. Step 3 − 使用过滤器。所有任务都会将 @year@ 的出现替换为 2021。

<copy todir="${dest.dir}" filtering="true">
   <fileset dir="${src.dir}"/>
</copy>

Filter Task Properties

以下是关键属性 −

Sr.No

Attribute & Description

1

token 不带有分隔符字符 (@) 的标记字符串

2

value 当文件被复制时,替换标记的字符串。

3

filtersfile 必须从中读取过滤器的文件。此文件必须格式化为属性文件。

为了让 Filter 任务正常工作,必须提供标记和值或过滤器文件。

Example

使用以下内容创建一个 src 文件夹和 text1.txt 文件 −

This is a sample text written in @year@.

使用以下内容创建 build.xml −

<?xml version="1.0"?>
<project name="sample" basedir="." default="copy">
   <property name="src.dir" value="src"/>
   <property name="dest.dir" value="build"/>
   <target name="copy">
      <filter token="year" value="2021"/>
      <copy todir="${dest.dir}" filtering="true">
         <fileset dir="${src.dir}"/>
      </copy>
   </target>
</project>

Output

在上述构建文件上运行 Ant 会生成以下输出:

F:\tutorialspoint\ant>ant
Buildfile: F:\tutorialspoint\ant\build.xml

copy:
   [copy] Copying 1 file to F:\tutorialspoint\ant\build

BUILD SUCCESSFUL
Total time: 1 second

F:\tutorialspoint\ant>

查看复制到 build 文件夹的文件的内容。

This is a sample text written in 2021.

Ant - Using Command Line Arguments

Ant 可以轻松读取命令行参数,以便将数据传递给其任务。

Commnd Line Arguments Options

ant [options] [target [target2 [target3] ...]]
Options:
   -help,          -h              print this message and exit
   -projecthelp,   -p              print project help information and exit
   -version                        print the version information and exit
   -diagnostics                    print information that might be helpful to diagnose or report problems and exit
   -quiet,         -q              be extra quiet
   -silent,        -S              print nothing but task outputs and build failures
   -verbose,       -v              be extra verbose
   -debug,         -d              print debugging information
   -emacs,         -e              produce logging information without adornments
   -lib          <path>            specifies a path to search for jars and classes
   -logfile      <file>            use given file for log
   -l            <file>                      ''
   -logger       <classname>       the class which is to perform logging
   -listener     <classname>       add an instance of class as a project listener
   -noinput                              do not allow interactive input
   -buildfile    <file>            use given buildfile
   -file         <file>                      ''
   -f            <file>                      ''
   -D            <property>=<value>   use value for given property
   -keep-going,    -k              execute all targets that do not depend on failed target(s)
   -propertyfile <name>            load all properties from file with -D properties taking precedence
   -inputhandler <class>           the class which will handle input requests
   -find         <file>            (s)earch for buildfile towards the root of
   -s            <file>            the filesystem and use it
   -nice         number            A niceness value for the main thread:1 (lowest) to 10 (highest); 5  is the default
   -nouserlib                      Run ant without using the jar files from ${user.home}/.ant/lib
   -noclasspath                    Run ant without using CLASSPATH
   -autoproxy                      Java 5+ : use the OS proxies
   -main         <class>           override Ant's normal entry point

我们将使用 -Dproperty 将变量传递给构建任务。

Example

使用以下内容创建一个 src 文件夹和 text1.txt 文件 −

This is a sample text written in 2021.

使用以下内容创建 build.xml −

<?xml version="1.0"?>
<project name="sample" basedir="." default="copy">
   <target name="copy">
      <copy todir="${dest.dir}" filtering="true">
		<fileset dir="${src.dir}"/>
      </copy>
   </target>
</project>

Output

此处我们使用 src.dir 和 dest.dir 属性,但并未对其进行定义。我们将使用命令行参数来传递这些属性。在上述构建文件中运行 Ant 时,将生成以下输出 −

F:\tutorialspoint\ant>ant -Dsrc.dir=src -Ddest.dir=build
Buildfile: F:\tutorialspoint\ant\build.xml

copy:
   [copy] Copying 1 file to F:\tutorialspoint\ant\build
BUILD SUCCESSFUL
Total time: 0 seconds

F:\tutorialspoint\ant>

查看复制到 build 文件夹的文件的内容。

This is a sample text written in 2021.

Ant - If Else Arguments

Ant 允许基于传递的条件来运行目标。我们可以使用 if 语句或 unless 语句。

Syntax

<target name="copy" if="copyFile">
   <echo>Files are copied.</echo>
</target>
<target name="move" unless="copyFile">
   <echo>Files are moved.</echo>
</target>

我们将使用 -Dproperty 将变量(如 copyFile)传递给构建任务。将要定义变量,此处变量的值无关紧要。

Example

使用以下内容创建 build.xml −

<?xml version="1.0"?>
<project name="sample" basedir="." default="copy">
   <target name="copy" if="copyFile">
      <echo>Files are copied.</echo>
   </target>
   <target name="move" unless="copyFile">
      <echo>Files are moved.</echo>
   </target>
</project>

Output

在上述构建文件上运行 Ant 会生成以下输出:

F:\tutorialspoint\ant>ant -DcopyFile=true
Buildfile: F:\tutorialspoint\ant\build.xml

copy:
   [echo] Files are copied.

BUILD SUCCESSFUL
Total time: 0 seconds

F:\tutorialspoint\ant>ant move
Buildfile: F:\tutorialspoint\ant\build.xml

move:
   [echo] Files are moved.

BUILD SUCCESSFUL
Total time: 0 seconds

F:\tutorialspoint\ant>ant move -DcopyFile=true
Buildfile: F:\tutorialspoint\ant\build.xml

move:

BUILD SUCCESSFUL
Total time: 0 seconds

F:\tutorialspoint\ant>ant move -DcopyFile=false
Buildfile: F:\tutorialspoint\ant\build.xml

move:

BUILD SUCCESSFUL
Total time: 0 seconds

F:\tutorialspoint\ant>ant move -DcopyFile=true
Buildfile: F:\tutorialspoint\ant\build.xml

move:

BUILD SUCCESSFUL
Total time: 0 seconds

F:\tutorialspoint\ant>ant move
Buildfile: F:\tutorialspoint\ant\build.xml

move:
   [echo] Files are moved.

BUILD SUCCESSFUL
Total time: 0 seconds

F:\tutorialspoint\ant>

Ant - Custom Components

Ant 允许轻松创建和使用自定义组件。可通过实现 Condition、Selector、Filter 等接口来创建自定义组件。一旦类准备就绪,我们便可以使用 typedef 在 build.xml 内创建该组件,以便在任何目标下使用。

Syntax

首先,将一个类定义为 Ant 自定义组件,比如 TextSelector.java,然后在 build.xml 中定义一个选择器。

<typedef name="text-selector" classname="TextSelector" classpath="."/>

然后,在目标内使用该组件。

<target name="copy">
   <copy todir="${dest.dir}" filtering="true">
      <fileset dir="${src.dir}">
         <text-selector/>
      </fileset>
   </copy>
</target>

Example

使用以下内容创建 TextSelector.java,将其放置在与 build.xml 相同的位置 −

import java.io.File;
import org.apache.tools.ant.types.selectors.FileSelector;
public class TextFilter implements FileSelector {
   public boolean isSelected(File b, String filename, File f) {
      return filename.toLowerCase().endsWith(".txt");
   }
}

在 src 目录中创建一个 text1.txt 和一个 text2.java。目标是将仅 .txt 文件复制到构建目录。

使用以下内容创建 build.xml −

<?xml version="1.0"?>
<project name="sample" basedir="." default="copy">
   <property name="src.dir" value="src"/>
   <property name="dest.dir" value="build"/>
   <typedef name="text-selector" classname="TextSelector"  classpath="."/>
   <target name="copy">
      <copy todir="${dest.dir}" filtering="true">
         <fileset dir="${src.dir}">
            <text-selector/>
         </fileset>
      </copy>
   </target>
</project>

Output

在上述构建文件上运行 Ant 会生成以下输出:

F:\tutorialspoint\ant>ant
Buildfile: F:\tutorialspoint\ant\build.xml

copy:
   [copy] Copying 1 file to F:\tutorialspoint\ant\build

BUILD SUCCESSFUL
Total time: 0 seconds

现在仅复制 .txt 文件。

Ant - Listeners & Loggers

Ant 允许使用侦听器和记录器监控构建过程。

Listeners

Ant 提供以下事件,可以使用侦听器捕获这些事件。

  1. build started

  2. build finished

  3. target started

  4. target finished

  5. task started

  6. task finished

  7. message logged

可以使用 -listener 参数在命令行上注册自定义侦听器。

Loggers

记录器扩展了侦听器的功能,并添加了以下特性

  1. 可以使用 -logfile 参数将日志信息记录到控制台或文件中

  2. 可以使用诸如 -quiet、-verbose、-debug 之类的日志记录级别进行日志记录

  3. Are emacs-mode aware

Built-in Listeners/loggers

  1. org.apache.tools.ant.DefaultLogger − 除非使用 -logger 命令行切换覆盖,否则隐式使用的记录器。

  2. org.apache.tools.ant.NoBannerLogger − 该记录器会忽略空目标输出的输出。

  3. org.apache.tools.ant.listener.MailLogger − 扩展 DefaultLogger,这样输出仍然以相同方式生成,并且在构建完成后可以发送电子邮件。

  4. org.apache.tools.ant.listener.AnsiColorLogger − 为构建输出添加颜色。

  5. org.apache.tools.ant.listener.Log4jListener − 将事件传递给 Apache Log4j 以实现高度可定制的日志记录。

  6. org.apache.tools.ant.XmlLogger − 将构建信息写入 XML 文件。

  7. org.apache.tools.ant.TimestampedLogger − 打印构建完成的时间

  8. org.apache.tools.ant.listener.BigProjectLogger − 为每个目标打印项目名称

  9. org.apache.tools.ant.listener.SimpleBigProjectLogger − 仅为子项目打印项目名称,否则在 Ant 1.8.1 中如同 NoBannerLogger

  10. org.apache.tools.ant.listener.ProfileLogger − 默认记录器,为每个任务和目标添加开始时间、结束时间和持续时间。

Example

使用以下内容创建 build.xml:

<?xml version="1.0"?>
<project name="sample" basedir="." default="copy">
   <target name="copy">
     <echo>File Copied</echo>
   </target>
</project>

Output

在上述构建文件上运行 Ant 会生成以下输出:

F:\tutorialspoint\ant>ant -logger org.apache.tools.ant.listener.TimestampedLogger
Buildfile: F:\tutorialspoint\ant\build.xml

copy:
   [echo] File Copied

BUILD SUCCESSFUL - at 03/12/21, 11:24 AM
Total time: 0 seconds

F:\tutorialspoint\ant>ant -logger org.apache.tools.ant.XmlLogger -verbose -logfile build_log.xml
Apache Ant(TM) version 1.10.12 compiled on October 13 2021
Trying the default build file: build.xml
Buildfile: F:\tutorialspoint\ant\build.xml

现在,你可以检查 build_log.xml 文件是否已使用相关日志创建。