Ant实战

 

第1章 Ant的安装和配置

本章实际开始实际接触Ant。本章首先将介绍如何在主流的操作系统下安装Ant,并详细解释Ant的安装文件;其次还会介绍如何在主流的IDE中集成Ant,以及Ant安装的最佳实践。 

1.1 检查JDK安装

在安装Ant之前,首先要确认你已经正确安装了JDK。Ant可以运行在JDK 1.4及以上的版本上。本书的所有样例都基于JDK 5及以上版本。打开Windows的命令行,运行如下的命令来检查你的Java安装:

C:\>echo %JAVA_HOME%

C:\ >java -version

结果如图1-1所示:

C:\>echo %JAVA_HOME%
D:\Program Files\Java\jdk1.6.0_20

C:\>java -version
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Client VM (build 16.3-b01, mixed mode, sharing)

图1-1 Windows中检查Java安装



1.2 下载Ant

请访问Ant的下载页面:http://ant.apache.org/bindownload.cgi,其中包含针对不同平台的各种版本的Ant下载文件。

在本博文编写的时候,Ant 1.8的最新版本是1.8.2。

 

1.3 本地安装

将安装文件解压到你指定的目录中,这里的Ant安装目录是D:\Program Files\apache-ant-1.8.2,接着需要设置环境变量,将Ant安装配置到操作系统环境中。

打开系统属性面板(桌面上右键单击“我的电脑”→“属性”),点击高级系统设置,再点击环境变量,在系统变量中新建一个变量,变量名为ANT_HOME,变量值为Ant的安装目录D:\Program Files\apache-ant-1.8.2。点击确定,接着在系统变量中找到一个名为Path的变量,在变量值的末尾加上%ANT_HOME%\bin;,注意多个值之间需要有分号隔开,然后点击确定。至此,环境变量设置完成。

这里需要提一下的是Path环境变量,当我们在cmd中输入命令时,Windows首先会在当前目录中寻找可执行文件或脚本,如果没有找到,Windows会接着遍历环境变量Path中定义的路径。由于我们将%M2_HOME%\bin添加到了Path中,而这里%ANT_HOME%实际上是引用了我们前面定义的另一个变量,其值是Ant的安装目录。因此,Windows会在执行命令时搜索目录D:\Program Files\apache-ant-1.8.2\bin,而ant执行脚本的位置就是这里。

明白了环境变量的作用,现在打开一个新的cmd窗口(这里强调新的窗口是因为新的环境变量配置需要新的cmd窗口才能生效),运行如下命令检查Maven的安装情况:

C:\>echo %ANT_HOME%

C:\>ant -v

运行结果如图1-3所示:

C:\>echo %ANT_HOME%
D:\Program Files\apache-ant-1.8.2

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


 图1-3 Windows中检查Ant安装

第一条命令echo %ANT_HOME%用来检查环境变量ANT_HOME是否指向了正确的ANT安装目录;而ant –version执行了第一条Ant命令,以检查Windows是否能够找到正确的ant执行脚本。

 

1.4 升级Ant

Ant还比较年轻,更新比较频繁,因此用户往往会需要更新Ant安装以获得更多更酷的新特性,以及避免一些旧的bug。

在Windows上更新Ant非常简便,只需要下载新的Ant安装文件,解压至本地目录,然后更新ANT_HOME环境变量便可。例如,假设ANT推出了新版本1.8.3,我们将其下载然后解压至目录D:\Program Files\apache-ant-1.8.3,接着遵照前一节描述的步骤编辑环境变量ANT_HOME,更改其值为D:\Program Files\apache-ant-1.8.2。至此,更新就完成了。同理,如果你需要使用某一个旧版本的Ant,也只需要编辑ANT_HOME环境变量指向旧版本的安装目录。

 

 

第2章 Ant使用入门 

到目前为止,我们已经大概了解并安装好了Ant,现在,我们开始创建一个最简单的Hello World项目。如果你是初次接触Ant,我建议你按照本章的内容一步步地编写代码并执行,可能你会碰到一些概念暂时难以理解,不用着急,记下这些疑难点,相信后续章节会帮你逐一解答。

2.1 编写build

Ant项目的核心是build.xml。build定义了项目的基本信息,用于描述项目如何构建,声明项目依赖,等等。现在我们先为Hello World项目编写一个最简单的build.xml。

首先创建一个名为ant-jar的文件夹,打开该文件夹,新建一个名为build.xml的文件,输入其内容如代码清单3-1:

代码清单2-1:Hello World的build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="ant-jar" basedir="." default="main">

	<property name="resources.dir" value="src/main/resources" />
	<property name="src.dir" value="src/main/java" />
	<property name="test.dir" value="src/test/java" />
	<property name="build.dir" value="build" />
	<property name="classes.dir" value="${build.dir}/classes" />
	<property name="test-classes.dir" value="${build.dir}/test-classes" />
	<property name="jar.dir" value="${build.dir}/jar" />
	<property name="report.dir" value="${build.dir}/report" />
	<property name="correctreport.dir" value="${report.dir}/html" />
	<property name="main-class" value="net.csdn.common.Luncher" />
	<property name="lib.dir" value="lib" />

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

	<target name="clean">
		<delete dir="${build.dir}" />
	</target>

	<target name="compile" depends="clean">
		<mkdir dir="${classes.dir}" />
		<mkdir dir="${test-classes.dir}" />
		<javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath" includeantruntime="true" />
		<javac srcdir="${src.dir}" destdir="${test-classes.dir}" classpathref="classpath" includeantruntime="true" />
		<javac srcdir="${test.dir}" destdir="${test-classes.dir}" classpathref="classpath" includeantruntime="true" />
		<copy todir="${classes.dir}">
			<fileset dir="${resources.dir}" />
		</copy>
		<copy todir="${test-classes.dir}">
			<fileset dir="${resources.dir}" />
		</copy>
	</target>

	<target name="test" depends="compile">
		<mkdir dir="${report.dir}" />
		<mkdir dir="${correctreport.dir}" />
		<junit printsummary="yes">
			<classpath>
				<path refid="classpath" />				
				<pathelement path="${test-classes.dir}" />
			</classpath>
			<formatter type="xml" />
			<batchtest fork="yes" todir="${report.dir}">
				<fileset dir="${test.dir}">
					<include name="**/*Test.java" />
				</fileset>
			</batchtest>
		</junit>
		<junitreport todir="${report.dir}">
			<fileset dir="${report.dir}">
				<include name="TEST-*.xml" />
			</fileset>
			<report format="frames" todir="${correctreport.dir}" />
		</junitreport>
	</target>

	<target name="jar" depends="compile">
		<mkdir dir="${jar.dir}" />
		<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
			<manifest>
				<attribute name="Main-Class" value="${main-class}" />
			</manifest>
            <zipfileset src= "${lib.dir}/log4j-1.2.15.jar" />
		</jar>
	</target>

	<target name="run" depends="jar">
		<java fork="true" classname="${main-class}">
			<classpath>
				<path refid="classpath" />
				<path id="application" location="${jar.dir}/${ant.project.name}.jar" />
			</classpath>
		</java>
	</target>

	<target name="main" depends="test,run">
		<echo message="Ant Build Successful" />
	</target>

</project>

图 2-1

    

2.2  编写主代码 

项目主代码和测试代码不同,项目的主代码会被打包到最终的构件中(比如jar),而测试代码只在运行测试时用到,不会被打包。假设Ant项目主代码位于src/main/java目录,创建该目录,然后在该目录下创建文件net/csdn/common/Luncher.java,其内容如代码清单2-2:

代码清单2-2:Hello World的主代码

package net.csdn.common;

import org.apache.log4j.Logger;

public class Luncher {

	private static Logger logger = Logger.getLogger(Luncher.class);

	public Luncher() {
		if (logger.isInfoEnabled())
			logger.info("net.csdn.common.Luncher#Luncher");
	}

	public static void main(String[] args) {
		if (logger.isInfoEnabled())
			logger.info("net.csdn.common.Luncher#main");
		System.out.println(call());
	}

	public static String call() {
		if (logger.isInfoEnabled())
			logger.info("net.csdn.common.Luncher#call");
		return "Hello Ant";
	}

}

图 2-2

 

 

       这是一个简单的Java类,它有一个call()方法,返回一个String。同时这个类还带有一个main方法,创调用call()方法,并将结果输出到控制台。

代码编写完毕后,我们使用Ant进行编译,在项目根目录下运行命令 ant compile,我们会得到如下输出:

D:\ant-jar>ant compile
Buildfile: D:\ant-jar\build.xml

clean:
   [delete] Deleting directory D:\ant-jar\build

compile:
    [mkdir] Created dir: D:\ant-jar\build\classes
    [mkdir] Created dir: D:\ant-jar\build\test-classes
    [javac] Compiling 1 source file to D:\ant-jar\build\classes
    [javac] Compiling 1 source file to D:\ant-jar\build\test-classes
    [javac] Compiling 1 source file to D:\ant-jar\build\test-classes
     [copy] Copying 1 file to D:\ant-jar\build\classes
     [copy] Copying 1 file to D:\ant-jar\build\test-classes

BUILD SUCCESSFUL
Total time: 1 second

 

clean告诉Ant清理输出目录build/,compile告诉Ant编译项目主代码,从输出中我们看到Ant首先执行了clean任务,删除build/目录,Ant构建的所有输出都在 build/目录中;接着执行compile任务,将项目主代码编译至build/classes目录(编译好的类为net/csdn/common/Luncher.Class)。

至此,Ant在没有任何额外的配置的情况下就执行了项目的清理和编译任务,接下来,我们编写一些单元测试代码并让Ant执行自动化测试。

 

2.3 编写测试代码 

为了使项目结构保持清晰,主代码与测试代码应该分别位于独立的目录中。Ant项目中测试代码目录是src/test/java。因此,在编写测试用例之前,我们先创建该目录。

在Java世界中,由Kent Beck和Erich Gamma建立的JUnit是事实上的单元测试标准。要使用JUnit,我们首先需要为Hello World项目添加一个JUnit依赖。

代码清单2-3:为Hello World的测试代码如下

......
	<target name="test" depends="compile">
		<mkdir dir="${report.dir}" />
		<mkdir dir="${correctreport.dir}" />
		<junit printsummary="yes">
			<classpath>
				<path refid="classpath" />				
				<pathelement path="${test-classes.dir}" />
			</classpath>
			<formatter type="xml" />
			<batchtest fork="yes" todir="${report.dir}">
				<fileset dir="${test.dir}">
					<include name="**/*Test.java" />
				</fileset>
			</batchtest>
		</junit>
		<junitreport todir="${report.dir}">
			<fileset dir="${report.dir}">
				<include name="TEST-*.xml" />
			</fileset>
			<report format="frames" todir="${correctreport.dir}" />
		</junitreport>
	</target>
......

图 2-3

 

配置了测试依赖,接着就可以编写测试类,回顾一下前面的Luncher类,现在我们要测试该类的call()方法,检查其返回值是否为“Hello Ant”。在src/test/java目录下创建文件,其内容如代码清单3-4,Hello World的测试代码

package net.csdn.common;

import junit.framework.Assert;

import org.apache.log4j.Logger;
import org.junit.Test;

public class LuncherTest {

	private static Logger logger = Logger.getLogger(LuncherTest.class);

	@Test
	public void testCall() {
		if (logger.isInfoEnabled())
			logger.info("net.csdn.common.LuncherTest#testCall");
		Assert.assertEquals("Hello Ant", Luncher.call());
	}

}

图 3-4

 

Java代码

一个典型的单元测试包含三个步骤:一,准备测试类及数据;二,执行要测试的行为;三,检查结果。上述样例中,我们首先初始化了一个要测试的HelloWorld实例,接着执行该实例的call()方法并保存结果到result变量中,最后使用JUnit框架的Assert类检查结果是否为我们期望的”Hello Ant”。在JUnit 3中,约定所有需要执行测试的方法都以test开头,这里我们使用了JUnit 4,但我们仍然遵循这一约定,在JUnit 4中,需要执行的测试方法都应该以@Test进行标注。

测试用例编写完毕之后就可以调用Ant执行测试,运行 ant test

D:\ant-jar>ant test
Buildfile: D:\ant-jar\build.xml

clean:
   [delete] Deleting directory D:\ant-jar\build

compile:
    [mkdir] Created dir: D:\ant-jar\build\classes
    [mkdir] Created dir: D:\ant-jar\build\test-classes
    [javac] Compiling 1 source file to D:\ant-jar\build\classes
    [javac] Compiling 1 source file to D:\ant-jar\build\test-classes
    [javac] Compiling 1 source file to D:\ant-jar\build\test-classes
     [copy] Copying 1 file to D:\ant-jar\build\classes
     [copy] Copying 1 file to D:\ant-jar\build\test-classes

test:
    [mkdir] Created dir: D:\ant-jar\build\report
    [mkdir] Created dir: D:\ant-jar\build\report\html
    [junit] Running net.csdn.common.LuncherTest
    [junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.078 sec
[junitreport] Processing D:\ant-jar\build\report\TESTS-TestSuites.xml to C:\DOCU
ME~1\ADMINI~1\LOCALS~1\Temp\null1722353399
[junitreport] Loading stylesheet jar:file:/D:/Program%20Files/apache-ant-1.8.2/l
ib/ant-junit.jar!/org/apache/tools/ant/taskdefs/optional/junit/xsl/junit-frames.
xsl
[junitreport] Transform time: 422ms
[junitreport] Deleting: C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\null1722353399

BUILD SUCCESSFUL
Total time: 2 seconds

 

我们看到test任务执行成功了,测试代码通过编译之后在build/test-classes下生成了二进制文件,紧接着test任务运行测试,这里它运行测试用例LuncherTest,并且输出测试报告,显示一共运行了多少测试,失败了多少,出错了多少,跳过了多少。显然,我们的测试通过了——BUILD SUCCESSFUL。

 

2.4  打包和运行 

将项目进行编译、测试之后,下一个重要步骤就是打包(package)。Hello World的Ant指定打包类型为jar,我们可以简单地执行命令 ant jar 进行打包,可以看到如下输出:

D:\ant-jar>ant jar
Buildfile: D:\ant-jar\build.xml

clean:
   [delete] Deleting directory D:\ant-jar\build

compile:
    [mkdir] Created dir: D:\ant-jar\build\classes
    [mkdir] Created dir: D:\ant-jar\build\test-classes
    [javac] Compiling 1 source file to D:\ant-jar\build\classes
    [javac] Compiling 1 source file to D:\ant-jar\build\test-classes
    [javac] Compiling 1 source file to D:\ant-jar\build\test-classes
     [copy] Copying 1 file to D:\ant-jar\build\classes
     [copy] Copying 1 file to D:\ant-jar\build\test-classes

jar:
    [mkdir] Created dir: D:\ant-jar\build\jar
      [jar] Building jar: D:\ant-jar\build\jar\ant-jar.jar

BUILD SUCCESSFUL
Total time: 1 second

 

类似地,Ant会在打包之前执行编译、测试等操作。这里我们看到ant jar任务负责打包,实际上就是jar插件的jar目标将项目主代码打包成一个名为ant-jar.jar的文件,该文件也位于build/输出目录中。

至此,我们得到了项目的输出,如果有需要的话,就可以复制这个jar文件到其他项目的Classpath中从而使用HelloWorld类。

到目前为止,我们还没有运行Hello World项目,不要忘了HelloWorld类可是有一个main方法的。默认打包生成的jar是不能够直接运行的,因为带有main方法的类信息不会添加到manifest中(我们可以打开jar文件中的META-INF/MANIFEST.MF文件,将无法看到Main-Class一行)。为了生成可执行的jar文件,我们需要配置如下:

......
	<target name="jar" depends="compile">
		<mkdir dir="${jar.dir}" />
		<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
			<manifest>
				<attribute name="Main-Class" value="${main-class}" />
			</manifest>
            <zipfileset src= "${lib.dir}/log4j-1.2.16.jar" />
		</jar>
	</target>
......

 

我们可以看到ant-jar.jar,打开ant-jar.jarMETA-INF/MANIFEST.MF,可以看到它包含这样一行信息:

Main-Class: net.csdn.common.Luncher

现在,我们在项目根目录中执行该jar文件:

D: \ant-jar\build\jar\java -jar ant-jar.jar

Hello Ant

控制台输出为Hello Ant,这正是我们所期望的。

本小节介绍了Hello World项目,侧重点是Ant而非Java代码本身,介绍了build、Ant项目结构、以及如何编译、测试、打包,等等。
 
附录:主要目录结构
D:\ant-jar\
│  build.xml
│
├─lib
│      log4j-1.2.16.jar
│
└─src
    ├─test
    │  ├─java
    │  │  └─net
    │  │      └─csdn
    │  │          └─common
    │  │                  LuncherTest.java
    │  │
    │  └─resources
    │          log4j.properties
    │
    └─main
        ├─resources
        │      log4j.properties
        │
        └─java
            └─net
                └─csdn
                    └─common
                            Luncher.java

 
 
注:运行junit测试,须要在 ../apache-ant-1.8.2/lib 目录下加入 junit.jar 包,否则出错。
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值