ant杂事整理

1 篇文章 0 订阅

ant简单介绍

      我们在平常的java开发过程中间,经常会处理一些这样的小任务,比如编译代码,运行测试代码,代码打包等。最常见的一些问题就是,如果用手工命令行来处理的话,需要敲很长的命令行,要在命令行里面指定各种参数。这样就很麻烦。如果用IDE来做呢,确实显得方便一点,可是不同的人拿到代码,用IDE打开,然后要来处理这些任务的时候,经常也需要配置classpath之类的各种路径。还是不够方便。总之,用命令行太啰嗦,用IDE则不够通用。还有,在某些特殊情况下,如果我们没有IDE,那该怎么办呢?别着急,我向您推荐自动化构建工具ant.

    实际上我前面提到的问题基本上在编译型语言中都会面临。不同的平台已经有了对应的工具了,比如c语言平台的make, java平台的ant, maven.还有.net平台的msbuild。对于ant来说,我们基本上只需要写一个指示各种任务的配置文件,然后就可以重复的多次运行了。比如说,我们想要编译代码的时候,只要用一个ant build之类的命令就搞定了,不需要敲一堆的命令。

常用的概念和任务列表

    ant本身的配置文件是一个xml文本。ant命令会默认的去查找当前目录的build.xml文件,如果写的配置文件不是默认命名为build.xml,就需要在命令里手工指定这个文件。基本上配置文件里面的结构如下:

一个build文件只是描述如何来构造一个project

    如下所示,在文件的声明部分,会有一个project的xml节点,它是最外层的声明。

 

<project name="structured" default="archive">
<description>Compile and runs a simple program</description>

</project>

 在这个大的结构里面,可以针对该构建的项目进行下一步的任务细节划分。

一个project中间包含有多个target

    这里每一个target对应着一个我们期望要完成的任务,比如说编译,运行代码或者测试等等。target的典型示例如下:

 

<target name="init">
        <mkdir dir="build/classes" />
        <mkdir dir="dist" />
    </target>
    
    <target name="compile" depends="init"
        description="Compiles the source code">
        <javac srcdir="src" 
            destdir="build/classes" />
    </target>
 

这里我们添加了两个target,一个是初始化构建过程的任务,主要就是创建两个目录。另外一个就是编译代码。通过在target里面配置和指定各种参数,我们就可以通过ant命令来执行这些target了。这里比较有意思的一点就是target之间会有一定的依赖关系。比如说,我们要运行代码的时候,起码代码要先编译了吧。那么我们就需要在运行的target上面指定depends的target,这样当要执行该target的时候,他所依赖的target会先执行。关于target之间的依赖,最典型的问题就是不要形成循环依赖,否则没法知道该先执行哪个后执行哪个。鬼打墙的道理,你懂的。

一个target可以包含有多个task

    因为要执行一个target可能需要多个步骤,比如前面的init target,就通过两个mkdir task来创建两个目录。所以说一个具体的task就是一个具体的执行小步骤。包括执行一个javac的编译命令或者jar打包命令。

 

    在实际的脚本中,我们还需要设置一些property来配置各种路径信息。总的来说,ant里面基本的概念就这么些几个,想想实在很简单。

一个简单的模版

    现在,假设我们要做一个项目,然后用ant来管理构建的话,需要做哪些事呢?基本上来说需要从两个角度来考虑。一个就是整体项目结构布局,另外就是项目常用的任务。简单来说,需要有一下几个部分:

代码编译

    我们的代码里面含有产品代码和测试代码,为了不让他们混淆在一起,我们需要做几个事。首先,让这两个部分的代码位于不同的目录里。另外,编译之后的代码最好不希望和源代码混在一起。常用的情况下,我们会把代码划分成两个部分:

main和test两个目录。编译后的代码可以考虑放在一个单独的bin目录中,里面包含有class-main, class-test两个目录,分别表示编译后的产品代码和测试代码。

类库引用

    同样处于分离产品和测试的考虑,我们将产品代码需要引用的类库和测试需要的类库进行分离,我们将需要的类库放在名字为lib的目录里。里面分别放了lib-main和lib-test两个目录。

这样,整体来说,代码和类库这几个基本的目录结构就定下来了,目录引用图如下:

目录结构

清除编译结果

    还有一个比较常用的就是要清理编译后生成的class文件以及一些生成的测试统计结果文件。这个时候就需要设定一个clean的target,它的目的无非就是找到这些文件目录,然后删掉他们。

 

总的来说,只要设置好这样的目录结构并计划要执行哪些target,然后就可以来写build脚本了。一般来说除了这几个编译产品和测试代码的常用任务,还可能会包含一些其他的任务。下面是我整理的一个示例脚本:完整的示例和代码可以见附件。

 

<project name="SampleProject" default="compile">

    <path id="classpath.main">
        <fileset dir="lib/lib-main" includes="**/*.jar" />
    </path>

    <path id="classpath.test">
        <path refid="classpath.main" />
        <pathelement location="bin/classes-main" />
        <fileset dir="lib/lib-test" includes="**/*.jar" />
    </path>

    <property name="junit.data" value="reports/junit/data" />
    <property name="junit.html" value="reports/junit/html" />

    <target name="clean">
        <delete failοnerrοr="false" includeemptydirs="yes">
            <fileset dir="bin" includes="classes-*/**" />
        </delete>
    </target>

    <target name="compile">
        <mkdir dir="bin/classes-main" />
        <javac srcdir="src/main" destdir="bin/classes-main"
            debug="on" classpathref="classpath.main" />
        <mkdir dir="bin/classes-test" />
        <javac srcdir="src/test" destdir="bin/classes-test"
            debug="on" classpathref="classpath.test"/>
    </target>

    <target name="test" depends="-test-run, -test-report" />
   
    <target name="-test-run" depends="compile">
        <mkdir dir="${junit.data}" />
        <junit printsummary="yes" fork="true" haltonfailure="no">
            <classpath>
                <path refid="classpath.test" />
                <pathelement location="bin/classes-test" />
            </classpath>
            <formatter type="xml" />
            <batchtest haltonfailure="no"
                todir="${junit.data}">
                <fileset dir="src/test" includes="**/Test*.java" />
            </batchtest>
        </junit>
    </target>

    <target name="-test-report" depends="-test-run">
        <mkdir dir="${junit.html}" />
        <junitreport todir="${junit.data}">
            <fileset dir="${junit.data}" includes="TEST-*.xml"/>
            <report format="frames" todir="${junit.html}" />
        </junitreport>
    </target>

</project>
 

这个示例中包含了编译代码,指定编译结果目录,然后执行测试,生成测试统计结果等任务。可以说,只要把这些任务和相关的依赖关系列出来,后面就相当于在每个任务里填空。

总结和引申

    ant是一个简单易懂的构建管理工具。实际上大多数的项目构建过程都比较接近,如果能够从中间整理一个常用的模版,以后根据自己的需要稍微修改一下就可以运行,这样可以省下很多的精力。前面给的示例还有一些小的需要改进的地方,比如说clean的时候,有些测试统计的结果如果也需要清理的话,就需要修改。另外,其中也没有添加将编译后的文件打包的功能。在有的项目,还可以利用ant进行项目自动化部署的工作。

参考材料

ant in action

Test driven PRACTICAL TDD AND ACCEPTANCE TDD FOR JAVA DEVELOPERS

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值