目录

Ant - 快速指南

ANT代表Another Neat Tool。 它是Apache的基于Java的构建工具。 在深入了解Apache Ant的细节之前,让我们先了解为什么我们首先需要构建工具。

需要构建工具

平均而言,开发人员花费大量时间执行构建和部署等普通任务,其中包括:

  • 编译代码
  • 打包二进制文件
  • 将二进制文件部署到测试服务器
  • 测试更改
  • 将代码从一个位置复制到另一个位置

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

Apache Ant的历史

  • Ant由James Duncan Davidson(Tomcat的原作者)创建。

  • 它最初用于构建Tomcat,并作为Tomcat发行版的一部分捆绑在一起。

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

  • Ant于2000年被提升为Apache的独立项目。截至2014年5月,Apache Ant的最新版本为1.9.4。

Apache Ant的功能

  • Ant是最完整的Java构建和部署工具。

  • Ant是平台中立的,可以处理特定于平台的属性,例如文件分隔符。

  • Ant可用于执行特定于平台的任务,例如使用“touch”命令修改文件的修改时间。

  • Ant脚本使用纯XML编写。 如果您已经熟悉XML,则可以快速学习Ant。

  • Ant善于自动执行复杂的重复性任务。

  • Ant附带了大量预定义任务。

  • Ant提供了一个开发自定义任务的界面。

  • 可以从命令行轻松调用Ant,它可以与免费和商业IDE集成。

Ant - Environment Setup

Apache Ant Ant是在Apache软件许可下发布的,这是一个由开源计划认证的完全开源的许可证。

最新的Apache Ant版本,包括其完整源代码,类文件和文档,可以在http://ant.apache.org.找到http://ant.apache.org.

安装Apache Ant

假设您已经在计算机上下载并安装了Java Development Kit(JDK)。 如果没有,请按照here的说明操作。

  • 确保将JAVA_HOME环境变量设置为安装JDK的文件夹。

  • http://ant.apache.org下载二进制文件

  • 将zip文件解压缩到方便的位置c:\文件夹。 使用Winzip,winRAR,7-zip或类似工具。

  • 创建一个名为ANT_HOME的新环境变量,该变量指向Ant安装文件夹,在本例中为c:\apache-ant-1.8.2-bin文件夹。

  • 将Apache Ant批处理文件的路径附加到PATH环境变量。 在我们的例子中,这将是c:\apache-ant-1.8.2-bin\bin文件夹。

验证Apache Ant安装

要验证在计算机上成功安装Apache Ant,请在命令提示符下键入ant。

您应该看到类似于的输出:

C:\>ant -version
Apache Ant(TM) version 1.8.2 compiled on December 20 2010

如果您没有看到上述输出,请确认您已正确执行安装步骤。

安装Eclipse

本教程还介绍了Ant与Eclipse IDE的集成。 因此,如果您尚未安装Eclipse,请下载并安装Eclipse

要安装Eclipse:

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

  • 将Eclipse二进制文件解压缩到一个方便的位置,例如c:\folder

  • 从c:\eclipse\eclipse.exe运行Eclipse

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. 所有构建文件都需要project元素和至少一个target元素。

XML元素project有三个属性:

属性 描述
name 项目名称。 (可选的)
default 构建脚本的默认目标。 项目可能包含任意数量的目标。 此属性指定应将哪个目标视为默认目标。 (必须)
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元素具有以下属性:

属性 描述
name 目标名称(必填)
depends 以逗号分隔的目标所依赖的所有目标的列表。 (可选的)
description 目标的简短描述。 (可选的)
if 允许基于条件属性的真实性执行目标。 (可选的)
unless 将目标添加到指定Extension Point的依赖项列表中。 扩展点类似于目标,但它没有任何任务。 (可选的)

上例中的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 - Property Task

Ant构建文件是用XML编写的,它不允许像你喜欢的编程语言那样声明变量。 但是,正如您可能想象的那样,如果Ant允许声明项目名称,项目源目录等变量,那将非常有用。

Ant使用property元素,允许您指定属性。 这允许将属性从一个构建更改为另一个或从一个环境更改为另一个。

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

属性 描述
ant.file 构建文件的完整位置。
ant.version Apache Ant安装的版本。
basedir 构建的基础,在project元素的basedir属性中指定。
ant.java.version Ant使用的JDK版本。
ant.project.name 项目name ,在project元素的name atrribute中指定。
ant.project.default-target 当前项目的默认目标。
ant.project.invoked-targets 以逗号分隔的当前项目中调用的目标列表。
ant.core.lib Ant jar文件的完整位置。
ant.home Ant安装的主目录。
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.iowiki.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.8.2  
      compiled on December 20 2010 - You are at www.iowiki.com
BUILD SUCCESSFUL
Total time: 0 seconds
C:\>

Ant - Property Files

如果您正在使用一些属性,则直接在构建文件中设置属性是可以的。 但是,对于大型项目,将属性存储在单独的属性文件中是有意义的。

将属性存储在单独的文件中具有以下优点:

  • 它允许您重用相同的构建文件,并为不同的执行环境使用不同的属性设置。 例如,可以为DEV,TEST和PROD环境单独维护构建属性文件。

  • 当您事先不知道属性(在特定环境中)的值时,它很有用。 这允许您在已知属性值的其他环境中执行构建。

没有硬性规则,但通常属性文件名为build.properties并且与build.xml文件并排放置。 您可以基于部署环境创建多个构建属性文件 - 例如build.properties.devbuild.properties.test.

build属性文件的内容类似于普通的java属性文件。 它们每行包含一个属性。 每个属性由名称和值对表示。 名称和值对由等号(=)分隔。 强烈建议使用适当的注释对属性进行注释。 使用散列(#)字符列出注释。

以下示例显示了build.xml文件及其关联的build.properties文件:

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

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

在上面的示例中, sitename是一个自定义属性,映射到网站名称。 您可以以这种方式声明任意数量的自定义属性。 上面示例中列出的另一个自定义属性是buildversion ,在本例中,它指的是构建版本。

除了上述内容之外,Ant还提供了许多预定义的构建属性,这些属性在上一节中列出,但在下面再次表示。

属性 描述
ant.file 构建文件的完整位置。
ant.version Apache Ant安装的版本。
basedir 构建的基础,在project元素的basedir属性中指定。
ant.java.version Ant使用的JDK版本。
ant.project.name 项目name ,在project元素的name atrribute中指定。
ant.project.default-target 当前项目的默认目标。
ant.project.invoked-targets 以逗号分隔的当前项目中调用的目标列表。
ant.core.lib Ant jar文件的完整位置。
ant.home Ant安装的主目录。
ant.library.dir Ant库文件的主目录 - 通常是ANT_HOME/lib文件夹。

本章介绍的示例使用ant.version内置属性。

Ant - Data Types

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

Apache Ant提供以下数据类型。

Fileset

文件集数据类型表示文件的集合。 它用作过滤器以包含或排除与特定模式匹配的文件。

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

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

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

模式集

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

  • ? - 仅匹配一个角色。

  • * - 匹配零个或多个字符。

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

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

<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>

文件列表

文件列表数据类型与文件集类似,但以下区别除外:

  • 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 todir="${output.dir}">
   <fileset dir="${releasenotes.dir}" includes="**/*.txt"/>
   <filterset>
      <filter token="VERSION" value="${current.version}"/>
   </filterset>
</copy>

在本守则中:

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

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

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

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

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文件夹中。

  • 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目标。

清楚的目标,顾名思义,删除build文件夹中的文件。

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

master-classpath保存类路径信息。 在这种情况下,它包括build文件夹中的类和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任务提供源文件夹和类路径,并要求它将类文件放在build文件夹中。

<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源文件并将类放在build文件夹中。

以下结果是运行Ant文件的结果:

C:\>ant
Buildfile: C:\build.xml
BUILD SUCCESSFUL
Total time: 6.3 seconds

这些文件被编译并放在build.dir文件夹中。

Ant - Build Documentation

文档是任何项目的必需品。 文档在维护项目中起着重要作用。 Java通过使用内置的javadoc工具使文档更容易。 通过按需生成文档,Ant使其变得更加容易。

如您所知,javadoc工具非常灵活,允许许多配置选项。 Ant通过javadoc任务公开这些配置选项。 如果您不熟悉javadoc,我们建议您从本Java Documentation Tutorial开始

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

属性 (Attributes)

可以使用sourcepathsourcepathrefsourcefiles指定Source。

  • sourcepath用于指向源文件的文件夹(例如src文件夹)。

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

  • 如果要将各个文件指定为逗号分隔列表,则使用sourcefiles

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

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

您可以过滤javadoc进程以仅显示公共,私有,包或受保护的类和成员。 这是通过使用privatepublicpackageprotected属性实现的。

您还可以使用相应的属性告诉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 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归档文件,即JAR文件。 使用jar任务,使用Ant创建JAR文件非常简单。 jar任务的常用属性如下:

属性 描述
basedir 输出JAR文件的基目录。 默认情况下,它设置为项目的基本目录。
compress 建议Ant在创建JAR文件时压缩文件。
keepcompression 虽然compress属性适用于单个文件,但keepcompression属性执行相同的操作,但它适用于整个存档。
destfile 输出JAR文件的名称。
duplicate 建议Ant在找到重复文件时该怎么做。 您可以添加,保留或失败重复文件。
excludes 建议Ant不要在包中包含这些以逗号分隔的文件列表。
excludesfile 与上面相同,除了使用模式指定排除文件。
inlcudesInverse of excludes.
includesfile 反向排除文件。
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应用程序li​​b文件夹中。

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

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

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

要执行jar任务,请将其包装在目标(最常见的是构建或包目标)中,然后执行它们。

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

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

以下结果是运行Ant文件的结果:

C:\>ant build-jar
Buildfile: C:\build.xml
BUILD SUCCESSFUL
Total time: 1.3 seconds

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

Ant - Creating WAR files

使用Ant创建WAR文件非常简单,与创建JAR文件任务非常相似。 毕竟,WAR文件,就像JAR文件只是另一个ZIP文件。

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

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

属性 描述
webxml web.xml文件的路径
lib 用于指定进入WEB-INF\lib文件夹的内容的分组。
classes 用于指定进入WEB-INF\classes文件夹的内容的分组。
metainf 指定生成MANIFEST.MF文件的说明。

继续我们的Hello World传真应用程序项目,让我们添加一个新目标来生成jar文件。 但在此之前让我们考虑战争任务。 请考虑以下示例:

<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目标(通常是包)中并运行它。 这将在指定位置创建WAR文件。

完全可以嵌套类,lib,metainf和webinf控制器,以便它们位于项目结构中任何位置的分散文件夹中。 但最佳实践表明,您的Web项目应具有与WAR文件结构类似的Web Content结构。 传真应用程序项目的结构使用此基本原则概述。

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

<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             <i>This folder contains the jsp files</i>
   +---css             <i>This folder contains the stylesheet files</i>
   +---js              <i>This folder contains the javascript files</i>
   +---images          <i>This folder contains the image files</i>
   +---META-INF        <i>This folder contains the Manifest.Mf</i>
   +---WEB-INF
      +---classes   <i>This folder contains the compiled classes</i>
      +---lib       <i>Third party libraries and the utility jar files</i>
      WEB.xml       <i>Configuration file that defines the WAR package</i>

Ant - Packaging Applications

我们已经使用Hello World传真Web应用程序逐点了解Ant的不同方面。

现在是时候把所有东西放在一起来创建一个完整而完整的build.xml文件。 考虑build.propertiesbuild.xml文件,如下所示:

build.properties

deploy.path=c:\tomcat6\webapps

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文件。

  • 我们还在master类路径中包含build.dir中存在的类文件。

  • Javadoc目标生成项目所需的javadoc,使用目标用于打印构建文件中存在的公共目标。

上面的示例显示了两个部署目标: deploydeploywar.

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

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

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

Ant - Deploying Applications

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

在本章中,我们将把Web应用程序直接部署到应用程序服务器部署文件夹,然后我们将添加一些Ant目标来启动和停止服务。 让我们继续使用Hello World传真Web应用程序。 这是前一章的延续,新组件以粗体突出显示。

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=http://www.iowiki.com:8080/manager
tomcat.manager.username=iowiki
tomcat.manager.password=secret

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中的webapp文件夹。

可以使用Tomcat管理器应用程序停止和启动Tomcat中的应用程序。 管理器应用程序的URL,用户名和密码也在build.properties文件中指定。 接下来,我们声明一个包含catalina-ant.jar的新CLASSPATH。 需要此jar文件才能通过Apache Ant执行Tomcat任务。

catalina-ant.jar提供以下任务:

属性 描述
InstallTask 安装Web应用程序。 类名:org.apache.catalina.ant.InstallTask
ReloadTask 重新加载Web应用程序。 类名:org.apache.catalina.ant.ReloadTask
ListTask 列出所有Web应用程序。 类名:org.apache.catalina.ant.ListTask
StartTask 启动Web应用程序。 类名:org.apache.catalina.ant.StartTask
StopTask 停止Web应用程序。 类名:org.apache.catalina.ant.StopTask
ReloadTask 无需停止即可重新加载Web应用程序。 类名:org.apache.catalina.ant.ReloadTask

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

  • 管理器应用程序的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应用程序并重新加载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视图Window 》 Show View 》 Other 》 Ant 》 Ant.

  • 打开Project Explorer,将build.xml拖到Ant视图中。

您的Ant视图类似于:

Eclipse Ant集成

单击目标,build/clean/usage将使用目标运行Ant。

单击“传真”将执行默认目标 - usage.

Ant Eclipse插件还附带了一个用于编辑build.xml文件的良好编辑器。 编辑器知道build.xml模式,可以帮助您完成代码。

要使用Ant编辑器,请右键单击build.xml(从Project Explorer),然后选择Open with> Ant Editor。 Ant编辑器看起来应该类似于:

Eclipse Ant集成

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

Ant - JUnit Integration

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

本章介绍如何使用Ant执行JUnit测试。 Ant通过JUnit任务直接进行。

JUnit任务的属性如下所示:

属性 描述
dir 从哪里调用VM。 禁用fork时会忽略此项。
jvm 用于调用JVM的命令。 禁用fork时会忽略此项。
fork 在单独的JVM中运行测试
errorproperty 如果存在JUnit错误,则设置的属性的名称
failureproperty 如果存在JUnit失败,则设置的属性的名称
haltonerror 发生测试错误时停止执行
haltonfailure 发生故障时停止执行
printsummary 建议Ant为每个测试显示简单的统计信息
showoutput 建议Ant将输出发送到其日志和格式化程序
tempdir Ant将使用的临时文件的路径
timeout 退出运行时间比此设置长的测试(以毫秒为单位)。

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

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

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

此示例显示了com.iowiki.UtilsTest junit类上JUnit的执行情况。 运行上面的代码会产生以下输出:

test:
[echo] Testing the application
[junit] Running com.iowiki.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.iowiki.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.iowiki.ant.MyTask" />
   <custom message="Hello World!"/>
</target>

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

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

这只是一个简单的示例,您可以使用Ant的强大功能来执行您想要的任何操作来改进构建和部署过程。

↑回到顶部↑
WIKI教程 @2018