| |
用Ant和Eclipse有效地提高部署效率 |
|
时间: 2006-05-30 来自:ibm |
 |
|
编译过程与产生不同目标环境的脚本分开执行
在前面介绍的 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;如果在命令行中,可以用下面的命令来执行:
解开 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。
结论
通过本文可以看出编写好有效的 Ant
脚本能很好的解决在编译部署包的时候出现的问题,将那些变化的内容放到配置文件中,在部署的时候切换不同的配置文件就可以实现生成不同的部署包。文中也介绍了如何使用
Eclipse 来提高你编写/调试 Ant 脚本的效率。
|
|
|
|
|
|
标签NewsAbout错误:Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
|
|
|
|
|
|