- Apache ANT 教程
- ANT - 首页
- ANT - 简介
- ANT - 环境设置
- ANT - 构建文件
- ANT - 属性任务
- ANT - 属性文件
- ANT - 数据类型
- ANT - 构建项目
- ANT - 构建文档
- ANT - 创建 JAR 文件
- ANT - 创建 WAR 文件
- ANT - 打包应用程序
- ANT - 部署应用程序
- ANT - 执行 Java 代码
- ANT - Eclipse 集成
- ANT - JUnit 集成
- ANT - 扩展 Ant
- Apache ANT 有用示例
- ANT - 使用 Token
- ANT - 使用命令行参数
- ANT - 使用 If Else 参数
- ANT - 自定义组件
- ANT - 监听器和日志记录器
- Apache ANT 资源
- ANT - 快速指南
- ANT - 有用资源
- ANT - 讨论
Ant - 快速指南
Ant - 简介
ANT 代表 **Another Neat** 工具。它是由计算机软件开发公司 Apache 开发的基于 Java 的构建工具。在深入了解 Apache Ant 的细节之前,让我们首先了解一下为什么我们需要构建工具。
构建工具的必要性
平均而言,开发人员会花费大量时间执行诸如构建和部署之类的例行任务,其中包括:
编译代码
打包二进制文件
将二进制文件部署到测试服务器
测试更改
将代码从一个位置复制到另一个位置
为了自动化和简化上述任务,Apache Ant 非常有用。它是一个操作系统构建和部署工具,可以从命令行执行。
Apache Ant 的历史
Ant 由软件开发人员 James Duncan Davidson 创建,他也是 Web 服务器应用程序 Tomcat 的最初创建者。
Ant 最初用于构建 Tomcat,并作为 Tomcat 发行版的一部分捆绑在一起。
它诞生于与 Apache Make 工具相关的各种问题和复杂性。
它于 2000 年在 Apache 中作为独立项目推广。截至 2021 年 10 月,Apache Ant 的最新版本为 **1.10.12**。
Apache Ant 的特性
Apache Ant 的特性如下:
它是目前最完整的 Java 构建和部署工具。
它是平台中立的,并且可以处理特定于平台的属性,例如文件分隔符。
它可以用于执行特定于平台的任务,例如使用“touch”命令修改文件的修改时间。
Ant 脚本使用纯 XML 编写。如果您已经熟悉 XML,那么您可以很快学会 Ant。
Ant 擅长自动化复杂且重复的任务。
Ant 带有一个大型预定义任务列表。
Ant 提供了一个接口来开发自定义任务。
Ant 可以轻松地从命令行调用,并且可以与免费和商业 IDE 集成。
Ant - 环境设置
Apache Ant 在 Apache 软件许可证下分发,该许可证是开源计划认证的完整开源许可证。
最新的 Apache Ant 版本(包括其完整源代码、类文件和文档)可以在 https://ant.apache.org 找到。
安装 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** 文件夹。
验证安装
要验证 Apache Ant 是否已成功安装在您的计算机上,请在命令提示符中键入 ant。
您应该看到如下输出:
C:\>ant -version Apache Ant(TM) version 1.10.12 compiled on October 13 2021
如果您没有看到上述输出,请验证您是否正确地按照安装步骤操作。
安装 Eclipse
本教程还涵盖了 Ant 与 Eclipse 集成开发环境 (IDE) 的集成。因此,如果您尚未安装 Eclipse,请下载并安装 Eclipse。
安装 Eclipse 的步骤
从 www.eclipse.org 下载最新的 Eclipse 二进制文件。
将 Eclipse 二进制文件解压缩到方便的位置,例如 c:\folder。
从 c:\eclipse\eclipse.exe 运行 Eclipse。
Ant - 构建文件
通常,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** 有三个属性,如下所示:
序号 | 属性 & 描述 |
---|---|
1 | name 项目的名称。(可选) |
2 | default 构建脚本的默认目标。一个项目可以包含任意数量的目标。此属性指定哪个目标应被视为默认目标。(必需) |
3 | basedir 项目的基目录(或)根文件夹。(可选) |
目标是您希望作为一个单元运行的任务的集合。在我们的示例中,我们有一个简单的目标来向用户提供信息消息。
目标可以依赖于其他目标。例如,**deploy** 目标可能依赖于 package 目标,**package** 目标可能依赖于 compile 目标,依此类推。依赖关系使用 **depends** 属性表示。
例如:
<target name="deploy" depends="package"> .... </target> <target name="package" depends="clean,compile"> .... </target> <target name="clean" > .... </target> <target name="compile" > .... </target>
target 元素具有以下属性:
序号 | 属性 & 描述 |
---|---|
1 | name 目标的名称(必需) |
2 | depends 此目标依赖的所有目标的逗号分隔列表。(可选) |
3 | description 目标的简短描述。(可选) |
4 | if 允许根据条件属性的真假执行目标。(可选) |
5 | unless 将目标添加到指定扩展点的依赖项列表中。扩展点类似于目标,但它没有任何任务。(可选) |
上面示例中的 **echo** 任务是一个简单的任务,它打印一条消息。在我们的示例中,它打印消息 **Hello World**。
要运行 ant 构建文件,请打开命令提示符并导航到 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 - 属性任务
Ant 构建文件是用 XML 编写的,它不允许像您在喜欢的编程语言中那样声明变量。但是,正如您可能想象的那样,如果 Ant 允许声明诸如项目名称、项目源目录等变量,那将非常有用。
Ant 使用 **property** 元素,允许您指定属性。这允许属性从一个构建更改为另一个构建,或从一个环境更改为另一个环境。
Ant 属性
默认情况下,Ant 提供以下预定义属性,可以在构建文件中使用:
序号 | 属性 & 描述 |
---|---|
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 - 属性文件
如果使用少量属性,则直接在构建文件中设置属性是可以的。但是,对于大型项目,将属性存储在单独的属性文件中更有意义。
好处
将属性存储在单独的文件中提供了以下好处:
它允许您重用同一个构建文件,但针对不同的执行环境使用不同的属性设置。例如,可以分别为 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 还带有一些预定义的构建属性,这些属性在上一节中列出,但为了方便参考,这里再次列出。
序号 | 属性 & 描述 |
---|---|
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 - 数据类型
Ant 提供了许多预定义的数据类型。不要将“数据类型”一词与编程语言中可用的数据类型混淆。相反,将其视为已内置到产品中的一组服务。
Ant 中的数据类型
Apache Ant 提供以下数据类型。
Fileset
fileset 数据类型表示文件的集合。它用作过滤器,用于包含或排除与特定模式匹配的文件。
例如,请参考以下代码。这里,src 属性指向项目的源文件夹。
<fileset dir="${src}" casesensitive="yes"> <include name="**/*.java"/> <exclude name="**/*Stub*"/> </fileset>
fileset 选择源文件夹中的所有 .java 文件,但包含单词“Stub”的文件除外。区分大小写的过滤器应用于 fileset,这意味着名为 Samplestub.java 的文件不会从 fileset 中排除。
模式集
模式集是一种模式,允许基于某些模式轻松过滤文件或文件夹。可以使用以下元字符创建模式:
? - 仅匹配一个字符。
* - 匹配零个或多个字符。
** - 递归匹配零个或多个目录。
以下示例描述了模式集的用法。
<patternset id="java.files.without.stubs"> <include name="src/**/*.java"/> <exclude name="src/**/*Stub*"/> </patternset>
然后可以将 patternset 与 fileset 结合使用,如下所示:
<fileset dir="${src}" casesensitive="yes"> <patternset refid="java.files.without.stubs"/> </fileset>
文件列表
filelist 数据类型类似于文件集,但存在以下区别:
它包含显式命名的文件列表,并且不支持通配符。
此数据类型可以应用于现有文件或不存在的文件。
让我们看看 filelist 数据类型的以下示例。这里,属性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>
过滤器集
通过将 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 数据类型通常用于表示类路径。路径中的条目使用分号或冒号分隔。但是,这些字符在运行时会被执行系统路径分隔符字符替换。
类路径设置为项目中 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 - 构建项目
现在我们已经了解了 Ant 中的数据类型,是时候将这些知识付诸实践了。我们将在本章中构建一个项目。本章的目的是构建一个 Ant 文件,该文件编译 Java 类并将它们放置在 WEB-INF\classes 文件夹中。
考虑以下项目结构:
数据库脚本存储在db文件夹中。
Java 源代码存储在src文件夹中。
图像、js、META-INF、样式(css)存储在war文件夹中。
Java 服务器页面 (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文件夹中。
Ant - 构建文档
文档在任何项目中都是必须的。文档在项目的维护中起着重要作用。Java 通过使用内置的javadoc工具使文档编制变得更容易。Ant 通过按需生成文档使其变得更加容易。
如您所知,javadoc 工具非常灵活,并允许许多配置选项。Ant 通过 javadoc 任务公开这些配置选项。如果您不熟悉 javadoc,我们建议您从本 Java 文档教程开始。
以下部分列出了 Ant 中最常用的 javadoc 选项。
属性
可以使用sourcepath、sourcepathref或sourcefiles指定源。
sourcepath用于指向源文件文件夹(例如 src 文件夹)。
sourcepathref用于引用 path 属性引用的路径(例如,delegates.src.dir)。
sourcefiles用于当您想将各个文件指定为逗号分隔的列表时。
目标路径使用destdir文件夹指定(例如 build.dir)。
您可以通过指定要包含的包名称来过滤javadoc任务。这是通过使用packagenames属性(包文件的逗号分隔列表)实现的。
您可以过滤 javadoc 过程以仅显示公共、私有、包或受保护的类和成员。这是通过使用private、public、package和protected属性实现的。
您还可以告诉 javadoc 任务包含作者和版本信息,方法是使用相应的属性。
您还可以使用 group 属性将包组合在一起,以便于导航。
将所有内容放在一起
让我们继续我们的Hello world传真应用程序主题,并在我们的传真应用程序项目中添加一个文档目标。
下面给出了一个在我们项目中使用的 javadoc 任务示例。在此示例中,我们已指定 javadoc 使用src.dir作为源目录,并将doc作为目标。
我们还自定义了出现在 Java 文档页面上的窗口标题、标题和页脚信息。
此外,我们创建了三个组:
一个用于我们源文件夹中的实用程序类,
一个用于用户界面类,以及
一个用于与数据库相关的类。
您可能会注意到数据包组有两个包——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 任务。它生成并将 Java 文档文件放置在 doc 文件夹中。
执行javadoc 目标时,会产生以下结果:
C:\>ant generate-javadoc Buildfile: C:\build.xml java doc has been generated! BUILD SUCCESSFUL Total time: 10.63 second
Java 文档文件现在位于doc文件夹中。
通常,javadoc 文件作为发布或包目标的一部分生成。
Ant - 创建 JAR 文件
编译 Java 源文件后的下一个逻辑步骤是构建 Java 存档,即 Java 存档 (JAR) 文件。使用 Ant 创建 JAR 文件非常简单,只需使用jar任务即可。
属性
jar 任务的常用属性如下:
序号 | 属性 & 描述 |
---|---|
1 | basedir 输出 JAR 文件的基本目录。默认情况下,它设置为项目的基目录。 |
2 | compress 建议 Ant 在创建 JAR 文件时压缩文件。 |
3 | keepcompression 虽然 compress 属性适用于单个文件,但 keepcompression 属性执行相同操作,但它应用于整个存档。 |
4 | destfile 输出 JAR 文件的名称。 |
5 | duplicate 建议 Ant 在找到重复文件时该怎么做。您可以添加、保留或失败重复文件。 |
6 | excludes 建议 Ant 不要将这些逗号分隔的文件列表包含在包中。 |
7 | excludesfile 与上面相同,只是排除文件是使用模式指定的。 |
8 | inlcudes excludes 的反义词。 |
9 | includesfile 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属性指向构建文件夹,其中可以找到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 - 创建 WAR 文件
使用 Ant 创建 Web 存档 (WAR) 文件非常简单,并且与创建 JAR 文件的任务非常相似。毕竟,WAR 文件与 JAR 文件一样,只是另一个 ZIP 文件。
WAR 任务是 JAR 任务的扩展,但它增加了一些很好的功能来操作 WEB-INF/classes 文件夹中的内容,以及生成 web.xml 文件。WAR 任务可用于指定 WAR 文件的特定布局。
由于 WAR 任务是 JAR 任务的扩展,因此 JAR 任务的所有属性都适用于 WAR 任务。
序号 | 属性 & 描述 |
---|---|
1 | webxml web.xml 文件的路径。 |
2 | lib 一个分组,用于指定要放入 WEB-INF\lib 文件夹中的内容。 |
3 | classes 一个分组,用于指定要放入 WEB-INF\classes 文件夹中的内容。 |
4 | metainf 指定生成 MANIFEST.MF 文件的指令。 |
继续我们的 **Hello World** 传真应用程序项目,让我们添加一个新的目标来生成 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 文件夹中已经存在此文件。最后,我们复制构建目录 web 文件夹中的所有类,并将它们放入 WEB-INF/classes 文件夹中。
将 war 任务包装在一个 Ant 目标(通常是 package)中并运行它。这将在指定位置创建 WAR 文件。
完全可以嵌套 classes、lib、metainf 和 webinf 目录,以便它们位于项目结构中任何分散的文件夹中。但是,最佳实践建议您的 Web 项目应具有与 WAR 文件结构类似的 Web 内容结构。传真应用程序项目使用此基本原理概述了其结构。
要执行 war 任务,请将其包装在一个目标中,最常见的是 build 或 package 目标,然后运行它们。
<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 - 打包应用程序
我们已经分阶段地学习了使用 **Hello World** 传真 web 应用程序的 Ant 的不同方面。
现在,是时候将所有内容整合在一起,创建一个完整且完整的 build.xml 文件。请考虑如下所示的 **build.properties** 和 **build.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>
在上面提到的示例中:
我们首先在 build properties 文件中将 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**。
deploy 目标将文件从 web 目录复制到 deploy 目录,同时保留最后修改日期时间戳。这在部署到支持热部署的服务器时非常有用。
clean 目标清除所有先前构建的文件。
deploywar 目标构建 war 文件,然后将 war 文件复制到应用程序服务器的 deploy 目录。
Ant - 部署应用程序
在上一章中,我们学习了如何打包应用程序并将其部署到文件夹中。
在本章中,我们将直接将 web 应用程序部署到应用程序服务器的 deploy 文件夹,然后添加一些 Ant 目标来启动和停止服务。
让我们继续使用 **Hello World** 传真 web 应用程序。这是上一章的延续;新组件以 **粗体** 突出显示。
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://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 作为我们的应用程序服务器。
首先,在 build properties 文件中,我们定义了一些其他属性,如下所述 -
**appserver.home** 指向 Tomcat 应用程序服务器的安装路径。
**appserver.lib** 指向 Tomcat 安装文件夹中的库文件。
**deploy.path** 变量现在指向 Tomcat 中的 webapp 文件夹。
可以使用 Tomcat 管理器应用程序停止和启动 Tomcat 中的应用程序。管理器应用程序的 URL、用户名和密码也在 build.properties 文件中指定。
接下来,我们声明一个新的 CLASSPATH,其中包含 **catalina-ant.jar**。此 jar 文件是通过 Apache Ant 执行 Tomcat 任务所必需的。
任务
catalina-ant.jar 提供以下任务 -
序号 | 属性 & 描述 |
---|---|
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 |
reload 任务需要以下其他参数 -
管理器应用程序的 URL。
重新启动 web 应用程序的用户名。
重新启动 web 应用程序的密码。
要重新启动的 web 应用程序的名称。
让我们发出 **deploy-war** 命令将 webapp 复制到 Tomcat webapps 文件夹,然后重新加载 Fax 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 应用程序将被部署并重新加载。
Ant - 执行 Java 代码
您可以使用 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="[email protected]"/> </java> </target> </project>
执行构建时,它会产生以下结果 -
C:\>ant Buildfile: C:\build.xml notify: [java] Administrator [email protected] has been notified BUILD SUCCESSFUL Total time: 1 second
在此示例中,java 代码执行了一个简单的事情,即发送电子邮件。我们可以使用 Ant 任务的内置功能来做到这一点。
但是,既然您已经了解了这个概念,您可以扩展您的构建文件以调用执行复杂操作的 java 代码。例如 - 加密您的源代码。
Ant - Eclipse 集成
如果您已经下载并安装了 Eclipse,那么您几乎不需要做任何事情就可以开始使用。Eclipse 预捆绑了 Ant 插件,随时可以使用。
按照简单的步骤,将 Ant 集成到 Eclipse 中。
确保 build.xml 是您 java 项目的一部分,并且不位于项目外部的位置。
通过以下操作启用 Ant 视图 **窗口 → 显示视图 → 其他 → Ant → Ant**。
打开项目资源管理器,将 build.xml 拖到 Ant 视图中。
您的 Ant 视图看起来类似于下面所示 -
单击目标 build/clean/usage 将使用该目标运行 Ant。
单击“fax”将执行默认目标 - **usage**。
Ant Eclipse 插件还带有一个用于编辑 build.xml 文件的良好编辑器。编辑器了解 build.xml 模式,可以帮助您完成代码。
要使用 Ant 编辑器,请右键单击您的 build.xml(来自项目资源管理器)并选择“使用 > Ant 编辑器打开”。Ant 编辑器应该看起来类似于 -
Ant 编辑器在右侧列出了目标。目标列表用作书签,允许您直接跳转到编辑特定目标。
Ant - JUnit 集成
JUnit 是用于基于 Java 的开发的常用单元测试框架。它易于使用且易于扩展。有许多可用的 JUnit 扩展。如果您不熟悉 JUnit,则应从 www.junit.org 下载它并阅读其手册。
本章展示了如何使用 Ant 执行 JUnit 测试。通过 JUnit 任务,使用 Ant 使其变得非常简单。
JUnit 任务的属性如下所示 -
序号 | 属性 & 描述 |
---|---|
1 | dir 从哪里调用 VM。禁用 fork 时将忽略此选项。 |
2 | jvm 用于调用 JVM 的命令。禁用 fork 时将忽略此选项。 |
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 - 扩展 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 - 使用 Token 过滤器
Ant 过滤器允许为当前项目设置 Token 过滤器。Token 由 @ 符号分隔,也可以使用属性文件读取。
步骤
**步骤 1** - 使用 @@ 定义 Token。
This is a sample text written in @year@.
**步骤 2** - 设置过滤器。
<filter token="year" value="2021"/>
**步骤 3** - 使用过滤器。所有任务都将用 2021 替换 @year@ 的出现。
<copy todir="${dest.dir}" filtering="true"> <fileset dir="${src.dir}"/> </copy>
过滤器任务属性
以下是关键属性 -
序号 | 属性 & 描述 |
---|---|
1 | token 不带分隔符字符(@)的 Token 字符串 |
2 | value 复制文件时应用于替换 Token 的字符串。 |
3 | filtersfile 必须从中读取过滤器的文件。此文件必须格式化为属性文件。 |
必须提供 Token 和 Value,或者提供 filtersfile 给 Filter 任务才能正常工作。
示例
创建一个 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 会产生以下输出:
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 - 使用命令行参数
Ant 可以轻松读取命令行参数,并将数据传递给其任务。
命令行参数选项
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 将变量传递到构建任务。
示例
创建一个 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>
输出
这里我们使用 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 参数
Ant 允许根据传递的条件运行目标。我们可以使用if语句或unless语句。
语法
<target name="copy" if="copyFile"> <echo>Files are copied.</echo> </target> <target name="move" unless="copyFile"> <echo>Files are moved.</echo> </target>
我们将使用 -Dproperty 将变量(如 copyFile)传递到构建任务。需要定义该变量,但变量的值在这里无关紧要。
示例
创建包含以下内容的 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>
输出
在上述构建文件上运行 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 - 自定义组件
Ant 允许非常轻松地创建和使用自定义组件。可以通过实现 Condition、Selector、Filter 等接口来创建自定义组件。一旦类准备就绪,我们就可以使用typedef在 build.xml 中创建组件,以便在任何目标下使用。
语法
首先定义一个类作为 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>
示例
创建包含以下内容的 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 目录。
创建包含以下内容的 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 会产生以下输出:
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 - 监听器和日志记录器
Ant 允许使用监听器和日志记录器来监控构建过程。
监听器
Ant 提供以下事件,可以使用监听器捕获这些事件。
构建开始
构建完成
目标开始
目标完成
任务开始
任务完成
记录消息
可以使用-listener参数在命令行上注册自定义监听器。
日志记录器
日志记录器扩展了监听器的功能,并添加了以下功能
可以使用-logfile参数将信息记录到控制台或文件中
可以使用日志记录级别(如 -quiet、-verbose、-debug)进行记录
支持 emacs 模式
内置监听器/日志记录器
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 - 仅对子项目打印项目名称,否则与 NoBannerLogger 相同(自 Ant 1.8.1 起)
org.apache.tools.ant.listener.ProfileLogger - 默认日志记录器,为每个任务和目标添加开始时间、结束时间和持续时间。
示例
创建包含以下内容的 build.xml 文件
<?xml version="1.0"?> <project name="sample" basedir="." default="copy"> <target name="copy"> <echo>File Copied</echo> </target> </project>
输出
在上述构建文件上运行 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 文件。