Ant 简明教程
Ant - Introduction
ANT 代表 Another Neat 工具。它是一种来自计算机软件开发公司 Apache 的基于 Java 的构建工具。在深入了解 Apache Ant 的细节之前,让我们首先理解为什么我们需要一个构建工具。
Need for a Build Tool
通常,开发人员将大量时间花在执行构建和部署等平凡任务上,其中包括−
-
Compiling the code
-
Packaging the binaries
-
将二进制文件部署到测试服务器
-
Testing the changes
-
将代码从一个位置复制到另一个位置
为了自动化和简化上述任务,Apache Ant 非常有用。它是一种可以从命令行执行的操作系统构建和部署工具。
Ant - Environment Setup
Apache Ant 以 Apache 软件许可证分发,该许可证是开源计划认证的、成熟的开源许可证。
最新版本的 Apache Ant, 包括了它的全源代码、类文件和文档,可以在 https://ant.apache.org 找到。
Installing Apache Ant
我们假设您已经下载并安装了 Java 开发工具包 (JDK)。如果没有,请按照 file:///C:/java/java_environment_setup.htm 的说明进行操作。
-
确保 JAVA_HOME 环境变量设置为您的 JDK 所安装到的文件夹。
-
从 https://ant.apache.org 下载二进制文件。
-
使用 Winzip、winRAR、7-zip 或类似工具将 zip 文件解压缩到 c:\folder 之类的方便位置中。
-
创建一个名为 ANT_HOME 的新环境变量,它指向 Ant 安装文件夹。这儿这个文件夹是 c:\apache-ant-1.10.12-bin 文件夹。
-
将 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
-
从 www.eclipse.org 下载最新的 Eclipse 二进制文件。
-
将 Eclipse 二进制文件解压缩到方便的位置,比如 c:\folder。
-
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
将属性存储在单独的文件中会带来以下好处:
-
它允许你对同一构建文件进行重复使用,针对不同的执行环境使用不同的属性设置。例如,可以在 DEV、TEST 和 PROD 环境中分别维护构建属性文件。
-
在你事先不知道某个属性的值(在特定环境中)时,这非常有用。这允许你在属性值已知,其他环境中执行构建。
没有硬性规定,但通常属性文件被命名为 build.properties ,并与 build.xml 文件放在一起。你可以根据部署环境创建多个构建属性文件,比如 build.properties.dev 和 build.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
模式集是一种模式,允许根据某些模式轻松过滤文件或文件夹。可以使用以下元字符创建模式:
-
?- 仅匹配一个字符。
-
- 匹配零个或多个字符。
-
**- 递归匹配零个或多个目录。
以下示例描述了模式集的用法。
<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
文件列表数据类型与文件集类似,但存在以下差异:
-
它包含明确命名的文件列表,并且不支持通配符。
-
此数据类型可应用于现有或不存在的文件。
让我们看一下文件列表数据类型的以下示例。在此处,属性 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>
在上面提到的代码中:
-
属性 output.dir 指向项目的输出文件夹。
-
属性 releasenotes.dir 指向项目的发布说明文件夹。
-
属性 current.version 指向项目的当前版本文件夹。
-
顾名思义,copy 任务用于将文件从一个位置复制到另一个位置。
Path
path 数据类型通常用于表示类路径。路径中的条目使用分号或冒号分隔。但是,这些字符会在运行时被执行系统的路径分隔符字符替换。
类路径被设置为项目中 jar 文件和类的列表,如下面的示例所示。
<path id="build.classpath.jar">
<pathelement path="${env.J2EE_HOME}/${j2ee.jar}"/>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
</path>
在上面给出的代码中:
-
属性 env.J2EE_HOME 指向环境变量 J2EE_HOME 。
-
属性 j2ee.jar 指向 J2EE 基本文件夹中的 J2EE jar 文件名称。
Ant - Building Projects
既然我们已学习了 Ant 中的数据类型,是时候将这份知识付诸实践了。我们将在本章中构建一个项目。本章的目标是构建一个 Ant 文件,编译 Java 类并将其置于 WEB-INF\classes 文件夹中。
考虑以下项目结构:
-
数据库脚本存储在 db 文件夹中。
-
java 源代码存储在 src 文件夹中。
-
图像、js、META-INF 和样式 (css) 存储在 war 文件夹中。
-
Java Server Pages (JSP) 存储在 jsp 文件夹中。
-
第三方 jar 文件存储在 lib 文件夹中。
-
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"/>
在上述示例中,
-
src.dir 指的是项目的源文件夹,其中可以找到 java 源文件。
-
web.dir 指的是项目的 Web 源文件夹,可以在其中找到 JSP、web.xml、css、javascript 和其他与 Web 相关的文件。
-
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
源可以通过 sourcepath 、 sourcepathref 或 sourcefiles 指定。
-
sourcepath 用于指向源文件所在的文件夹(例如 src 文件夹)。
-
sourcepathref 用于引用 path 属性引用的路径(例如,delegates.src.dir)。
-
当您希望将各个文件指定为逗号分隔的列表时,请使用 sourcefiles 。
目标路径是使用 destdir 文件夹指定的(例如 build.dir)。
您可以通过指定要包含的程序包名称来过滤 javadoc 任务。这是通过使用 packagenames 属性(逗号分隔的程序包文件列表)来实现的。
您可以过滤 javadoc 进程,以仅显示 public、private、package 或 protected 类和成员。这是通过使用 private 、 public 、 package 和 protected 属性实现的。
您还可以通过使用相应属性来告诉 javadoc 任务包含作者和版本信息。
您还可以使用 group 属性对包进行分组,以便于导航。
Putting it all together
让我们继续 Hello world 传真应用程序的主题,并向传真应用程序项目添加文档目标。
下面给出了项目中使用的一个 javadoc 任务示例。在此示例中,我们指定 javadoc 使用 src.dir 作为源目录,使用 doc 作为目标。
我们还自定义了显示在 java 文档页面上的窗口标题、页眉和页脚信息。
此外,我们还创建了三个组:
-
第一个组是我们源文件夹中的实用程序类,
-
一个用于用户界面类,
-
一个用于数据库相关类。
你可能会注意到,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.properties 和 build.xml 文件如下:
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>
在上述示例中,
-
我们首先在构建属性文件中将 Tomcat 中的 webapps 文件夹路径声明为 deploy.path 变量。
-
我们还在 src.dir 变量中声明 Java 文件的源文件夹。
-
然后,我们在 web.dir 变量中声明 Web 文件的源文件夹。 javadoc.dir 是用于存储 Java 文档的文件夹, build.dir 是用于存储构建输出文件的路径。
-
之后,我们声明 Web 应用程序的名称,在我们的案例中它是 fax 。
-
我们还定义了主类路径,该路径包含项目 WEB-INF/lib 文件夹中存在的 JAR 文件。
-
我们还将 build.dir 中存在的类文件包括在主类路径中。
-
Javadoc 目标会生成项目所需的 javadoc,而 usage 目标用于打印构建文件中存在的通用目标。
上面的示例展示了两个部署目标 − deploy 和 deploywar .
部署目标从 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 作为我们的应用程序服务器。
首先,在构建属性文件中,我们定义了一些附加属性,如下所示 −
-
appserver.home 指向 Tomcat 应用程序服务器的安装路径。
-
appserver.lib 指向 Tomcat 安装文件夹中的库文件。
-
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 |
重新加载任务需要以下附加参数:
-
管理器的应用程序 URL。
-
用于重新启动 Web 应用程序的用户名。
-
用于重新启动 Web 应用程序的密码。
-
要重新启动的 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 中。
-
确保 build.xml 是您 Java 项目的一部分,且不位于项目外部某个位置。
-
遵照 Window → Show View → Other → Ant → Ant 来启用 Ant View。
-
打开 Project Explorer,将 build.xml 拖到 Ant View 中。
您的 Ant 视口与此给定视口类似 −
点击 target,build/clean/usage 将使用 target 运行 Ant。
点击“传真”将执行默认 target - usage 。
Ant Eclipse 插件还带有适合编辑 build.xml 的好编辑器。该编辑器了解 build.xml 架构并且可以帮助您完成代码。
要使用 Ant 编辑器,请右键单击您的 build.xml(从 Project Explorer 中),并选择用 > Ant Editor 打开。Ant 编辑器应类似于:
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
-
Step 1 − 使用 @@ 定义一个标记。
This is a sample text written in @year@.
-
Step 2 − 设置过滤器。
<filter token="year" value="2021"/>
-
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>
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>
Ant - Listeners & Loggers
Ant 允许使用侦听器和记录器监控构建过程。
Listeners
Ant 提供以下事件,可以使用侦听器捕获这些事件。
-
build started
-
build finished
-
target started
-
target finished
-
task started
-
task finished
-
message logged
可以使用 -listener 参数在命令行上注册自定义侦听器。
Loggers
记录器扩展了侦听器的功能,并添加了以下特性
-
可以使用 -logfile 参数将日志信息记录到控制台或文件中
-
可以使用诸如 -quiet、-verbose、-debug 之类的日志记录级别进行日志记录
-
Are emacs-mode aware
Built-in Listeners/loggers
-
org.apache.tools.ant.DefaultLogger − 除非使用 -logger 命令行切换覆盖,否则隐式使用的记录器。
-
org.apache.tools.ant.NoBannerLogger − 该记录器会忽略空目标输出的输出。
-
org.apache.tools.ant.listener.MailLogger − 扩展 DefaultLogger,这样输出仍然以相同方式生成,并且在构建完成后可以发送电子邮件。
-
org.apache.tools.ant.listener.AnsiColorLogger − 为构建输出添加颜色。
-
org.apache.tools.ant.listener.Log4jListener − 将事件传递给 Apache Log4j 以实现高度可定制的日志记录。
-
org.apache.tools.ant.XmlLogger − 将构建信息写入 XML 文件。
-
org.apache.tools.ant.TimestampedLogger − 打印构建完成的时间
-
org.apache.tools.ant.listener.BigProjectLogger − 为每个目标打印项目名称
-
org.apache.tools.ant.listener.SimpleBigProjectLogger − 仅为子项目打印项目名称,否则在 Ant 1.8.1 中如同 NoBannerLogger
-
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 文件是否已使用相关日志创建。