Apache Ant学习笔记之二(转载)

Apache Ant学习笔记之二

©作者:zdon

安装ant

        http://jakarta.apache.org/builds/ant/release/下载最新的编译好的ant发布版本,比如我下载的是apache-ant-1.6.1-bin.zip。将其解压到一个特定的目录,比如我将其解压到D:"apache-ant-1.6.1

       在系统环境变量中设ANT_HOMEANT_HOME 应该设置为 Ant 根目录,即包含 bin lib 目录的目录。在我的机器中为D:"apache-ant-1.6.1,在PATH变量中加入;%ANT_HOME%"bin,保存。确保 JAVA_HOME 环境变量设置为安装了 JDK 的目录,这样ANT就可以使用了。

    GNU/Linux上把以下配置加入/etc/profile中或者或者加入用户目录下的.bashrc文件中:

export ANT_HOME=/home/ant
export JAVA_HOME=/usr/java/j2sdk1.4.1
export PATH=$PATH:$JAVA_HOME/bin:$ANT_HOME/bin

运行ant

        没有指定任何参数时,Ant会在当前目录下查询build.xml文件。如果找到了就用该文件作为buildfile。要想让Ant使用其他的buildfile,可以用参数 -buildfile file,这里file指定了你想使用的buildfile

    使用ant -buildfile build.xml -logfile error.log来运行ant,就会将出错信息放入error.log中,方便查看。

       重要参数

       ·选项 -quite,告诉Ant运行时只输出少量的必要信息。而 -verbose,告诉Ant运行时要输出更多的信息。

       ·可以指定执行一个或多个target。当省略target时,Ant使用标签<project>default属性所指定的target

•build.xml文件基本结构

 

           <project>
              <property/>              
全局变量的定义
              <property/>...

             <target name="1">         任务组(tasks)
                <javac></javac>      
一项javac任务
                 ...
               <oneTask></ontTask>  
一项其它任务
            </target>

            <target name="2">
               <javac></javac>
                ...
               <oneTask></ontTask>
            </target>
        </project>

        配置文件由目标树构成。每个目标都包含了要执行的任务,其中任务就是可以执行的代码。每个目标都有唯一的名称和可选的相关性。目标相关性需要在执行目标任务列表之前执行。如:

  <target name="compile" depends="JUNIT">

 <mkdir dir="${build.dir}">
<javac srcdir="src/main/" destdir="${build.dir}">
<includ name="**/*.java/>
</javac>

</target>

        在本例中,mkdir 是目标 compile 的任务。mkdir 是建立在 Ant 中的一个任务,用于创建目录。同时,在执行 compile 目标中的任务之前需要先运行 JUNIT 目标。这种类型的配置可以让您在一个配置中有多个树。

•ant生成文件主要概念

project代表一个项目

 default:运行到名称为"dist"target(任务组)

 basedir:基准路径。

属性

一个project可以有很多的properties。可以在buildfile中用property task来设定,或在Ant之外设定。一个property有一个名字和一个值。property可用于task的属性值。这是通过将属性名放在"${"和"}"之间并放在属性值的位置来实现的。例如如果有一个property builddir的值是"build",这个property就可用于属性值:${builddir}/classes。这个值就可被解析为build/classes。 

Path-like Structures
你可以用":"";"作为分隔符,指定类似PATHCLASSPATH的引用。Ant会把分隔符转换为当前系统所用的分隔符。

          当需要指定类似路径的值时,可以使用嵌套元素。一般的形式是

<classpath>
<pathelement path="${classpath}"/>
<pathelement location="lib/helper.jar"/>
</classpath>
location
属性指定了相对于project基目录的一个文件和目录,而path属性接受逗号或分号分隔的一个位置列表。path属性一般用作预定义的路径--其他情况下,应该用多个location属性。

为简洁起见,classpath标签支持自己的pathlocation属性。所以:

<classpath>
<pathelement path="${classpath}"/>
</classpath>
可以被简写作:

<classpath path="${classpath}"/>
也可通过<fileset>元素指定路径。构成一个fileset的多个文件加入path-like structure的顺序是未定的。

<classpath>
<pathelement path="${classpath}"/>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
<pathelement location="classes"/>
</classpath>
上面的例子构造了一个路径值包括:${classpath}的路径,跟着lib目录下的所有jar文件,接着是classes目录。

如果你想在多个task中使用相同的path-like structure,你可以用<path>元素定义他们(与target同级),然后通过id属性引用--参考Referencs例子。

path-like structure可能包括对另一个path-like structurede的引用(通过嵌套<path>元素):

<path id="base.path">
<pathelement path="${classpath}"/>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
<pathelement location="classes"/>
</path>
<path id="tests.path">
<path refid="base.path"/>
<pathelement location="testclasses"/>
</path>

前面所提的关于<classpath>的简洁写法对于<path>也是有效的,如:

<path id="tests.path">
  <path refid="base.path"/>
<pathelement location="testclasses"/>
</path>
可写成:

<path id="base.path" path="${classpath}"/>

·         任务依赖

Antdepends属性只指定了target应该被执行的顺序-如果被依赖的target无法运行,这种depends对于指定了依赖关系的target就没有影响。Ant会依照depends属性中target出现的顺序(从左到右)依次执行每个target。然而,要记住的是只要某个target依赖于一个target,后者就会被先执行。

<target name="A"/>
<target name="B" depends="A"/>
<target name="C" depends="B"/>
<target name="D" depends="C,B,A"/>

假定我们要执行target D。从它的依赖属性来看,你可能认为先执行C,然后B,最后A被执行。错了,C依赖于BB依赖于A,所以先执行A,然后B,然后C,最后D被执行。一个target只能被执行一次,即时有多个target依赖于它。

·         注释用<!--   -->方式

·         一般一个ant生成文件应该完成

·         定义全局变量

·         初始化,主要是建立目录

·         编译  (已有)

·         打包为jar

·         建立API documentation

·         生成distribution产品 多种任务

最简单的例子:

  <?xml version="1.0" encoding="GB2312"?>
<!-- edited with XMLSPY v5 U (http://www.xmlspy.com) by zdon -->
<project name="testExampleProject" default="makejar" basedir=".">
 <description>
一个简单的创建项目的build练习</description>
 <!--
为此build设置全局化的属性 -->
 <!--
主要的系统环境属性-->
 <property environment="env"/>
 <property name="java.home" value="${env.JAVA_HOME}"/>
 <property name="ant.home" value="${env.ANT_HOME}"/>
 <!--
主要的app环境属性-->
 <property name="src" location="src"/>
 <property name="build" location="build"/>
 <property name="dist" location="dist"/>
 <!--app
用到的lib-->
 <property name="lib.dir" value="zdon-example/WEB-INF/lib"/>
 <path id="classpath">
  <!--
本项目用到的所有包,将在使用javac任务时引用-->
  <pathelement location="${build}"/>
  <pathelement path="${java.home}/lib/tools.jar"/>
  <pathelement path="${lib.dir}/classes12.jar"/>
  <pathelement path="${lib.dir}/servlet.jar"/>
  <pathelement path="${lib.dir}/commons-lang.jar"/>
  <pathelement path="${lib.dir}/commons-logging.jar"/>
  <pathelement path="${lib.dir}/commons-beanutils.jar"/>
  <pathelement path="${lib.dir}/commons-collections.jar"/>
  <pathelement path="${lib.dir}/log4j-1.2.8.jar"/>
  <pathelement path="${lib.dir}/cglib.jar"/>
  <pathelement path="${lib.dir}/struts.jar"/>
  <pathelement path="${lib.dir}/hibernate2.jar"/>
 </path>
 <!--
初始化任务 -->
 <target name="init" description="
初始化任务,创建编译目录">
  <!-- Create the time stamp -->
  <tstamp/>
  <!-- Create the build directory structure used by compile -->
  <mkdir dir="${build}"/>
  <mkdir dir="${dist}"/>
 </target>
 <target name="compile" depends="init" description="
编译源文件 ">
  <!-- Compile the java code from ${src} into ${build} -->
  <javac srcdir="${src}" destdir="${build}">
   <classpath refid="classpath"/>
  </javac>
 </target>
 <target name="makejar" depends="init,compile" description="
将所有编译好的文件打包 ">
  <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
  <jar jarfile="${dist}/boncexample-${DSTAMP}.jar" basedir="${build}"/>
 </target>
 <target name="clean" description="
清场">
  <!-- Delete the ${build} and ${dist} directory trees -->
  <delete dir="${build}"/>
  <delete dir="${dist}"/>
 </target>
</project>

基本任务参考:

1.引用外部的properties文件:

 <property file="${basedir}/build.properties" />

       这样做是为了方便工程人员或客户,使他们不必去看xml格式的build文件就可以做一些简单的配置工作。

2.CLASSPATH设置:

     <path id="classpath">
        <pathelement path="${jsdk_jar}"/>
        <fileset dir="${lib.dir}">
           <include name="**/*.jar"/>
        </fileset>
    </path>
等价于:CLASSPATH=/path/to/resin/lib/jsdk23.jar; /path/to/project/lib/*.jar;

3.创建与删除目录:

     <!-- create directories -->
    <mkdir dir="${build.src}"/>
    <mkdir dir="${build.dest}"/>

 <delete dir="${root}/dist/"/>

4.拷贝文件:

     <!-- copy src files -->
    <copy todir="${build.src}">
      <fileset dir="${src.dir}"/>
    </copy>

      单个文件

 <copy file="${deploy_path}/classjar.jar" todir="${root}/dist/"/>

5.进行编译:

  <target name="compile" depends="init" description="编译源文件 ">
  <!-- Compile the java code from ${src} into ${build} -->
  <javac srcdir="${src}" destdir="${build}">
   <classpath refid="classpath"/>
  </javac>
 </target>

        注意:编译时的CLASSPATH环境通过<classpath refid="classpath"/>
的方式引用了一个path对象。
6.
打包任务:jar

 对应用打包生成项目所写名的.jar文件
  <!-- ======================================= -->
  <!-- Creates the class package                                           -->
  <!-- ======================================= -->
  <target name="jar" depends="build">
    <jar jarfile="${lib.dir}/${name}.jar"
         basedir="${build.dest}"
         includes="**"/>
  </target>

               打包时使用时间戳

<target name="makejar" depends="init,compile" description="将所有编译好的文件打包 ">
  <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
  <jar jarfile="${dist}/boncexample-${DSTAMP}.jar" basedir="${build}"/>
 </target>

7.生成JAVADOC文档:

   <!--=================================== -->
  <!-- Creates the API documentation                          -->
  <!--=================================== -->
  <target name="javadoc" depends="build">
    <mkdir dir="${build.javadocs}"/>
    <javadoc packagenames="${packages}"
             sourcepath="${build.src}"
             destdir="${build.javadocs}"
             author="true"
             version="true"
             use="true"
             splitindex="true"
             windowtitle="${Name} API"
             doctitle="${Name}">
      <classpath refid="classpath"/>
    </javadoc>
  </target>

8.清空临时编译文件:

   <!--================================== -->
  <!-- Clean targets                                                       -->
  <!--================================== -->
  <target name="clean" depends="init">
    <delete dir="${build.src}"/>
    <delete dir="${build.dest}/org"/>
    <delete dir="${build.dest}/com"/>
    <delete>
      <fileset dir="${build.dest}" includes="**/*.class"/>
    </delete>
  </target>

9.测试任务:JUnit测试

     <!--  编译Junit文件 -->
    <target name="compilejunit" depends="compilesrc">
        <mkdir dir="${dist.junit}"/>
       
        <javac destdir="${dist.junit}" deprecation="on">
            <src path="${src.junit}"/>
            <classpath refid="classpath"/>
        </javac>       
    </target>

     <!--  运行junit  -->
    <target name="junit" depends="compilejunit">
        <mkdir dir="${doc.junitReport}"/>
        <copy todir="${dist.junit}">
            <fileset dir="junit_lib">
                <exclude name="**/*.jar"/>
            </fileset>

            <fileset dir="${src.code}">
                <include name="fog.hbm.xml"/>
            </fileset>
        </copy>
       
        <junit printsummary="yes" haltonfailure="no">
            <classpath>
                <path refid="classpath"/>
                <pathelement location="${dist.junit}"/>
            </classpath>
           
            <formatter type="brief" usefile="false"/>
            <formatter type="xml"/>
       
            <batchtest todir="${doc.junitReport}">
                <fileset dir="${dist.junit}" includes="**/*Test.class" />
            </batchtest>
        </junit>

        <junitreport todir="${doc.junitReport}">
            <fileset dir="${doc.junitReport}">
                <include name="TEST*-*.xml"/>
            </fileset>
            <report format="frames" styledir="${junit.styleDir}" todir="${doc.junitReport}"/>
        </junitreport>
    </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>

10.代码风格检查任务:CheckStyle

    <!-- 运行checkstyle检查代码规范 -->
    <target name="checkstyle" depends="init">
        <mkdir dir="${doc.checkstyleReport}"/>
       
        <checkstyle config="${checkstyle.config}">
            <fileset dir="${src.code}" includes="**/*.java"/>
            <formatter type="plain"/>
            <formatter type="xml" toFile="${doc.checkstyleReport}/checkstyle_report.xml"/>
        </checkstyle>
       
        <style in="${doc.checkstyleReport}/checkstyle_report.xml" out="${doc.checkstyleReport}/checkstyle_report.html" style="${checkstyle.xsl}"/>
    </target>

11.对数据库的操作:

     <!-- Oracle -->
    <target name="db_setup_oracle" description="Database setup for Oracle">
      <antcall target="check_params_results"/>
      <sql driver="oracle.jdbc.driver.OracleDriver"
       url="jdbc:oracle:thin:@192.168.0.1:1521:oa"
       userid="oa" password="oa"
       onerror="continue"
       print="yes"
       src="./demo.ddl"/>
    </target>

        注意:demo.ddl中写的是sql语句

12.运行JAVA程序:

      <!--(10)运行(args中是参数,随应用程序的具体情况有所不同)->
   <target name="simplesql"  depends="compile,db_setup_oracle">
    <java classname="examples.jdbc.oracle.simplesql"
      fork="yes" failonerror="yes"
      args="-user zrb
            -password zrb
            "/>

</target>

13.使用样式表来查看ant生成脚本:

     使用样式表来查看ant脚本,准备好这个样式表之后,可将其放在某个浏览器能够访问的地方。最后一步是向 Ant 脚本中加入指令。这些指令告诉浏览器在显示该文档的时候使用您的样式表。请将下面高亮显示的部分拷贝到 Ant 脚本的最上面,然后用您的样式表的位置替换 href 属性的值。

 <?xml version="1.0"?>
<?xml-stylesheet type="text/xsl"
    href="./examples/example2/ant2html.xsl"?>
<project name="Example2" default="main" basedir=".">

  <!--  The rest of the Ant script goes here.  --  >

</project>

       这样处理后就会有以下好处:

 

· 提供内容列表,方便用户迅速地找到脚本中相应的节

· 对使用到的所有属性和目标都按字母排序并分组

· 在目标及其所依赖的部分之间提供导航链接

· 显示构造出某个特定目标的任务

      另一个一个可以生成框架的样式表

14.使用ant来调用RetroGuard混淆器

 

    <target name="obfuscate" description="使用混淆器" depends="package">

        <java fork="yes" classname="RetroGuard" classpath="${obfuscate.lib}">

           <arg line="${build.dir.bin.jarunobfus}"/>

           <arg line="${build.dir.bin.jar}"/>

           <arg line="${obfuscator.script}"/>

        </java>

    </target>

      混淆器用的是Open Source的RetroGuard.在http://www.retrologic.com/下载

15.使用时间戳:

      一般是在init中的第一行写一个<stamp />,声明。说他是声明是因为如果你想在你的build脚本中使用当前的时间日期的话就必须指定这个,然后在后文中就可以使用${DSTAMP}这样标签了。〈未完

posted @ 2008-12-03 17:06  zhanlh  阅读(810)  评论(0编辑  收藏  举报