- 浏览: 90406 次
- 性别:
- 来自: 烟台
最新评论
-
daxiaoli123:
1 http://sourceforge.net/projec ...
GCJ让Java程序脱离jre执行 -
zhangtongysu:
楼主 ,那个下载 怎么回事啊。
利用Ant和Eclipse有效地提高部署工作效率
本文主要介绍 Ant 在多用户开发的情况下,如何用 Eclipse,并且根据不同的目标环境编译不同的部署包。文中首先介绍一个场景,给出在开发、编译、部署过程中遇到的问题;然后介绍如何用 Eclipse 来简化你的 Ant 开发过程;文章的最后解释如何通过编写有效的 Ant 脚本来提高你的工作效率。
读者定位为具有 Java 和 Ant 使用经验的开发人员。
读者可以学习到如何使用 Ant 解决一些多用户开发环境中,根据不同的目标环境编译成不同部署包的问题。
工作场景
现在有一个 web 项目,是多人进行开发的,通过 CVS 来管理。另外该项目还有一些测试人员,他们测试部署在测试服务器上的应用程序,发现 bug 后通过 bug 管理系统通知开发人员,在开发人员修复 bug 并经过本地测试后,由专门的人负责检出(check out)代码,编译打包后部署到测试服务器上。
该项目的成员小A就是负责检出代码、编译打包,并部署到服务器上的人。除了这个任务之外,他还是该项目的编程人员。在项目进入测试阶段后,小A在得到组中别的成员修复了 bug 并且检入(check in)了代码的消息后(也有可能是小A自己检入了代码),小A首先更新本地的代码,先在本地做测试,确认修复了 bug 后打成 WAR 包部署到测试服务器上,并通知测试人员已经修复了 bug,让测试人员继续进行测试。
小A的烦恼
在该项目中,有一些为测试方便开发而写的代码和页面,比如跳过用户认证,但是在部署到测试机环境的时候,需要删除这些代码和页面;另外作为一个具有灵活性和扩展性的应用程序,又有一些配置文件,配置文件中的值会根据环境的改变而变动。例如,在项目中使用了 Log4j 记录日志,需要给 Log4j 指定日志文件的保存路径,本地程序员开发的时候用的是 Windows 系统,给 Log4j 指定的也是 Windows 的文件系统,在测试阶段的时候,需要部署到 Linux 系统中,那么日志的保存路径也需要做相应的改动。部署到测试服务器上的时候,除了 Log4j 需要改之外,还有很多别的配置项目也需要变动,并且分散在各个 package 中。小A的烦恼也随之而来,每次他在做完本地测之后,就根据测试机的需要逐个找配置文件,更改相应的值,并删除那些为测试方便写的代码和页面,每天可能根据需要做好几次这样的事情,最烦的是他在快做完对测试机环境更改的时候,某开发人员突然通知小A说:“我又改了一点代码,刚检入,你再重打一个包吧。”,小A又不得不从头开始做新一轮的检出代码、本地测试、更改配置文件、删除不需要的文件、打包部署的工作。另外小A在测试阶段的后期被通知要求除了每次生成一个测试环境的 WAR 包外还必须生成一个在产品环境下的 WAR 包,他做的事情就更多了。
从上面的场景可以看出,小A的工作效率低而且容易出错,甚至有可能导致整个项目的工作效率低下。其实可以通过 Ant 来帮助小A快速而且有效地完成这个工作。在 Ant 中,根据目标环境的需要,可以把所有要更改的配置文件的项目集中写到某个配置文件中。这样根据不同的目标环境得到不同的配置文件,Ant 在编译包时根据不同的目标环境切换不同的配置文件即可。比如小A现在碰到的有 3 中环境:开发环境、测试环境以及产品环境,根据这三种环境可以生成三个不同的配置文件:develop_deploy.property、test_deploy. property和product_deploy. property,当小A想生成不同的包时只需在这三个配置文件之间切换就可以了。
在正式开始编写脚本之前,我们需要下载安装相应的软件。
Eclipse:为了使 Ant 的开发更加简单,我们选择了 Eclipse3.1 作为开发环境。当然你可以使用任何你喜欢的文本编辑工具来开发你的 Ant。Eclipse 的最新版本可以在 http://eclipse.org/ 上下载。
Ant:Ant 是基于 Java 的编译工具,它就像 C/C++ 中的 make,但是没有 make 那样难用。Ant 的最新版本可以在 http://ant.apache.org/bindownload.cgi 上下载。如果你用 Eclipse 来开发 Ant,则不用去单独下载 Ant,因为在 Eclipse 中已经集成了 Ant。
CVS 客户端(cvs.exe):CVS 可以在 http://www.nongnu.org/cvs/ 上下载
用 Eclipse3.1 来创建 Ant 脚本
如果你使用 Eclipse 来编写 Ant,建议使用 Eclipse 3.1 以后的版本。除了以前 Ant 编辑器提供的语法高亮,提示语法错误等功能外,Eclipse3.1 版本增加了许多新的功能。比如:脚本代码的折叠;快速定位某属性或者目标(target)段的定义;在同一 builder 文件中重构属性名和目标名(快捷方式Alt + Shift +R);调试 Ant 脚本等。
下面我们就来看看 Eclipse 3.1 中对 Ant 的支持
打开“File”-“New”-“Project”-“Simple”-“Project”,点击“Next”,输入工程名“Ant”,然后点击直到“Finish”
在新建的 Ant 工程中,新建 Test.xml,并且拷贝下面的脚本。该段脚本的内容就不做介绍了,我们主要看 Eclipse 提供了哪些功能。注意这时候打开的并不是 Ant 编辑器,将内容拷贝进去之后,关掉打开的“Test.xml”,然后再重新打开它,这样 Eclipse 就会用 Ant 编辑器打开它,并且也语法高亮了。
<?xml version="1.0" encoding="UTF-8"?>
<project name="Test" default="init" basedir=".">
<property name="test" value="test"/>
<target name="init">
<echo>${test}</echo>
</target>
</project>
自动提示和代码折叠功能。如果是 Ant 内置的命令或者前面已经定义的变量,编辑器会自动提示;编辑器右边的加/减号可以代码折叠。如下所示:
快速定位目标(target)或者定义变量处。在上图中,将鼠标移至 default=”init” 中的 init 上之后,按下 ctrl 键,鼠标变成手状,单击就可以定位到定义该目标的地方
快速重构目标名或者属性名。选中目标/属性名,按下 Alt + Shift + R,然后键入你要修改后的值,所有引用到的地方都会随之改动。如下图所示,选中 init 后,按下快捷键,改成 initial:
调试 Ant 脚本。在标签“<target name=..”的左边设置一断点,然后在编辑器中右击,出现的菜单中选“Debug As”-“Ant Build”,出现后的窗口与调试 Java 程序的界面差不多。
这是调试窗口,这里可以选择单步跟进、跳出等:
下面是运行时变量窗口。可以看到 test 变量的值是“test”:
运行结果窗口:
由此可见,如果使用好 Eclipse Ant 编辑器所提供强大的功能的话能大大提高写 Ant 脚本的效率。
Ant 中使用 property(属性)文件
刚开始写 Ant 的初学者可能会把所有的信息都放在 build.xml 中,下面就是这样的一个例子。
<project name="testBuild" default="compile" basedir=".">
<target name="init">
<mkdir dir="c:/temp/dest/testProj" />
</target>
<target name="compile" depends="init">
<javac srcdir="c:/temp/src/testProj" destdir="c:/temp/dest/testProj "/>
<echo>Build into c:/temp/dest/testProj, successfully.</echo>
</target>
</project>
在上面的例子中,所有的路径信息都是写在 build.xml 中。但是 Ant 脚本可能在不同的机器或者不同的系统上运行,也有可能一些值需要根据环境的不同而变化,在 Ant 中可以把所有这些可能变化的地方都放到一个配置文件中,然后在 Ant 脚本中引用这个配置文件就可以了,针对上面的例子,如下所示:
<project name="testBuild" default="compile" basedir=".">
<property file="build.properties"/>
<target name="init">
<mkdir dir="${dest.dir}" />
</target>
<target name="compile" depends="init">
<javac srcdir="${src.dir}" destdir="${dest.dir}"/>
<echo>Build into ${dest.dir}, successfully.</echo>
</target>
</project>
build.properties的内容:
dest.dir=c:/temp/dest/testProj
src.dir=c:/temp/src/testProj
如果想在 Ant 脚本中引用值的话,只需用$符号开头,在一对"{}"中写入要引用的键值。如上例中,需要引用编译的目标路径用"${dest.dir}"。
使用 Ant 任务从 CVS 中检出(check out)源代码,并编译打包
Ant 中提供了 cvs 任务(Task)可以从 CVS 服务器中检出资源(注意:在使用 Ant 的 cvs 任务之前,请先将 cvs.exe 下载到你的机器,并且将它添加到你本地的 PATH 环境变量中,然后重新启动 Eclipse。否则在执行下面脚本的时候就会得到 error=2 的错误)。cvs 的可选用属性很多,在这里介绍经常使用到的几个属性。从 CVS 中检出资源一般需要指定:
CVS 所在的服务器地址:目标 CVS 服务器地址
用户名:登录该 CVS 服务器你指定的用户名
密码:登录该 CVS 服务器需要的密码
库路径(Repository Path):服务器中的库路径
模块名:当前需要检出的模块名,一般都是以工程的名字作为模块名
标签名:需要从 CVS 中检出哪个标签
在介绍使用 Ant 的 cvs 之前,先说一下本地的目录结构。在 C 盘的 temp 目录下,分别有四个目录,如下所示:
build 目录:放编译后的类以及资源文件
dist 目录:放生成的 jar 文件或者 war 文件
lib 目录:放在编译过程中需要用到的 jar 文件
src 目录:放从 cvs 中检出的源文件(包括 JSP 等)
在 Ant 中这样写就可以从中检出资源:
<cvs cvsRoot=":pserver:username:pwd@cvs.server:/home/testPath"
package="TestProj" dest=" c:/temp/src/testProj " failonerror="true" />
这段脚本片断的意思就是从叫"cvs.server"的服务器中,用用户名是 username、密码为 pwd 的用户检出在库路径是 /home/testPath 下的 TestProj 模块(项目),检出后的资源放入本地目录 c:/temp/src/testProj 中。在上面这段脚本中,可以看到有很多值可能会根据不同的环境或者用户随之改变的,比如用户名和密码等;而且从脚本的重复可利用性来说,需要把有些值抽出来放到配置文件中,如服务器的地址和库路径等。因此把这些可能需要更改的地方放到 property 文件中,效果会更好。改完后的完整 Ant 脚本如下所示:
<?xml version="1.0"?>
<project name="testWeb" default="checkout" basedir=".">
<target name="checkout">
<property file="TestWeb.properties" />
<cvs cvsRoot="${cvs.root}" package="${cvs.projectName}"
tag="${cvs.tag}" dest="${src.dir}" failonerror="true" />
</target>
</project>
对应的 TestWeb.properties 文件内容如下所示:
base.dir=c:/temp/
src.dir=${base.dir}/src
cvs.server=cvs.server
cvs.user=username
cvs.pw=pwd
cvs.repositoryPath=/home/testPath
cvs.projectName=TestProj
cvs.root=:pserver:${cvs.user}:${cvs.pw}@${cvs.server}:${cvs.repositoryPath}
cvs.tag=
在检出了资源后,需要对其进行编译打包。为了使 Ant 脚本更加具有可读性和灵活性,我们需要对上面的 Ant 脚本进行一些改动。首先将 Ant 脚本中进行分段,如下所示:
<?xml version="1.0"?>
<project name="testWeb" default="all" basedir=".">
<target name="all" depends="init,clean,checkout,build">
<!--脚本的入口点-->
</target>
<target name="init">
<!--做初始化属性文件和设置classpath等设置初始条件-->
</target>
<target name="clean">
<!--删除上一次留下的没用的目录和文件-->
</target>
<target name="checkout">
<!--从CVS中检出资源-->
</target>
<target name="build">
<!--编译源文件并打包到指定的目录-->
</target>
</project>
上面的脚本中,总共分成了5个目标(target),脚本的入口点是"all",all 按顺序调用 init,clean,checkout,build。其中:
init 是用来做初始化属性文件和设置 classpath 等设置初始条件的事情
clean 用来删除上一次留下的没用的目录和文件
checkout 已经介绍过了,是用来从 CVS 中检出资源
build 用来编译源文件并打 WAR 包到指定的目录
详细的 Ant 脚本可以参见随本文所附的 TestWeb.xml 和 TestWeb.properties。
编译过程与产生不同目标环境的脚本分开执行
在前面介绍的 Ant 脚本中,根据从 CVS 服务器中检出的资源打成了一个默认的 war 包,并没有考虑根据不同的目标环境来生成不同的包,从下一节开始介绍如何根据不同的环境来生成不同的部署包。
还有一个问题是:为什么需要把从 CVS 中检出资源、编译的过程跟根据目标环境打包的过程分开?
这是因为本身 CVS 检出资源是需要花一定的时间,如果资源比较多这个过程就会花费挺长时间;另外,在多人开发的情况下必须保证在生成不同的部署包的时候是用的是同一套代码生成的,否则会出现各个服务器上运行的版本不一致,如果检出资源、编译的过程跟生成包的脚本一起执行的话就会出现这个问题(比如小A在测试服务器测试通过的时候之后,再生成一个在产品环境下的部署包,如果分两次从 CVS 服务器中检出资源的话,在此期间可能会有开发人员往 CVS 服务器中检入代码,导致生成的版本不一致),因此,必须将这两个过程分开执行。现在我们开始建立另外一个 Ant 脚本文件,叫 deploy.xml,专门用来生成包;另外与 deploy.xml 相对应的还有一个 deploy.properties 文件。在 deploy.xml 中会引用 deploy.properties 文件。另外根据在前面的场景中碰到的环境,创建三个不同的属性文件, develop_deploy.property、test_deploy. property 和 product_deploy. Property,在打包的时候,根据不同的目标环境,将相应属性文件中的内容拷贝至 deploy.properties 文件中(或者也可以直接在 deploy.xml 中直接切换不同的属性文件),然后在 Eclipse 中直接执行 deploy.xml;如果在命令行中,可以用下面的命令来执行:
ant –f deploy.xml
解开 WAR 包
我们首先得建立一个目录(这里是 unpack)用来存放解压后的文件。Ant 中提供了 unzip 命令用来解压 ear/war/jar 包。除了这个目录外,根据不同的目标环境,在运行目录下建立一个与目标环境相对应的目录,重新打好的 war 包就放在这个目录下,比如针对场景中的情况,如果需要创建一个产品环境下的部署包,我们可以建立一个 TestWebProduct 目录,目录名写在配置文件中(${pack.base.dir})。
<target name="init">
<echo>init in deploy</echo>
<property file="deploy.properties" />
<delete dir="${unpack.base.dir}" failonerror="false" />
<delete dir="${pack.base.dir}" failonerror="false" />
<mkdir dir="${unpack.base.dir}" />
<mkdir dir="${pack.base.dir}" />
</target>
<target name="unpack">
<echo>unpack the ${war.name}</echo>
<copy file="${dest.dir}/${war.name}" todir="${unpack.base.dir}" />
<unzip src="${unpack.base.dir}/${war.name}" dest="${unpack.base.dir}/${projectName}" />
<delete file="${unpack.base.dir}/${war.name}" />
</target>
在 init 段中首先删除掉上次解压的目录和目标打包目录,然后重新建立目录;在 unpack 中,首先将编译好的默认 war 包拷贝至 unpack 定义的目录,解压之后把 unpack 下的 war 包删除。下面是这时候对应的属性文件。
projectName=MTSWeb
war.name=MTSWeb.war
#根目录
base.dir=c:/temp
#默认的war包所在的目录
dest.dir=${base.dir}/dist
#解压后的目录
unpack.base.dir=${base.dir}/unpack
#目标环境相对应的目录
pack.base.dir=${base.dir}/TestWebProduct
利用 Ant 提供的 filter 任务替换属性值
现在根据不同环境的需要,对某些配置文件的值做一些替换。在 Ant 中,提供了 filter 任务,使得替换值很方便。当然也可以使用下面介绍的正则表达式来替换属性值。filter 主要用来在同一行内容中的替换,而正则表达式一下子可以替换多行内容。filter 的使用例子:
<filter token=" log4j.logger" value="INFO"/>
<copy todir="${dest.dir}" filtering="true">
<fileset dir="${src.dir}"/>
</copy>
这段脚本的意思就是在 src.dir 目录下的所有文件中,如果有预先定义好的"@log4j.logger@"占位符的话,在拷贝到 dest.dir 目录后,所有的占位符都被替换成了"INFO"。
你也可以将所有被替换的值放到某个属性文件中,filter 任务将属性文件中的每一个条目读出来并且设置成一个 Filter。如下所示:
<filter filtersfile="deploy_env.properties"/>
<copy todir="${dest.dir}" filtering="true">
<fileset dir="${src.dir}"/>
</copy>
上面的脚本表示所有在 deploy_env 中出现的条目将被作为一个 filter,在拷贝到 dest.dir 目录后,所有 src.dir 目录中存在的占位符将被替换成 deploy_env 中的值。具体的例子可以参见随本文附带的 deploy.xml, deploy_env.properties 和 Test.properties。
其中 deploy.xml 是 ant 脚本,deploy_env.properties 中包含所有要替换的值,在 Test.properties 中是包含有占位符的资源文件。
利用正则表达式替换属性值
Ant 中支持多种正则表达式,在运行 Ant 的时候用哪种正则表达式可以通过设置 ant.regexp.regexpimpl 的值来切换,Ant 支持的的正则表达式有:
java.util.regex package of JDK 1.4
jakarta-regexp
installation dependencies
正则表达式的例子:
<replaceregexp byline="true">
<regexp pattern="正则表达式"/>
<substitution expression="将要替换的值"/>
<fileset dir="${unpack.war.dir}/WEB-INF" includes="web.xml"/>
</replaceregexp>
byline 属性用来确认被替换的时候是一次替换一行还是多行;pattern 属性用来指明正则表达式;substitution expression 中是替换的值,替换的值都定义在相对应的配置文件中;fileset 属性中的 dir 用来指定被替换文件所在的目录,includes 用来指定要替换哪个文件。需要注意的是,如果在正则表达式或者替换的值中出现"<"的话,需要用转义符"<"。
在 Eclipse3.1 中已经内置了对正则表达式的支持;但是如果你在命令行中运行需要正则表达式支持的脚本的话,则需要自己将正则表达式的包下载下来加到 classpath 中。在随文章的 deploy.xml 中提供了一个简单的替换属性文件的值的例子。正则表达式的例子可以在本文所带的 deploy.xml 中找到。
Ant 使用条件表达式,根据属性值删除不需要的文件
在生成部署包的时候,还有可能会根据目标环境的不同,删除一些不同的文件。比如在产品环境中那些作为测试需要的代码往往需要删除,但是测试环境中并不需要。因此就需要条件表达式来做判断。如下所示:
<target name="checkTestEnv">
<condition property="isTestEnv">
<istrue value="${deploy.isTestEnv}" />
</condition>
<antcall target="trueCondition" />
<antcall target="falseCondition" />
</target>
<target name="trueCondition" if="isTestEnv">
<echo message="true condition in ${projectName}" />
</target>
<target name="falseCondition" unless="isTestEnv">
<echo message="false condition in ${projectName}" />
</target>
在上面的例子中,先读出 ${deploy.isTestEnv} 的值(在配置文件 deloy.properties 中),根据读出的值对属性 isTestEnv 设值,如果 ${deploy.isTestEnv} 的值是 true,isTestEnv 的值也是 true;否则是 false。然后分别调用目标段 trueCondition 和 falseCondition。在这里,表达式值的判断是用"istrue",在 Ant 中还提供了很多别的表达式,比如 not/and/or,equals 等等,具体关于条件表达式的信息可以参考:http://ant.apache.org/manual/CoreTasks/condition.html ,该页也可以在随下载下来的文档中找到。
在段 trueCondition 中,判断 isTestEnv,如果是真的话就运行,否则不运行;在段 falseCondition 中,也判断 isTestEnv,如果是假就运行,否则不运行,在段中可以根据情况做相应的事情。条件判断式的例子可以在本文的 deploy.xml 中找到。
重新打包,并拷贝到不同的目录
在上面的替换过程完成后,调用 war 将 unpack 目录下的内容重新打包。
<target name="repack">
<war destfile="${pack.base.dir}/${projectName}.war"
basedir="${unpack.base.dir}/${projectName}"
webxml="${unpack.base.dir}/${projectName}/WEB-INF/web.xml"
manifest="${unpack.base.dir}/${projectName}/META-INF/MANIFEST.MF">
</war>
</target>
详细的例子可以参见随本文的附件 deploy.xml 和 deploy.properties。
下载:点击下载
读者定位为具有 Java 和 Ant 使用经验的开发人员。
读者可以学习到如何使用 Ant 解决一些多用户开发环境中,根据不同的目标环境编译成不同部署包的问题。
工作场景
现在有一个 web 项目,是多人进行开发的,通过 CVS 来管理。另外该项目还有一些测试人员,他们测试部署在测试服务器上的应用程序,发现 bug 后通过 bug 管理系统通知开发人员,在开发人员修复 bug 并经过本地测试后,由专门的人负责检出(check out)代码,编译打包后部署到测试服务器上。
该项目的成员小A就是负责检出代码、编译打包,并部署到服务器上的人。除了这个任务之外,他还是该项目的编程人员。在项目进入测试阶段后,小A在得到组中别的成员修复了 bug 并且检入(check in)了代码的消息后(也有可能是小A自己检入了代码),小A首先更新本地的代码,先在本地做测试,确认修复了 bug 后打成 WAR 包部署到测试服务器上,并通知测试人员已经修复了 bug,让测试人员继续进行测试。
小A的烦恼
在该项目中,有一些为测试方便开发而写的代码和页面,比如跳过用户认证,但是在部署到测试机环境的时候,需要删除这些代码和页面;另外作为一个具有灵活性和扩展性的应用程序,又有一些配置文件,配置文件中的值会根据环境的改变而变动。例如,在项目中使用了 Log4j 记录日志,需要给 Log4j 指定日志文件的保存路径,本地程序员开发的时候用的是 Windows 系统,给 Log4j 指定的也是 Windows 的文件系统,在测试阶段的时候,需要部署到 Linux 系统中,那么日志的保存路径也需要做相应的改动。部署到测试服务器上的时候,除了 Log4j 需要改之外,还有很多别的配置项目也需要变动,并且分散在各个 package 中。小A的烦恼也随之而来,每次他在做完本地测之后,就根据测试机的需要逐个找配置文件,更改相应的值,并删除那些为测试方便写的代码和页面,每天可能根据需要做好几次这样的事情,最烦的是他在快做完对测试机环境更改的时候,某开发人员突然通知小A说:“我又改了一点代码,刚检入,你再重打一个包吧。”,小A又不得不从头开始做新一轮的检出代码、本地测试、更改配置文件、删除不需要的文件、打包部署的工作。另外小A在测试阶段的后期被通知要求除了每次生成一个测试环境的 WAR 包外还必须生成一个在产品环境下的 WAR 包,他做的事情就更多了。
从上面的场景可以看出,小A的工作效率低而且容易出错,甚至有可能导致整个项目的工作效率低下。其实可以通过 Ant 来帮助小A快速而且有效地完成这个工作。在 Ant 中,根据目标环境的需要,可以把所有要更改的配置文件的项目集中写到某个配置文件中。这样根据不同的目标环境得到不同的配置文件,Ant 在编译包时根据不同的目标环境切换不同的配置文件即可。比如小A现在碰到的有 3 中环境:开发环境、测试环境以及产品环境,根据这三种环境可以生成三个不同的配置文件:develop_deploy.property、test_deploy. property和product_deploy. property,当小A想生成不同的包时只需在这三个配置文件之间切换就可以了。
在正式开始编写脚本之前,我们需要下载安装相应的软件。
Eclipse:为了使 Ant 的开发更加简单,我们选择了 Eclipse3.1 作为开发环境。当然你可以使用任何你喜欢的文本编辑工具来开发你的 Ant。Eclipse 的最新版本可以在 http://eclipse.org/ 上下载。
Ant:Ant 是基于 Java 的编译工具,它就像 C/C++ 中的 make,但是没有 make 那样难用。Ant 的最新版本可以在 http://ant.apache.org/bindownload.cgi 上下载。如果你用 Eclipse 来开发 Ant,则不用去单独下载 Ant,因为在 Eclipse 中已经集成了 Ant。
CVS 客户端(cvs.exe):CVS 可以在 http://www.nongnu.org/cvs/ 上下载
用 Eclipse3.1 来创建 Ant 脚本
如果你使用 Eclipse 来编写 Ant,建议使用 Eclipse 3.1 以后的版本。除了以前 Ant 编辑器提供的语法高亮,提示语法错误等功能外,Eclipse3.1 版本增加了许多新的功能。比如:脚本代码的折叠;快速定位某属性或者目标(target)段的定义;在同一 builder 文件中重构属性名和目标名(快捷方式Alt + Shift +R);调试 Ant 脚本等。
下面我们就来看看 Eclipse 3.1 中对 Ant 的支持
打开“File”-“New”-“Project”-“Simple”-“Project”,点击“Next”,输入工程名“Ant”,然后点击直到“Finish”
在新建的 Ant 工程中,新建 Test.xml,并且拷贝下面的脚本。该段脚本的内容就不做介绍了,我们主要看 Eclipse 提供了哪些功能。注意这时候打开的并不是 Ant 编辑器,将内容拷贝进去之后,关掉打开的“Test.xml”,然后再重新打开它,这样 Eclipse 就会用 Ant 编辑器打开它,并且也语法高亮了。
<?xml version="1.0" encoding="UTF-8"?>
<project name="Test" default="init" basedir=".">
<property name="test" value="test"/>
<target name="init">
<echo>${test}</echo>
</target>
</project>
自动提示和代码折叠功能。如果是 Ant 内置的命令或者前面已经定义的变量,编辑器会自动提示;编辑器右边的加/减号可以代码折叠。如下所示:
快速定位目标(target)或者定义变量处。在上图中,将鼠标移至 default=”init” 中的 init 上之后,按下 ctrl 键,鼠标变成手状,单击就可以定位到定义该目标的地方
快速重构目标名或者属性名。选中目标/属性名,按下 Alt + Shift + R,然后键入你要修改后的值,所有引用到的地方都会随之改动。如下图所示,选中 init 后,按下快捷键,改成 initial:
调试 Ant 脚本。在标签“<target name=..”的左边设置一断点,然后在编辑器中右击,出现的菜单中选“Debug As”-“Ant Build”,出现后的窗口与调试 Java 程序的界面差不多。
这是调试窗口,这里可以选择单步跟进、跳出等:
下面是运行时变量窗口。可以看到 test 变量的值是“test”:
运行结果窗口:
由此可见,如果使用好 Eclipse Ant 编辑器所提供强大的功能的话能大大提高写 Ant 脚本的效率。
Ant 中使用 property(属性)文件
刚开始写 Ant 的初学者可能会把所有的信息都放在 build.xml 中,下面就是这样的一个例子。
<project name="testBuild" default="compile" basedir=".">
<target name="init">
<mkdir dir="c:/temp/dest/testProj" />
</target>
<target name="compile" depends="init">
<javac srcdir="c:/temp/src/testProj" destdir="c:/temp/dest/testProj "/>
<echo>Build into c:/temp/dest/testProj, successfully.</echo>
</target>
</project>
在上面的例子中,所有的路径信息都是写在 build.xml 中。但是 Ant 脚本可能在不同的机器或者不同的系统上运行,也有可能一些值需要根据环境的不同而变化,在 Ant 中可以把所有这些可能变化的地方都放到一个配置文件中,然后在 Ant 脚本中引用这个配置文件就可以了,针对上面的例子,如下所示:
<project name="testBuild" default="compile" basedir=".">
<property file="build.properties"/>
<target name="init">
<mkdir dir="${dest.dir}" />
</target>
<target name="compile" depends="init">
<javac srcdir="${src.dir}" destdir="${dest.dir}"/>
<echo>Build into ${dest.dir}, successfully.</echo>
</target>
</project>
build.properties的内容:
dest.dir=c:/temp/dest/testProj
src.dir=c:/temp/src/testProj
如果想在 Ant 脚本中引用值的话,只需用$符号开头,在一对"{}"中写入要引用的键值。如上例中,需要引用编译的目标路径用"${dest.dir}"。
使用 Ant 任务从 CVS 中检出(check out)源代码,并编译打包
Ant 中提供了 cvs 任务(Task)可以从 CVS 服务器中检出资源(注意:在使用 Ant 的 cvs 任务之前,请先将 cvs.exe 下载到你的机器,并且将它添加到你本地的 PATH 环境变量中,然后重新启动 Eclipse。否则在执行下面脚本的时候就会得到 error=2 的错误)。cvs 的可选用属性很多,在这里介绍经常使用到的几个属性。从 CVS 中检出资源一般需要指定:
CVS 所在的服务器地址:目标 CVS 服务器地址
用户名:登录该 CVS 服务器你指定的用户名
密码:登录该 CVS 服务器需要的密码
库路径(Repository Path):服务器中的库路径
模块名:当前需要检出的模块名,一般都是以工程的名字作为模块名
标签名:需要从 CVS 中检出哪个标签
在介绍使用 Ant 的 cvs 之前,先说一下本地的目录结构。在 C 盘的 temp 目录下,分别有四个目录,如下所示:
build 目录:放编译后的类以及资源文件
dist 目录:放生成的 jar 文件或者 war 文件
lib 目录:放在编译过程中需要用到的 jar 文件
src 目录:放从 cvs 中检出的源文件(包括 JSP 等)
在 Ant 中这样写就可以从中检出资源:
<cvs cvsRoot=":pserver:username:pwd@cvs.server:/home/testPath"
package="TestProj" dest=" c:/temp/src/testProj " failonerror="true" />
这段脚本片断的意思就是从叫"cvs.server"的服务器中,用用户名是 username、密码为 pwd 的用户检出在库路径是 /home/testPath 下的 TestProj 模块(项目),检出后的资源放入本地目录 c:/temp/src/testProj 中。在上面这段脚本中,可以看到有很多值可能会根据不同的环境或者用户随之改变的,比如用户名和密码等;而且从脚本的重复可利用性来说,需要把有些值抽出来放到配置文件中,如服务器的地址和库路径等。因此把这些可能需要更改的地方放到 property 文件中,效果会更好。改完后的完整 Ant 脚本如下所示:
<?xml version="1.0"?>
<project name="testWeb" default="checkout" basedir=".">
<target name="checkout">
<property file="TestWeb.properties" />
<cvs cvsRoot="${cvs.root}" package="${cvs.projectName}"
tag="${cvs.tag}" dest="${src.dir}" failonerror="true" />
</target>
</project>
对应的 TestWeb.properties 文件内容如下所示:
base.dir=c:/temp/
src.dir=${base.dir}/src
cvs.server=cvs.server
cvs.user=username
cvs.pw=pwd
cvs.repositoryPath=/home/testPath
cvs.projectName=TestProj
cvs.root=:pserver:${cvs.user}:${cvs.pw}@${cvs.server}:${cvs.repositoryPath}
cvs.tag=
在检出了资源后,需要对其进行编译打包。为了使 Ant 脚本更加具有可读性和灵活性,我们需要对上面的 Ant 脚本进行一些改动。首先将 Ant 脚本中进行分段,如下所示:
<?xml version="1.0"?>
<project name="testWeb" default="all" basedir=".">
<target name="all" depends="init,clean,checkout,build">
<!--脚本的入口点-->
</target>
<target name="init">
<!--做初始化属性文件和设置classpath等设置初始条件-->
</target>
<target name="clean">
<!--删除上一次留下的没用的目录和文件-->
</target>
<target name="checkout">
<!--从CVS中检出资源-->
</target>
<target name="build">
<!--编译源文件并打包到指定的目录-->
</target>
</project>
上面的脚本中,总共分成了5个目标(target),脚本的入口点是"all",all 按顺序调用 init,clean,checkout,build。其中:
init 是用来做初始化属性文件和设置 classpath 等设置初始条件的事情
clean 用来删除上一次留下的没用的目录和文件
checkout 已经介绍过了,是用来从 CVS 中检出资源
build 用来编译源文件并打 WAR 包到指定的目录
详细的 Ant 脚本可以参见随本文所附的 TestWeb.xml 和 TestWeb.properties。
编译过程与产生不同目标环境的脚本分开执行
在前面介绍的 Ant 脚本中,根据从 CVS 服务器中检出的资源打成了一个默认的 war 包,并没有考虑根据不同的目标环境来生成不同的包,从下一节开始介绍如何根据不同的环境来生成不同的部署包。
还有一个问题是:为什么需要把从 CVS 中检出资源、编译的过程跟根据目标环境打包的过程分开?
这是因为本身 CVS 检出资源是需要花一定的时间,如果资源比较多这个过程就会花费挺长时间;另外,在多人开发的情况下必须保证在生成不同的部署包的时候是用的是同一套代码生成的,否则会出现各个服务器上运行的版本不一致,如果检出资源、编译的过程跟生成包的脚本一起执行的话就会出现这个问题(比如小A在测试服务器测试通过的时候之后,再生成一个在产品环境下的部署包,如果分两次从 CVS 服务器中检出资源的话,在此期间可能会有开发人员往 CVS 服务器中检入代码,导致生成的版本不一致),因此,必须将这两个过程分开执行。现在我们开始建立另外一个 Ant 脚本文件,叫 deploy.xml,专门用来生成包;另外与 deploy.xml 相对应的还有一个 deploy.properties 文件。在 deploy.xml 中会引用 deploy.properties 文件。另外根据在前面的场景中碰到的环境,创建三个不同的属性文件, develop_deploy.property、test_deploy. property 和 product_deploy. Property,在打包的时候,根据不同的目标环境,将相应属性文件中的内容拷贝至 deploy.properties 文件中(或者也可以直接在 deploy.xml 中直接切换不同的属性文件),然后在 Eclipse 中直接执行 deploy.xml;如果在命令行中,可以用下面的命令来执行:
ant –f deploy.xml
解开 WAR 包
我们首先得建立一个目录(这里是 unpack)用来存放解压后的文件。Ant 中提供了 unzip 命令用来解压 ear/war/jar 包。除了这个目录外,根据不同的目标环境,在运行目录下建立一个与目标环境相对应的目录,重新打好的 war 包就放在这个目录下,比如针对场景中的情况,如果需要创建一个产品环境下的部署包,我们可以建立一个 TestWebProduct 目录,目录名写在配置文件中(${pack.base.dir})。
<target name="init">
<echo>init in deploy</echo>
<property file="deploy.properties" />
<delete dir="${unpack.base.dir}" failonerror="false" />
<delete dir="${pack.base.dir}" failonerror="false" />
<mkdir dir="${unpack.base.dir}" />
<mkdir dir="${pack.base.dir}" />
</target>
<target name="unpack">
<echo>unpack the ${war.name}</echo>
<copy file="${dest.dir}/${war.name}" todir="${unpack.base.dir}" />
<unzip src="${unpack.base.dir}/${war.name}" dest="${unpack.base.dir}/${projectName}" />
<delete file="${unpack.base.dir}/${war.name}" />
</target>
在 init 段中首先删除掉上次解压的目录和目标打包目录,然后重新建立目录;在 unpack 中,首先将编译好的默认 war 包拷贝至 unpack 定义的目录,解压之后把 unpack 下的 war 包删除。下面是这时候对应的属性文件。
projectName=MTSWeb
war.name=MTSWeb.war
#根目录
base.dir=c:/temp
#默认的war包所在的目录
dest.dir=${base.dir}/dist
#解压后的目录
unpack.base.dir=${base.dir}/unpack
#目标环境相对应的目录
pack.base.dir=${base.dir}/TestWebProduct
利用 Ant 提供的 filter 任务替换属性值
现在根据不同环境的需要,对某些配置文件的值做一些替换。在 Ant 中,提供了 filter 任务,使得替换值很方便。当然也可以使用下面介绍的正则表达式来替换属性值。filter 主要用来在同一行内容中的替换,而正则表达式一下子可以替换多行内容。filter 的使用例子:
<filter token=" log4j.logger" value="INFO"/>
<copy todir="${dest.dir}" filtering="true">
<fileset dir="${src.dir}"/>
</copy>
这段脚本的意思就是在 src.dir 目录下的所有文件中,如果有预先定义好的"@log4j.logger@"占位符的话,在拷贝到 dest.dir 目录后,所有的占位符都被替换成了"INFO"。
你也可以将所有被替换的值放到某个属性文件中,filter 任务将属性文件中的每一个条目读出来并且设置成一个 Filter。如下所示:
<filter filtersfile="deploy_env.properties"/>
<copy todir="${dest.dir}" filtering="true">
<fileset dir="${src.dir}"/>
</copy>
上面的脚本表示所有在 deploy_env 中出现的条目将被作为一个 filter,在拷贝到 dest.dir 目录后,所有 src.dir 目录中存在的占位符将被替换成 deploy_env 中的值。具体的例子可以参见随本文附带的 deploy.xml, deploy_env.properties 和 Test.properties。
其中 deploy.xml 是 ant 脚本,deploy_env.properties 中包含所有要替换的值,在 Test.properties 中是包含有占位符的资源文件。
利用正则表达式替换属性值
Ant 中支持多种正则表达式,在运行 Ant 的时候用哪种正则表达式可以通过设置 ant.regexp.regexpimpl 的值来切换,Ant 支持的的正则表达式有:
java.util.regex package of JDK 1.4
jakarta-regexp
installation dependencies
正则表达式的例子:
<replaceregexp byline="true">
<regexp pattern="正则表达式"/>
<substitution expression="将要替换的值"/>
<fileset dir="${unpack.war.dir}/WEB-INF" includes="web.xml"/>
</replaceregexp>
byline 属性用来确认被替换的时候是一次替换一行还是多行;pattern 属性用来指明正则表达式;substitution expression 中是替换的值,替换的值都定义在相对应的配置文件中;fileset 属性中的 dir 用来指定被替换文件所在的目录,includes 用来指定要替换哪个文件。需要注意的是,如果在正则表达式或者替换的值中出现"<"的话,需要用转义符"<"。
在 Eclipse3.1 中已经内置了对正则表达式的支持;但是如果你在命令行中运行需要正则表达式支持的脚本的话,则需要自己将正则表达式的包下载下来加到 classpath 中。在随文章的 deploy.xml 中提供了一个简单的替换属性文件的值的例子。正则表达式的例子可以在本文所带的 deploy.xml 中找到。
Ant 使用条件表达式,根据属性值删除不需要的文件
在生成部署包的时候,还有可能会根据目标环境的不同,删除一些不同的文件。比如在产品环境中那些作为测试需要的代码往往需要删除,但是测试环境中并不需要。因此就需要条件表达式来做判断。如下所示:
<target name="checkTestEnv">
<condition property="isTestEnv">
<istrue value="${deploy.isTestEnv}" />
</condition>
<antcall target="trueCondition" />
<antcall target="falseCondition" />
</target>
<target name="trueCondition" if="isTestEnv">
<echo message="true condition in ${projectName}" />
</target>
<target name="falseCondition" unless="isTestEnv">
<echo message="false condition in ${projectName}" />
</target>
在上面的例子中,先读出 ${deploy.isTestEnv} 的值(在配置文件 deloy.properties 中),根据读出的值对属性 isTestEnv 设值,如果 ${deploy.isTestEnv} 的值是 true,isTestEnv 的值也是 true;否则是 false。然后分别调用目标段 trueCondition 和 falseCondition。在这里,表达式值的判断是用"istrue",在 Ant 中还提供了很多别的表达式,比如 not/and/or,equals 等等,具体关于条件表达式的信息可以参考:http://ant.apache.org/manual/CoreTasks/condition.html ,该页也可以在随下载下来的文档中找到。
在段 trueCondition 中,判断 isTestEnv,如果是真的话就运行,否则不运行;在段 falseCondition 中,也判断 isTestEnv,如果是假就运行,否则不运行,在段中可以根据情况做相应的事情。条件判断式的例子可以在本文的 deploy.xml 中找到。
重新打包,并拷贝到不同的目录
在上面的替换过程完成后,调用 war 将 unpack 目录下的内容重新打包。
<target name="repack">
<war destfile="${pack.base.dir}/${projectName}.war"
basedir="${unpack.base.dir}/${projectName}"
webxml="${unpack.base.dir}/${projectName}/WEB-INF/web.xml"
manifest="${unpack.base.dir}/${projectName}/META-INF/MANIFEST.MF">
</war>
</target>
详细的例子可以参见随本文的附件 deploy.xml 和 deploy.properties。
下载:点击下载
发表评论
-
调试MAVEN项目appfuse-light-struts2-spring-jdbc-1.8的问题
2008-03-07 16:31 2284出现问题: Project appfuse-light-str ... -
MVC设计思想
2008-03-01 22:13 2142MVC英文即Model-View-Controll ... -
当前Java软件开发中几种认识误区(转)
2008-03-01 22:11 968软件的生命性 软件是有生命的,这可能是老调重弹了,但是因 ... -
给servlet写单元测试的总结(转)
2008-02-19 11:19 3544servlet的测试一般来说需要容器的支持,不是像通常的jav ... -
取得参数的几中形式
2008-02-18 12:54 881java -DSTOP.PORT=8080 -DSTOP.KE ... -
正则表达式
2008-02-18 12:34 898目录 本文目标 如何使 ... -
关于Java中类在构造对象时的初始化步骤详解
2008-02-18 12:17 2098很多人在学习Java的过程 ... -
Java连接各种数据库的实例
2008-02-18 12:13 1164一、jsp连接Oracle8/8i/9i数据库(用thin模式 ... -
为什么要使用接口编程(转)
2008-02-17 21:42 1283看了接口编程这篇文章, ... -
JAVA中浅复制与深复制
2008-02-17 21:38 7191.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变 ... -
短信网关发送部分源代码
2008-02-17 21:37 1214package com.etonenet.iiie.sdk; ... -
appfuse结合eclipse开发流程
2008-02-17 21:33 1218Appfuse应用的核心在于ant ... -
使用Antlr和JfreeChart实现项目源代码行数计算图表
2008-02-17 21:30 1541Antlr的功能在我的其他文章里提到了就不多说了,JFreeC ... -
使用ANT协助开发java项目
2008-02-17 21:29 894ANT是Apache的开源项目,目前在java的项目开发中被广 ... -
使用开源软件 Mantis 实施缺陷跟踪的成功实践
2008-02-17 21:22 1697内容摘要 中国开源 注:当前Mantis稳定发布版本为1.0. ... -
开源缺陷跟踪系统mantis安装指南
2008-02-17 21:14 18861. 简介 mantis(螳螂)是一个基于php/MySQL/ ... -
无所不能的“蚂蚁”-Ant(转)
2008-02-17 21:12 3231说他无所不能,好像有点夸张,但是用过Ant之后,感觉真的是只有 ... -
Java华为面试题
2008-02-17 21:08 1468第一部分:选择题 QUESTION NO: 1 1、publi ... -
java中读取Properties文件
2008-02-17 21:06 906ResourceBundle resourceBundle = ... -
Java范型
2008-02-17 21:04 1536从jdk1.5开始,Java中开始 ...
相关推荐
标题中的"ant-eclipse.jar.zip"表明这是一个包含“ant-eclipse.jar”文件的压缩包,主要用于在Eclipse集成开发环境...通过安装并导入这个插件,开发者可以提高他们的工作效率,无需离开Eclipse就能完成复杂的构建流程。
将Eclipse PDE与ANT结合,可以实现插件开发的自动化流程,提高开发效率并确保每次构建的一致性。 在"Export ANT Script"过程中,Eclipse PDE提供了将工程导出为ANT构建脚本的功能。这个脚本包含了构建、打包和签名...
总的来说,Ant-EclipseLink-Schemagen-1.0.6.jar.zip是Java开发中一个实用的工具集,它结合了Ant的灵活性和EclipseLink的强大功能,使得数据库建模工作变得更加便捷高效。对于那些需要处理大量数据库操作的项目来说...
这种方式使得开发者无需离开熟悉的开发环境,就能完成项目的构建流程,提高了工作效率。 在实际开发中,一个典型的流程可能是这样的:首先,开发者在 Eclipse 中编写和编辑 Java 代码,然后利用内置的 Ant 支持生成...
利用Ant脚本自动构建SVN增量是提升开发效率和质量的有效手段。通过自动化,开发者可以从繁琐的手动操作中解放出来,将更多精力投入到创新和优化中。同时,这也要求团队成员,尤其是测试人员,掌握Ant的使用,以便更...
通过以上步骤,你就可以利用Eclipse和Ant实现RCP应用的自动化打包。这不仅可以节省时间,还能减少手动操作带来的错误,提高软件发布质量。在实际项目中,还可以进一步优化Ant脚本,比如添加签名、版本控制集成、自动...
在Eclipse中,开发者可以利用Ant来构建、编译、测试和部署Java项目。 `.project`文件是Eclipse工作空间中每个项目的核心配置文件。它是隐藏的文本文件,包含了关于项目类型、构建配置、Natures(特性)和Builder...
通过在Eclipse中有效运用Ant,开发者可以实现项目的自动化构建,不仅节省了大量重复性工作的时间,还提高了构建过程的可靠性和一致性。这不仅有利于团队协作,还能显著提升软件开发的整体效率和质量。因此,掌握...
在软件开发过程中,自动化工具的应用能够显著提高工作效率并减少人为错误。Apache Ant(以下简称“Ant”)作为一款强大的Java平台下的批处理构建工具,可以帮助开发者实现诸如编译、打包等一系列任务的自动化处理。...
6. **最佳实践**:讲解如何优化配置,提高开发效率,例如使用工作空间变量、配置Eclipse的自动构建选项、设置Ant的默认属性等。 通过学习和实践这个教程,开发者不仅可以熟练掌握Java Web开发的基本工具,还能了解...
在IT行业中,Ant和...总结起来,Ant和Tomcat的结合使用可以帮助开发者高效地管理Java Web应用的构建和部署流程,实现自动化,提高工作效率。通过编写Ant脚本并配合Tomcat的管理功能,可以简化日常的开发运维任务。
理解Ant的基本概念和语法对于在Eclipse中有效使用它是至关重要的。 "Ant的使用.txt"可能提供了更多关于如何在Eclipse中利用Ant进行项目构建的细节,包括如何配置Ant构建路径、运行Ant任务以及调试构建过程。熟悉...
总之,熟练使用Ant和Eclipse的集成,可以提高开发效率,简化构建流程,尤其对于Web应用的构建和部署,Ant提供了强大的灵活性和可控性。通过合理的目录结构、库管理以及构建脚本设计,开发者可以更好地组织和管理项目...