利用Ant实现项目自动构建测试备份并发布到项目web

 
利用 Ant 实现项目自动构建测试备份并发布到项目 web
www.jiedichina.com,南京捷帝科技
       Ant 是一个非常好的 java 编译工具。作者说这个东西是不带 make 缺陷的 make 工具( linux/unix 用户对 make/makefile 应该是很熟悉了吧),这里我们来具体实践一下使用 Ant 进行项目构建管理。
    文章开始,我也没有免了俗套,先简要的介绍一下 Ant Ant 是一个 java 的基本构建工具(我这里使用构建这个词,是因为我觉得对于 Ant 来讲,编译只是其中很小的一部分)。 Ant 是使用 java 开发的,但不仅仅是一个只适用于 java 工具,也可以为其他语言提供相映的功能,就像其他的 make 工具一样。而且由于 java 是跨平台的,所以 ant 也是可以跨平台使用的,真正的实现了 java 的一次编写到处运行的。当前 Ant 已经推出了 1.54 版了,这个版本需要 jdk1.1 以上版本的支持。不过我没有具体试验过,一来 jdk1.1 找起来很不容易,二来也没有人会用这个低版本的 jdk 进行开发了,尤其在中国。
       Ant 需要用户自己编写一个 build 脚本来对项目进行管理。这个脚本是 xml 格式的文档(近来非常流行使用 xml 文档,至少我看到的 apache.org 上的 java 项目的配置文件都是 xml 格式了,看来我们也的与时俱进呀)。使用任何一种你喜欢的编辑器都可以编写这样的 build 脚本,如果你愿意当然可以使用 windows 自带的记事本来写,没有人会反对。我在这里使用的是 eclipse 。选择他的缘故是因为 eclipse 自身已经集成了 Ant 1.5.3 版本(作为 eclipse 的一个插件),可以很方便的使用,而且集成了 Ant 的编辑器,可以做到代码提示,最重要的原因是我的项目是用 eclipse 来开发的,所以 eclipse 是不二的选择。
    eclpise 中是不需要配置 Ant 的如果你是在其他的环境中使用 Ant 那么需要配置相应的 path classpath ,将你的 ant_home 下的 lib 文件夹加入 classpath 中,这里包含了 ant 的基本类包。将 ant_home 下的 bin 文件夹加入你的 path 中,这样就可以在 windows 终端窗口使用 ant 工具了。
       Ant 的执行是 Ant [ 脚本文件 ] 这种格式,如果没有指明脚本文件,那么 ant 会在当前文件夹下寻找 build.xml 文件作为当前的脚本文件,如果连这个也找不到就只好报错了。
    当然在 eclipse 中是不用这么麻烦的。只要在 eclipse 中运行扩展工具里的 run as 中的 ant build 就可以了。 Ant 会自动去寻找当前项目文件夹中的 build.xml 的。并且以后就可以直接使用了。
    基本知识介绍完毕,开始进入正题: Ant build.xml 的编写。下面以我的 InterfacePackage 项目的开发来进行 build.xml 的解说。
    首先大家要记住 build.xml xml 文档(好像是废话,因为文件的扩展名已经告诉我们答案了),所以所编写的 build.xml 必须遵守 xml 文档的规范 , 否则 ant 会毫不留情的报错(计算机就是这样,一点也不给人留面子,每次报错都是直截了当冷酷无情的)。
      
<!-- 这是申明,说明这确实是一个 xml 文档 -- >
    <?xml version="1.0" encoding="UTF-8" ?>   
 
<! 这里说明了我的项目的文件名 ,default 指定的是默认的 task-- >
<project name="ConsoleViewer" default="dest">
    这里我们基础到了几个 ant 的基本概念,就是每一个脚本都是由 project 段内的一些内容为主体的,通过 project 标签我们可以指定项目名,和默认的 task Task ant 中的一个最重要的概念, ant 通过执行脚本中的一系列 task 来完成工作,所以 task 是可以说是 ant 的灵魂。
      
<property name="project.version.info" value="1.1.0" />
      <property name="project.name.info" value="InterfacePackage" />
      <property name="project.package.type.info" value="jar" />
      <property name="project.encoding.info" value="UTF-8" />
 
      <property name="base.dir" value="." />
      <property name="src.dir" value="${base.dir}/src" />
      <property name="bin.dir" value="${base.dir}/bin" />
      <property name="dest.dir" value="${base.dir}/dest" />
      <property name="doc.dir" value="${base.dir}/doc" />
      <property name="code.dir" value="${base.dir}/code" />
      <property name="lib.dir" value="${base.dir}/lib" />
      <property name="bak.dir" value="${base.dir}/bak"/>
      <property name="juit.report.dir" value="${base.dir}/JUnitReport" />
      <property name="web.dir" value="E:/env/deploy/html/ibeyond/${project.name.info}" />
      <property name="web.doc.dir" value="${web.dir}/doc" />
      <property name="web.code.dir" value="${web.dir}/code" />
      <property name="web.src.dir" value="${web.dir}/src" />
      <property name="web.src.dir" value="${web.dir}/bin" />
      <property name="web.old.dir" value="${web.dir}/old" />
      <property name="web.bin.dir" value="${web.dir}/bin" />
      <property name="web.report.dir" value="${web.dir}/test/report"/>
以上这些是我定义的一些 property 。何谓 property 呢?就是 ant 脚本的一些属性,而 task 就是 ant 脚本的方法,通过属性和方法的结合完成对象所能完成的工作,看来 ant 也是面向对象的。以上 property 我不需解释大家也肯定应该能看的懂吧 . 其中带 info 后缀的是指信息,带 dir 后缀的当然是指文件夹了。
<path id="appClassPath">
           <pathelement path="${java.class.path}"/>
           <fileset dir="${lib.dir}">
                 <include name="*.jar"/>
           </fileset>
           <fileset dir="${bin.dir}">
                 <include name="**/*.class"/>
           </fileset>
      </path>
先配置一下路径问题,因为是一个 java 项目,当然优先考虑的是 classpath 了。
<target name="init">
           <tstamp />
           <delete dir="${dest.dir}" />
           <delete dir="${doc.dir}" />
           <delete dir="${code.dir}" />
           <delete dir="${bin.dir}" />
           <mkdir dir="${base.dir}"/>
           <mkdir dir="${bin.dir}"/>
           <mkdir dir="${dest.dir}"/>
           <mkdir dir="${doc.dir}"/>
           <mkdir dir="${code.dir}"/>
           <mkdir dir="${bak.dir}"/>
           <mkdir dir="${juit.report.dir}"/>
           <mkdir dir="${juit.report.dir}/xml"/>
           <mkdir dir="${web.dir}"/>
           <mkdir dir="${web.code.dir}"/>
           <mkdir dir="${web.doc.dir}"/>
           <mkdir dir="${web.old.dir}"/>
           <mkdir dir="${web.src.dir}"/>
           <mkdir dir="${web.bin.dir}"/>
           <mkdir dir="${web.report.dir}"/>
      </target>
首先进行初始化任务,看起来也很简单。就是清空一些文件夹然后建立一些文件夹,这个 target 就是 task 的集合,也就是说一个 target 可以执行多个 task ,也很容易理解为了完成一个目标当然有可以使用多个方法了,这里的 delete mkdir 都是各自独立的 task 。我在第一行写了 <stamp /> 这个声明,说他是声明是因为如果你想在你的 build 脚本中使用当前的时间日期的话就必须指定这个,然后在后文中就可以使用 ${DSTAMP} 这样 标签 了。
<target name="javadoc" depends="init">
           <javadoc packagenames="*"
                 destdir="${doc.dir}"
                 sourcepath="${src.dir}"
                 charset="${project.encoding.info}"
                 encoding="${project.encoding.info}"
                 author="true"
                 version="true"
                 use="true"
                 splitindex="true"
                 windowtitle="${project.name.info} ${project.version.info} API Documentation">
                 <classpath refid="appClassPath" />
                 <doctitle>
                      <![CDATA[ <h1>${project.name} APIs(Version ${project.version})</h1> ]]>
                 </doctitle>
                 <bottom>
                      <![CDATA[ <div algin="center">Copyright &#169; 2002-2003 www.ibeyond.org, All Rights Reserved.</div>]]>
                 </bottom>
                 <tag name="todo" scope="all" description="To do:" />
           </javadoc>
</target>
第二个 target ,其中只有一个 task 就是 javadoc ,用来生成项目的 api doc ,基本上 javadoc 的参数都被 ant 支持了。所以你平时怎么用 javadoc 现在依然可以怎么用 javadoc 。合格 target 出现了一个新的关键字“ depends
也就是依赖,就是说如果要执行这个 task 那么就必须先运行他的“ depends ”在这里就是“ init ”,所以我写的这个 build 就像是文学中的倒叙似的。
<taskdef name="java2html" classname="com.java2html.Java2HTMLTask" />
      <target name="javacode" depends="javadoc">
           <java2html title="${project.name.info}version(${project.version.info}) Source Code Online View"
                 simple="no"
                 tabsize="4"
                 marginsize="2"
                 header="true"
                 footer="true"
                 encoding="UTF-8"
                 destination="${code.dir}">
                 <fileset dir="${src.dir}">
                      <include name="**/*.java"/>
                 </fileset>
                 <javadoc localRef="${doc.dir}" />
           </java2html>
      </target>
      又来了一个新的关键字 taskdef ,这个是用来做什么的呢?听我慢慢道来。
古人云:“人无完人”, ant 的开发者也是这样,他不可能预见到所有用户的需求,也就不能知道当前用户需要哪些 task ,肯定就会出现用户希望得到的 task ant 默认没有支持的情况,所以 ant 的开发者提供了一个借口,可以让用户自定义自己的 task ,然后通过 taskdef 来声明 ( 为开发 者的 个想法 击节 叫好 , 司令了一句名言“高, 在是高” ) 这样 实现 ant 的无限 展了。 Taskdef 至少要指明name和classname。Name用来指定 task 的任 标签 名,像 javadoc 这样 的就是 标签 (javadoc 是ant内置的task),classpath就是 标签 名的要 行的 的方法名, task 开发 我会在其他文章中 述的, 里就到此 止,大家心里有 个印象就可以了( java2html 可以看出是一个把java代 码转换 html 文档的工具,我使用的是我的修改版,可以支持字符 编码 拙著的〈 java2html 改造手 〉系列文章,当前我已 经开发 java2html 形界面,同 我会另外撰文 述)。
      <target name="compile" depends="init">
           <javac srcdir="${src.dir}"
                 destdir="${bin.dir}"
                 encoding="${project.encoding.info}"
                 debug="off"
                 optimize="on">
                 <classpath refid="appClassPath" />
           </javac>
      </target>
      这个也很简单,就是一个编译。
<target name="junit" depends="compile">
           <junit printsummary="yes" fork="yes" haltonfailure="no">
                 <classpath>
                      <pathelement location="${bin.dir}"/>
                      <pathelement path="${java.class.path}"/>
                 </classpath>
                 <formatter type="xml"/>
                 <batchtest todir="${juit.report.dir}/xml/${DSTAMP}">
                      <fileset dir="${bin.dir}">
                            <include name="**/*Test.class" />
                   </fileset>
                 </batchtest>
           </junit>
           <junitreport todir="${juit.report.dir}/xml/${DSTAMP}">
                 <fileset dir="${juit.report.dir}/xml/${DSTAMP}">
                      <include name="TEST-*.xml"/>
                 </fileset>
                 <report format="noframes" todir="${juit.report.dir}/html/${DSTAMP}"/>
           </junitreport>
      </target>
      这是一个测试 target 。执行全部的测试代码,并把测试结果生成 xml 文档并将这个 xml 文档转换成 html 文档, junit 也是 ant 默认支持的( java 的开源社区的力量实在是太强大了,向广大的开源社区的同志们致敬)。
<target name="package" depends="junit">
           <jar jarfile="${dest.dir}/${project.name.info}-${project.version.info}-N${DSTAMP}.${project.package.type.info}"
                 basedir="${bin.dir}" />
      </target>
      <target name="backup" depends="package">
           <zip destfile="${bak.dir}/${project.name.info}-${project.version.info}-N${DSTAMP}.zip">
                 <zipfileset file="${base.dir}/build.xml" />
                 <zipfileset file="${dest.dir}/${project.name.info}-${project.version.info}-N${DSTAMP}.${project.package.type.info}" />
                 <zipfileset dir="${src.dir}" prefix="src/"/>
                 <zipfileset dir="${bin.dir}" prefix="bin/" />
                 <zipfileset dir="${doc.dir}" prefix="doc/" />
                 <zipfileset dir="${code.dir}" prefix="code/" />
                 <zipfileset dir="${lib.dir}" prefix="lib/" />
                 <zipfileset dir="${juit.report.dir}" prefix="JunitReport/"/>
           </zip>
      </target>
<target name="email" depends="backup">
      </target>
以上内容是把应用打包备份等( jar/zip 都是 ant 内置支持的)。 Email 这一段我使空着的,因为当前这个项目只有我一个人开发,所以我也不会给自己发 email ,如果你是一个团队开发异地开发,倒是可以利用这个将测试结果或者其他你想发的东西发送给你指定的人,而我的这个脚本要直接把开发结果发送到 web 上去,所以 email 功能对我来说也许是多余的。
<target name="dest" depends="email">
           <copy todir="${web.code.dir}">
                 <fileset dir="${code.dir}" />
           </copy>
           <copy todir="${web.doc.dir}">
                 <fileset dir="${doc.dir}" />
           </copy>
           <copy todir="${web.old.dir}">
                 <fileset dir="${bak.dir}">
                      <include name="${project.name.info}-${project.version.info}-N${DSTAMP}.zip"/>
                 </fileset>
           </copy>
           <copy todir="${web.src.dir}">
                 <fileset dir="${src.dir}" />
           </copy>
           <copy todir="${web.report.dir}">
                 <fileset dir="${juit.report.dir}/html" />
           </copy>
           <copy todir="${web.bin.dir}">
                 <fileset dir="${dest.dir}">
                      <include name="${project.name.info}-${project.version.info}-N${DSTAMP}.${project.package.type.info}"/>
                 </fileset>
           </copy>
</target>
将刚才生成的乱七八糟的东西 copy 到指定的地方去,完成部署,这样我的脚本就完成了。最后别忘了再脚本的最后面添加 </project> ,这样才符合 xml 文档的格式。
在这个脚本里我实现了项目 Api 文档的生成,在线 java 代码的生成,编译,测试,打包,备份,部署到 web 等,我个人觉得这个已经满足一般的项目需求了,当然你也可以根据以上内容进行扩充,例如利用 ant cvs 的内置支持实现版本控制,或者每日构建等(每日构建可是微软的看家法宝,而且 xp 编程每日构建只是最低要求,以上纯是道听途说)。发挥你的想象力去重复利用 ant 给你带来的乐趣和成就感吧。
还是那句老话,没有你做不到,只有你想不到。
 
以上内容 iBeyond 版权所有 ( ibeyond beyondii 是同一个人,从名字上就可以看出 ) ,你也许可以从 www.ibeyond.org 得到相关信息, 也可以通过admin@ibeyond.org 和我联系。
 
  www.jiedichina.com,南京捷帝科技
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值