• ANT从入门到精通


    一、ANT的安装和配置(略,参考《ant实践》吧)
    二、ANT的学习方法
    学习ANT应该从“到底要用ANT来做什么”开始,针对自己的目的来学习,只要能够满足自己的工作的需要就可以了,ANT设计为可扩展的插件式的结构,每天都有人为ANT增加新的插件,因此要将ANT的所有功能掌握是不可能的,从我们的工作需求出发,ANT主要就是用来compile, test, build, package, deloy, integration test,这也是我使用ANT的一种固定方式,我已经为这个固定的方式写了一个模板,每次编写新的ANT的时候只需要针对具体的项目把这个模板修改一下就可以了,其实使用ANT是很简单的,如果ant很复杂和难于使用,相信也不会有如此的popular。

    三、buildfile的结构
    对于ANT的使用者来说,理解ANT的配置文件是最重要的,ANT的XML配置文件的结构很简单,这也是ANT的一个优点,简单易懂,容易上手,ANT的配置文件主要由project,target和task三层树型结构组成如下:
    <project name="helloworld" default="master">
     <property name="" value=""/>
     <target name="master">
      <task attribute1="" attribute2=""/><!--这是一个虚拟的task,具体到应用可能是ant的core task也可能是optional task-->
     </target>
    </project>
    关于project,target,task的概念,请参考官方文档的6 Using Ant部分。

    四、ANT的DataType
    前面说到了ANT的配置文件的结构主要由project,target和task组成,其实project,target和task是ANT的四个重要的概念里面的三个,还有一个很重要的概念就是Data Elements(数据类型),这是ANT最容易让人搞不清楚的一个方面,它们表达的是数据而不是任务。数据类型定义包括三个级别,project- level,target-level和task-level,有点类似于类里面定义全局变量,局部变量的方式,不同的是,这里代表了其在ant buildfile里面的可视性,如果直接定义在project节点下那就是project-level,所有的target和task都可以引用它们,以次类推。
    数据类型分为两个部分:property和DataType。
    property:<property/>标签里定义了name-value对。
    DataType:用于表示一套复杂的数据集,例如FileSet和Path
    数据类型的定义通常和target平级,也就是是数据类型一般直接在<project>下一层定义,当然也有一些直接定义在task里面,通常我们定义的数据类型和target平级的时候,可以在task下面引用这些数据类型。
    总结ANT的数据类型如下:
    argument参数:从命令行传递到buildfile的参数
    environment环境变量:传递到buildfile的环境变量
    filelist文件列表:文件不一定存在
    fileset文件集:文件必须存在

    patternset模式集
    filterset过滤集
    path路径,还有classpath
    mapper映射:定义了输入与输出文件之间的一套复杂的关系。
    ANT的数据类型很多,以上列出的是一些常用的数据类型,下面重点总结一些我自己常用的数据类型,如environment,fileset,patternset,path

    1、property属性
    一个项目可以配置很多property,property可以在在buildfile里面设置,也是可以在外部设置,在task中可以引用property,通过'${'和'}'符号来引用

    除了常见的在buildfile里面定义属性外,很多情况下可以定义一个.properties文件,然后在buildfile里面load这个文件,这样的好处是可以让buildfile不用修改的就在不同的环境里面运行,用户提供自己的.properties文件就可以了
    例如,我们定义了一个build.properties文件
    #build.properties
    extend.1.dir = 
    extend.2.dir =
    然后在buildfile里面load这个build.properties文件,在后面就可以直接引用该文件里定义的所有属性了。
    <property file="build.properties">


    ANT属性的定义原则是先定义的有效,也就是说相同的属性,定义了多次,只有第一次定义的值是有效的,例如:
    #override.properties
    test=first

    <!-- buildfile -->
    <property file="override.properties"/>
    <property name="test" value="second"/>
    因为override.properties文件中已经设置了test的值,所以在buildfile里面第二次设置的值是无效的,test的值仍然是first

    build-in properties
    ANT提供了访问系统properties的机制,也就是build-in properites,所谓系统properties,可以查看System.getProperties返回的值,以下是我的机器上的系统properties(只列出了一部分)
    -- listing properties --
    java.runtime.name=Java(TM) 2 Runtime Environment, Stand...
    sun.boot.library.path=D:/jdk1.3.1_03/jre/bin
    java.vm.version=1.3.1_03-b03
    java.vm.vendor=Sun Microsystems Inc.
    java.vendor.url=http://java.sun.com/
    path.separator=;
    java.vm.name=Java HotSpot(TM) Client VM
    file.encoding.pkg=sun.io
    java.vm.specification.name=Java Virtual Machine Specification
    user.dir=G:/server
    java.runtime.version=1.3.1_03-b03
    java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment
    os.arch=x86
    java.io.tmpdir=C:/TMP/
    line.separator=
    这些build-in properties可以直接象property那样引用,例如:${java.home}

    除此之外,ANT还提供了自身的build-in properties:
    basedir
    ant.file
    ant.version
    ant.project.name
    ant.java.version


    2、Environment环境变量
    假设你根据你的工作环境配置了下面的property:
    <property name="xalan.home" value="C:/java/xalan-j_2_1_0"/>
    显然你的buildfile到其他开发人员的环境下面还能继续有效的可能性很小,因为其他人的xalan很可能在其他目录,使用Environment环境变量可以解决这个问题
    <property environment="env"/>
    <property name="xalan.home" value="${env.XALAN_HOME}"/>
    <target name="checkXalanHome" unless="env.XALAN_HOME">
    <fail message="XALAN_HOME must be set!"/>
    </target>
    关键是:
    <property environment="env"/>
    设置了这个属性之后,以后可以直接引用环境变量,只要前面加一个env.的前缀就可以了。


    3、fileset文件集
    fileset 表示了一套文件的集合,通常定义为project-level,ANT的task可以通过显式(explicit)的方式来引用或者直接嵌套 fileset,如果是直接嵌套,这个时候fileset是task-level的,很多ANT的task都支持隐式(implicit)的 fileset,也就是说这些TASK支持fileset的所有属性和嵌套的子元素,和filelist不同的是fileset所表示的文件必须存在。 Fileset可以定义为target-level的,并通过他们的id来引用。
    fileset支持以下常用的属性(只列出常用的,其他的请参考官方文档):
    attribute       |  description
    ----------------|------------------------------------------------
    id              |可选,定义了id将来就可以引用了
    dir             |必须指定,用于指定文件所在的目录
    excludes        |可选,用于指定在dir指定的目录下那些不应该包括进来的文件,内容是逗号分割的文件模式(file pattern)。
    excludesfile    |跟excludes类似,区别是只能包括单独的文件模式(不能用逗号分隔多个文件模式),通常情况下我习惯使用excludes,因为excludes也包括了excludesfile的功能
    includes        |可选,用于指定在dir指定的目录下那些需要包括进来的文件,内容是逗号分割的文件模式(file pattern)。
    includesfile    |跟includes类似,区别是只能包括单独的文件模式(不能用逗号分隔多个文件模式),通常情况下我习惯使用includes,因为includes也包括了includesfile的功能

    除了上面的属性之外,fileset还可以嵌套多个(0...n)以下的patternset元素
    <exclude> , <include> , <patternset> , <excludesfile> , <includesfile> .
    关于patternset的用法,我会在patternset这个部分专门总结。

    例子:
    <fileset id="sources1" dir="src"
    includes="**/*.java"
    excludes="**/test/**/*.java">
    </fileset>
    等价于
    <fileset id="sources2" dir="src">
    <include name="**/*.java"/>
    <exclude name="**/test/**/*.java"/>
    </fileset>
    等价于
    <fileset id="sources3" dir="src">
    <patternset>
    <include name="**/*.java"/>
    <exclude name="**/test/**/*.java"/>
    </patternset>
    </fileset>
    也等价于
    <patternset id="non.test.source">
    <include name="**/*.java"/>
    <exclude name="**/test/**/*.java"/>
    </patternset>
    <!-- later in the same buildfile -->
    <fileset id="sources4" dir="src">
    <patternset refid="non.test.source"/>
    </fileset>

    4、patternset模式集
    fileset 将文件合成一个组,patternset将模式合成一个组,它们的概念很接近,其实fileset依赖于patternset来选择文件,patternset可以表达为target-level,然后通过它的id来引用,也可以直接嵌套在fileset下面,那些支持隐式 (implicit)的fileset的task也支持嵌套的patternset。
    patternset支持includes, excludes, includesfile,excludesfile四个属性,这跟fileset的用法一样,还支持以下的嵌套的元素:
    0..n 个嵌套的 <include>和<exclude>元素,它们支持以下属性
    attribute       |  description
    ----------------|------------------------------------------------
    name            |必须指定,内容为相应的include和exclude的模式。
    if              |可选,和target的if属性的用法一样
    unless          |可选,和target的unless属性的用法一样

    0..n 个嵌套的 <includesfile> 和 <excludesfile> 元素,它们支持以下属性:
    attribute       |  description
    ----------------|------------------------------------------------
    name            |必须指定,内容为相应的include和exclude的模式,但是只能是单个
    if              |可选,和target的if属性的用法一样
    unless          |可选,和target的unless属性的用法一样

    例子:
    patternset的定义
    <patternset id="xml.files">
    <include name="**/*.dtd,**/*.xml,**/*.xslt"/>
    </patternset>

    patternset的引用
    <fileset dir="${src.dir}">
    <patternset refid="${xml.files}"/>
    </fileset>

    5、path路径
    path这个DataType除了单独定义之外,还可以是某个元素的attribute也可以是这个元素下面一个嵌套的元素,最常用的是classpath这个形式,但是也用于其他用途。
    当作为XML元素使用的时候,path的用法非常的灵活,path支持以下attribute(搞清楚元素和属性的区别)
    attribute       |  description
    ----------------|------------------------------------------------
    location        |可选,表示单个文件或者单个路径,它跟path的区别是数量上的
                    |path可以表示多个文件和路径
    path            |可选,路径或者文件列表,用;或者:作为分隔符
    refid           |可选,引用其他的path的id,如果在buildfile里面会经常用到同样的path,
                    |可以将其定义为一个公用的,然后在使用到这个path的地方通过refid来引用,
                    |如果refid被指定了,path的其他attribute和其嵌套的元素都是禁止使用的。
    path支持的嵌套元素如下:
    0..n 个嵌套的<pathelement> pathlelement定义在路径下的一个或者多个文件, pathelement支持location和path这两个attribute,用法和path元素一样。(注意,他们之间可以互相嵌套,功能是非常强大滴)
    0..n 个嵌套的<fileset> 
    0..n 个嵌套的<path>

    classpath是path元素的一个针对类路径的特殊的元素,具有和path用样的使用语法,但是使用的场合主要是<javac>task下面。

    例子:
    <classpath>
    <pathelement path="${builddir}"/>
    </classpath>
    等价于
    <classpath path="${builddir}"/>

    <classpath> (合并了多个路径)
    <pathelement path="${builddir1}"/>
    <pathelement path="${builddir2}"/>
    </classpath>
    等价于
    <classpath path="${builddir1};${builddir2}"/>

    <classpath>
    <pathelement path="${builddir}"/>
    <fileset dir="${libdir}" includes="**/*.jar"/>
    </classpath>

    <path>
    <pathelement location="${libdir}/servlet.jar"/>
    <pathelement location="${libdir}/logging.jar"/>

    <pathelement path="${builddir}"/>
    <pathelement path="${utilpath}"/>
    </path>


    五、目标驱动的ANT
    为什么说目标驱动ANT呢,这其实是我的学习方法,也就是说我使用ANT来做什么,而“做什么”就是我们的目标,也就是buildfile里面的 target,只学习跟我们的目标有关的部分,其他的留到用的时候再去查阅有关资料,对于大部人来说,学习ANT的目的是为了更好的辅助项目的创建 (build),而不是要成为ANT的专家。
    就我目前的工作内容出发,我需要ANT协助我完成编译,测试,打包,发布,生成文档,有些时候,还会使用到版本控制系统。

    组织一个良好的目录结构是完成一次成功的build所必须的,apache的开源项目的目录结构提供了事实上(de facto)的标准,如非特殊需要,我们可以直接采取那样的目录结构。
    project_home               #项目所在目录
                /src           #源码
                    /java      #Java主程序代码
                    /test      #Java测试程序代码
                    /conf      #manifest声明文件
                /lib           #库文件目录
                /doc           #项目有关说明文档,如果是开源项目,通常该目录下是相应的web content
                    /api       #生成项目的Java API文档的地方
                /build         #用于创建的临时目录
                      /classes #编译的结果保存在该目录
                /dist          #用于发布的临时目录,通常会将build/classes下的文件打包成jar,保存在该目录下
                README         #项目的说明文件
                RELEASE        #项目的发布文件
                LICENSE        #项目的license文件
                
    下面是一个和目录有关的配置的例子:
    <project name="helloworld" default="all" basedir=".">

     <property name="src.dir" value="src"/>
     <property name="lib.dir" value="lib"/>
     <property name="build.dir" value="build"/>
     <property name="dist.dir" value="dist"/>
     <property name="doc.dir" value="doc"/>
     
     <path id="compile.classpath">
      <pathelement dir="${lib.dir}"/>
     </path>
     
     <path id="test.classpath">
      <pathelement refid="compile.classpath"/>
      <pathelement dir="${build.dir}/classes"/>
     </path>
     
     <!-- the following  targets are ignored -->
     
    </project>

    编译<javac>:

    1。编译器的选择
    对于<javac>,除了classic(JDK 1.1/1.2)和modern(JDK 1.3/1.4/1.5),还有不同的编译器可以选择,例如:jikes,jvc,kjc,gcj,sj等等,不过我还没有用过这些编译器,<javac>默认的编译器是你用来运行ANT的JDK 1.X所带的编译器,如果你想使用自己的编译器,需要如下声明,ANT运行<javac>的时候会自动用你配置的编译器来编译:
    <property name="build.compiler" value="jikes"/><!-- 使用jikes编译器 -->

    2。<javac>的语法
    编译可以说是ANT里面最基本的任务,首先回顾一下命令行下进行编译的命令:
    c:/hellworld>javac -d build/classes
                       -classpath %CLASSPATH%;lib/outlib.jar
                       -sourcepath src
                       -g
    下面是常用的<javac>语法列表,并附上对应到javac命令的参数
    srcdir Java文件所在的目录,相当于javac命令的-sourcepath参数,srcdir也是<javac>的隐式(implicit)的FileSet,因此srcdir支持FileSet的所有特征,有关FileSet的用法请参考前面。
    destdir classes文件输出的目录,相当于javac命令的-d参数
    debug 生成并输出调试信息,debug="yes"相当于javac命令的-g参数,debug="no"相当于javac命令的-g:none参数
    deprecation 输出对于那些使用了deprecation的API的源文件的位置,默认是off,deprecation="on"相当于javac命令的-deprecation参数
    optimize 优化,默认是off,optimize="on"相当于javac命令的-o参数
    fork 使用外部的JDK编译器来运行javac,默认是no,采用yes可以取得更好的效率,当然对机器的要求也高
    failonerror 如果编译错误,build是否继续,默认是true
    compiler 类似于全局的属性build.compiler,不过这里是<javac>的attribute而已,直接指定<javac>的编译器,用法和build.compiler一样。
    还有很多attribute,请参考官方文档吧。

    补充两点:
    <javac>支持隐式的FileSet,支持<fileset>的所有attribute,不同的是dir在<javac>里面是srcdir。
    <javac> 的srcdir, classpath, sourcepath, bootclasspath, 和extdirs attributes都是path-like 结构,可以完全通过嵌套的 <src>, <classpath>, <sourcepath>, <bootclasspath> and <extdirs> 元素来代替。

    例子:
    <javac destdir="${build.classes.dir}"
           debug="${build.debug}"
           includeAntRuntime="yes"
           srcdir="${sirc.dir}">
           <classpath refid="compile.classpath"/>
           <include name="**/*.java"/>
    </javac>

    测试<junit>和<junitreport>:
    JUnit是事实上(de facto)的Java单元测试工具,ANT集成了JUnit,可以在build过程中执行test suite,并捕获结果和生成报表,关于JUnit的用法,请查阅有关资料,这里只总结ANT怎么将JUnit集成到Build里面去的方法。
    下面给出一些简单的例子,先有个感性的认识,后面在详细讲解一些常用的参数,<junit>用法非常简单,例如:
    <junit>
     <classpath refid="test.classpath"/>
     <test name="myexample.Example1Test"/>
    </junit>
    为了捕获测试结果,需要使用<format>,例如:
    <junit printsummary="false" haltonfailure="true">
     <classpath refid="test.classpath"/>
     <formatter type="brief" usefile="false"/>
     <test name="myexample.Example1Test"/>
    </junit>
    <junit>还支持运行多个TestCase
    <junit fork="yes">
     <classpath refid="test.classpath"/>
     <batchtest>
      <fileset dir="${src.test.dir}">
       <include name="**/*Test*.java"/>
       <exclude name="**/AllTests.java"/>
      </fileset>
     </batchtest>
    <junit>


    下面讲讲junit支持的一些参数Parameters
    attribute       |  description
    ----------------|------------------------------------------------
    fork            |在独立的JVM里运行测试,可以参考javac,java的fork属性,默认是off
    haltonerror     |测试的时候如果发生错误,是否停止整个build进程,默认是off
    haltonfailure   |测试的时候如果某个测试失败了,是否停止整个build进程,默认是off
    下面是JUnit支持的一些嵌套的元素Nested Elements
    1。<classpath> 用法参考<path>部分
    2。<test> 运行单个TestCase
    <test>支持以下参数Parameters
    attribute       |  description
    ----------------|------------------------------------------------
    name            |测试的类的全名,必须指定
    fork            |在独立的JVM里运行测试,可以参考javac,java的fork属性,默认是off
    haltonerror     |测试的时候如果发生错误,是否停止整个build进程,默认是off
    haltonfailure   |测试的时候如果某个测试失败了,是否停止整个build进程,默认是off
    todir           |测试结果的输出目录,默认是当前目录
    outfile         |测试结果的输出的文件名,默认是TEST-name,全文件名取决于<formatter的定义>
    注意,<test>支持if,unless参数,还支持嵌套的<formatter>

    3。<batchtest> 可运行多个TestCase,并且支持<fileset>定义的所有TestCase
    attribute       |  description
    ----------------|------------------------------------------------
    fork            |在独立的JVM里运行测试,可以参考javac,java的fork属性,默认是off
    haltonerror     |测试的时候如果发生错误,是否停止整个build进程,默认是off
    haltonfailure   |测试的时候如果某个测试失败了,是否停止整个build进程,默认是off
    todir           |测试结果的输出目录,默认是当前目录

    注意,<batchtest>是批处理测试,因此不在支持具有单个测试含义的参数,如name,outfile

    4。<formatter>用来控制输出结果的格式,支持下面的参数
    attribute       |  description
    ----------------|------------------------------------------------
    type            |目前支持xml,plain,brief三种格式,plain和brief都是text格式,
                    |但是plain提供了更加详细的统计信息
    extension       |输出文件的扩展名
    usefile         |输出结果是否输入到文件,默认为true 
    注意,我们可以同时使用多次<formatter>,这样可以控制多个输出结果,例如
    <formatter type="brief" usefile="false"/>
    <formatter type="xml"/>
    在控制台显示了测试结果的综合信息,同时把详细的测试结果写入了XML文件
                 

    上面只列出了一些常用的参数和元素,再结合前面的例子应该可以应付基本的测试了。


    <junitreport>的用法等待添加

    发布
    让我们先看看发布前必须做的一些准备工作:
    1。撰写文档。
    2。撰写和平台相关的自启动脚本(bootstrap script),批处理文件(batch file) ,或者程序。
    3。撰写安装脚本,使用安装工具。
    4。检查版本控制系统中和项目相关的源码,文档,以及其他资料。
    5。将版本控制系统中的源码打上标签。
    6。运行一次完整的build。
    7。运行一次完整的测试。
    8。将软件打包成适当的形式,用于发布和安装。
    对于打包这个步骤,如下图
    Data files          Java source               Documentation 
         |                   |                        |         
         |              _____|_____                   |         
         |             |           |                  |         
         |          <javac>     <javadoc>             |                       
         |             |           |                  |         
         |_____________|           |__________________|         
                |                            |
               jar                           |         
                |                            |
              jar file                       |
                |____________________________|                                               
                             |
                             |
                       <zip><gzip><tar>
                             |
                             |
                        Distribution
                           package          
    将源码和数据文件打包成JAR,将文档和生成的文档保存在某个目录,然后将整体打包zip或者tar,为不同的平台提供最终的版本以供下载,这就是打包的过程。

    打包和发布的一个通用的过程是复制和移动文件的过程,在深入打包的细节之前,有必要总结一下ANT里面和复制,移动以及删除有关的任务(这部分内容大部分来自官方文档,经过翻译和整理)。


    <copy>
    <copy>将文件或者FileSet复制到一个新的文件或者目录。FileSet用于指定用于复制的文件集合,如果使用了FileSet,<copy>的todir必须指定一个值,<copy>支持的常用的attribute如下:
    attribute |  description
    ----------|------------------------------------------------
    file      |  要复制的文件
    tofile    |  复制到新的文件的文件名
    todir     |  复制到新的目录的目录名
    overwrite |  默认值为false,也就是只有当被复制的文件比目标文件新的时候才复制,
              |  如果需要强制覆盖目标文件,需要将overwrite设置为true

    <copy>嵌套<fileset>用于选择用于复制的文件集合,这个时候需要指定todir
    下面的例子均选自官方文档
    例一
      <copy file="myfile.txt" tofile="mycopy.txt"/>

    例二

      <copy file="myfile.txt" todir="../some/other/dir"/>

    例三

      <copy todir="../new/dir">  <copy>嵌套<fileset>用于选择用于复制的文件集合,这个时候需要指定todir
        <fileset dir="src_dir"/>
      </copy>

    例四

      <copy todir="../dest/dir">
        <fileset dir="src_dir">
          <exclude name="**/*.java"/>
        </fileset>
      </copy>

    例五

      <copy todir="../dest/dir">
        <fileset dir="src_dir" excludes="**/*.java"/>
      </copy>

    <move>
    <move>跟<copy>的区别是移动而不是复制,语法跟<copy>一样,这里不多写了,只提供一些例子:

    下面的例子均选自官方文档
    例一

      <move file="file.orig" tofile="file.moved"/>

    例二

      <move file="file.orig" todir="dir/to/move/to"/>

    例三

      <move todir="new/dir/to/move/to">
        <fileset dir="src/dir"/>
      </move>

    例四

      <move todir="some/new/dir">
        <fileset dir="my/src/dir">
          <include name="**/*.jar"/>
          <exclude name="**/ant.jar"/>
        </fileset>
      </move>

    <delete>删除单个文件,单个目录,多个文件,多个目录,支持FileSet,通常在清除build产生的临时文件和目录的时候会用到<delete>,一个典型的buildfile一般都会有一个名叫clean的target。
    <delete>支持的最常见的attribute如下:
    attribute |  description
    ----------|------------------------------------------------
    file      | 指定文件,<delete file="somefile"/>
    dir       | 指定目录,<delete dir="somedir"/>
    可以嵌套<fileset>,但是如果没有指定FileSet,file和dir其中之一必须指定。
    下面的例子均选自官方文档
    例一
    <delete file="/lib/ant.jar"/>
    例二
    <delete dir="lib"/>
    例三
      <delete>
        <fileset dir="." includes="**/*.bak"/>
      </delete>
    例四
      <delete includeEmptyDirs="true">
        <fileset dir="build"/>
      </delete>
    例五
      <delete includeemptydirs="true">
        <fileset dir="build" includes="**/*"/>
      </delete>

    补充:关于复制,移动,删除,还有一个重要的用法就是filter,不过我用到的机会不多,所以没有怎么研究过,有关详细的资料请查阅官方文档。

    发布前还应该准备文档,特别是javadoc文档,<javadoc>是一个非常复杂的task,一共有50多个attribute,幸好只有三个attribute是必须的,那就是sourcepath,sourcefiles,sourcepathref,destdir,对于 sourcepath,sourcefiles,sourcepathref只需要指定其中一个,如果都没有指定,那么必须提供嵌套的<sourcepath>, <fileset> 或者 <packageset>,从字面上很容易理解sourcepath,sourcefiles,sourcepathref是源文件所在的目录,而destdir是生成的javadoc API所在的目录。
    下面是一些我们常用的attribute,没有必要去死记这些attribute,最好的学习方式是理解它们的意义,然后写一个template,再用到的时候根据需要修改这个template就可以了:
    attribute       |  description
    ----------------|------------------------------------------------
    sourcepath      |源文件目录,可用嵌套的<sourcepath>代替
    sourcefiles     |逗号分割的文件列表,可用嵌套的<source>代替
    destdir         |输出文件所在的目录,通常我们习惯将结果保存在doc/api下
    packagenames    |逗号分割的java包列表,可用嵌套的<package>代替
    packageList     |指定一个文件,文件内容是<javadoc>需要处理的包的列表
    classpath       |指定class文件所在的位置,可用嵌套的<classpath>代替
    use             |生成class和package的用法
    version         |生成@version的信息
    author          |生成@author的信息
    windowtitle     |生成的doc的浏览的窗口的标题
    header          |每一页的header信息
    footer          |每一页的footer信息
    bottom          |每一页的bottom信息
    nodeprecated    |不生成@deprecated的信息
    常见的可以嵌套的参数如下:
    packageset,fileset,package,excludepackage,source,doctitle,header,footer,bottom,它们的具体用法请参考官方文档。

    <javadoc> 的sourcepath, classpath 和 bootclasspath是path-like机构也就是完全可以用嵌套的<sourcepath>, <classpath> 和 <bootclasspath>来代替

    给几个例子:
    例一
    <javadoc packagenames="com.dummy.test.*"
               sourcepath="src"
               defaultexcludes="yes"
               destdir="docs/api"
               author="true"
               version="true"
               use="true"
               windowtitle="Test API">
               <classpath refid="compile.classpath"/>
    </javadoc>

    例二
    <javadoc author="true"
             destdir="${javadoc.dir}"
             packagenames="org.example.helloworld.*"
             sourcepath="src"
             use="true"
             version="true"
             windowtitle="Helloworld api spec"
             private="true">
             <classpath refid="compile.classpath"/>
    </javadoc>

    例三
     <javadoc
               destdir="docs/api"
               author="true"
               version="true"
               use="true"
               windowtitle="Test API">

        <packageset dir="src" defaultexcludes="yes">
          <include name="com/dummy/test/**" />
          <exclude name="com/dummy/test/doc-files/**"/>
        </packageset>

        <doctitle><![CDATA[<h1>Test</h1>]]></doctitle>
        <bottom><![CDATA[<i>Copyright &#169; 2000 Dummy Corp. All Rights Reserved.</i>]]></bottom>
        <tag name="todo" scope="all" description="To do:" />
        <group title="Group 1 Packages" packages="com.dummy.test.a*"/>
        <group title="Group 2 Packages" packages="com.dummy.test.b*:com.dummy.test.c*"/>
        <link offline="true" href="http://java.sun.com/products/jdk/1.2/docs/api/" packagelistLoc="C:/tmp"/>
        <link href="http://developer.java.sun.com/developer/products/xml/docs/api/"/>
      </javadoc>

    准备文档的内容除了javadoc之外,那些install script和其他document也是内容之一,将其复制到待打包的目录。
    例如
    <target name="prepare-docs" depends="init">
     <property name="readme.file" location="readme.txt"/>
     <copy file="${readme.file}" todir="${doc.dir}"/>
     <copy file="${readme.file}" tofile="${doc.dir}/README"/>
    </target>
    因为windows平台的文本文件行结束标志为/r/n,而unix平台的行结束标志为/n,所以还要考虑平台之间的纯文本文件的格式问题,详情请查阅有关资料。

    接下来是准备发布的库文件,常见的库文件的发布形式是打包之后的格式,如JAR,WAR,EAR,ZIP等等,
    对我来说最常用的是JAR,JAR文件是基于ZIP格式的,JAR文件本质上就是ZIP文件,但是多了一个可选择的META-INF目录,JAR文件通常通过命令行jar工具来创建,JAR文件不只是是java class文件和resource文件简单的进行打包的结果,JAR文件是应用程序创建的一个块(block),而META-INF目录,如果存在的话,里面保存了包和扩展的配置数据,如安全,版本,扩展和服务等等。在META-INF目录下最常见的文件就是MANIFEST.MF,其他的文件请查阅 SUN关于JAR的规范。
    下面重点讲一下ANT的<jar>的用法,<jar>实际上就是将一些文件集合打包成JAR的格式,这些文件打包成JAR之后,文件原来的permission,也就是访问权限不会保留在JAR里面,同样<jar>也支持隐式的 FileSet,basedir就是指定需要用于打包的文件所在的目录,因为JAR格式包含了manifest,如果没有提供的话,ANT会自动提供一个简单的manifest文件,对于已经存在的目标文件,如果再次进行打包,update参数可以控制是否覆盖已经存在的文件,下面是<jar>支持的常见的attribute
    attribute       |  description
    ----------------|------------------------------------------------
    destfile        |目标文件,必须指定
    basedir         |用于打包的文件所在的目录
    compress        |默认为true,表示打包的同时还对文件进行压缩
    manifest        |指定要使用的manifest文件
    update          |默认为false,该attribute用于指示jar在目标文件
                    |已经存在的情况下是否更新或者覆盖目标文件
    支持的常见的嵌套的元素有manifest,fileset
    于manifest的格式,一组name:value叫做section,section之间通过空行来隔开,manifest的配置文件就是由 section组成的,这里简单列出META-INF/MANIFEST.MF文件里面常见的一些attribute:Manifest- Version,Created-By,Main-Class,Specification-Title,Specification- Version,Specification-Vendor,Implementation-Title,Implementation-Version ,Implementation-Vendor ,Sealed等等,至于这些attribute的解释请查阅官方文档。

    大部分情况下,ANT自动生成的JAR的manifest已经足够了,如下:
    Manifest-Version:1.0
    Created-By:Apache Ant 1.5
    但是如果你面临以下情况的时候,需要自己提供manifest:

    以下例子来自ANT官方手册:
    例一
      <jar destfile="${dist}/lib/app.jar" basedir="${build}/classes"/>
    ${dist}/lib directory.
    例二
      <jar destfile="${dist}/lib/app.jar"
           basedir="${build}/classes"
           excludes="**/Test.class"
      />
    ${dist}/lib directory. Files with the name Test.class are excluded.
    例三
      <jar destfile="${dist}/lib/app.jar"
           basedir="${build}/classes"
           includes="mypackage/test/**"
           excludes="**/Test.class"
      />
    ${dist}/lib directory. Only files under the directory mypackage/test are used, and files 例四
      <jar destfile="${dist}/lib/app.jar">
        <fileset dir="${build}/classes"
                 excludes="**/Test.class"
        />
        <fileset dir="${src}/resources"/>
      </jar>
    例五
      <jar destfile="test.jar" basedir=".">
        <include name="build"/>
        <manifest>
          <attribute name="Built-By" value="${user.name}"/>
          <section name="common/class1.class">
            <attribute name="Sealed" value="false"/>
          </section>
        </manifest>
      </jar>
    关于manifest的用法请查阅官方手册,这里给出例五创建的MANIFEST.MF文件的最后内容:
    Manifest-Version: 1.0
    Built-By: conor
    Created-By: Apache Ant 1.5alpha

    Name: common/class1.class
    Sealed: false

    至于发布,其实通常很简单,就是将打包的jar,war,ear文件复制到应用服务器相应的目录下,只要掌握了<copy>就可以了。

  • 相关阅读:
    PAT乙级1008. 数组元素循环右移问题 (20)
    PAT乙级1007. 素数对猜想 (20)
    PAT乙级1006. 换个格式输出整数 (15)
    ubuntu mate 开机自动启动ssh服务
    ubuntu 修改网卡名称
    ubuntu 绑定固定ip
    ubuntu sogou 輸入法無法輸入文字,解決辦法【转载】
    select()函数小结【转载】
    listen函数小结
    python学习过程二(《python核心编程》第三章)
  • 原文地址:https://www.cnblogs.com/kms1989/p/2766770.html
Copyright © 2020-2023  润新知