<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Ant構建項目

      前言:

      Ant是java世界里第一個具有里程碑意義的項目構建工具。

      官網地址:http://ant.apache.org/

      文檔地址(Ant task):http://ant.apache.org/manual/index.html

      擴展工具地址(比如checkstyle和clover):http://ant.apache.org/external.html

      本文并不打算長篇累牘的描述Ant的使用方法,因為官網已經夠清楚,也有多位大神發過博文,這里只描述核心概念和一些基本實例,本文還會繼續編輯,希望大家多提寶貴意見。

       

      1,Ant的安裝

      從官網下載(http://ant.apache.org/bindownload.cgi)包,解壓到任意目錄,將bin目錄加入到環境變量,一般推薦使用英文路徑,并且先建立ANT_HOME的方式,以相對路徑設置環境變量。(這是個好習慣)

      2,Ant的核心概念

      構建文件是以XML文件來描述,這就意味著,你可以通過xsd查看所有的熟悉和配置方式,這非常有用,當然eclipse支持Ant提示。

      每個構建文件包含一個工程(project),其實是對一個項目概念的抽象,在Eclipse插件開發當中,也有這樣的抽象。

      每個工程包含若干個目標(target),目標是構成Ant構建文件的基本單元,在以后的Maven(另一種強大的項目管理工具)中類似于任務的概念。

      目標可以依賴于其他目標(depends),可以稱為項目內的依賴,Ant的目標可以構成鏈式,樹形,網狀的配置結構,目標的合理依賴可以使Ant文件有良好的擴展性和復用性。

      易于擴展,很多優秀項目已經實現與Ant的整合,比如checkstyle,junit,clover。

      目標的任務可以調用另一個工程的目標。(在一個項目中,可以引用另一個項目的配置,可以稱為項目級別的依賴)

      3,環境

      環境準備:Eclipse + Ant 1.7 + jdk1.5+

      項目準備:
          使用Eclipse建立一個maven目錄結構的項目或者普通的Java工程。
          普通java項目:在classpath上顯示的源目錄為src
          Maven目錄結構項目:普通java項目建立后,在classpath上刪除src源目錄,并在src目錄下新建類似于Maven工程的目錄結構。

      4,簡單Ant文件 

      說明:我不會對每一個標簽和屬性做解釋。最佳實踐都屬個人參考或總結,如有疏漏或錯誤,請高手指正并留下您的建議或指導。

      如下是一份簡單的通用構建的build.xml,并附上build.properties。

      1),資源文件的配置
         最佳實踐:首先,盡量較少的定義非關聯的屬性,而采用相對引用的方式。其次,盡量采用直觀而明確的名稱定義屬性,保持層次感和語義的完整性。
         順便提到一句,對于稍大項目的構建,如果是構建依賴的基礎包目錄,盡量應該采取按功能模塊或者相互依賴的關系分成獨立的目錄,在不破壞整個項目結構下,子項目能夠采用引入最少依賴的方式完成構建。
      build.properties:

      復制代碼
      #依賴資源包根目錄
      dependency.lib.path=../../web-libs
      dependency.resource.path=${dependency.lib.path}/resources
      #編譯源依賴包
      dependency.lib.main.path=${dependency.lib.path}/main
      #編譯測試依賴包
      dependency.lib.test.path=${dependency.lib.path}/test
      #工具包目錄
      dependency.lib.tool.path=${dependency.lib.path}/tool
      
      #源目錄 目前定義為 maven的默認目錄格式,方便之后介紹maven
      src.main.java=src/main/java
      src.main.resources=src/main/resources
      src.test.java=src/test/java
      src.test.resources=src/test/resources
      復制代碼

       
      2),構建文件的配置
         最佳實踐:target任務可以相互調用,我們采用depends屬性來控制這個依賴,如果依賴的比較復雜,那么我們的Ant文件可能會偏向于倒立的樹形結構,并且分支可能有所交叉,這從結構上并不是一個很好的腳本設計。
      由于Ant腳本是順序執行的,我們也最好依照這個特點,盡量避免target的交叉依賴,也就是完成一個target,和完成其它的target不要有太多的交集。還有一個非常重要的概念,很多target原則上都是需要清理的,我們應當樹立一種清理的意識,比如我們在新建一個目錄的時候,最好先清理這個目錄,因為你不清楚之前的一次構建是什么時候或者構建是否過期。

      build.xml:

      復制代碼
      <?xml version="1.0" encoding="UTF-8"?>
      <project name="common-web-demo" default="build" basedir=".">
       <description>common project automatic build script</description>
      
       <!--加載資源文件 -->
       <property file="build.properties" />
      
       <!-- 源目錄classpath-->
       <path id="main.classpath">
        <fileset dir="${dependency.lib.main.path}" includes="**/*.jar" />
       </path>
      
       <!--測試目錄classpath -->
       <path id="test.classpath">
        <fileset dir="${dependency.lib.main.path}" includes="**/*.jar" />
        <fileset dir="${dependency.lib.test.path}" includes="**/*.jar" />
        <fileset dir="${dependency.lib.tool.path}" includes="**/*.jar" />
       </path>
      
       <!--工具包classpath -->
       <path id="tool.classpath">
        <fileset dir="${dependency.lib.tool.path}" includes="**/*.jar" />
       </path>
      
       <!--工具包任務定義 -->
       <taskdef resource="net/sf/antcontrib/antlib.xml">
        <classpath refid="tool.classpath" />
       </taskdef>
      
       <target name="clean">
        <delete dir="${build.target.dir}" />
        <mkdir dir="${build.target.dir}" />
       </target>
      
       <!-- 主目錄編譯清理  -->
       <target name="main.clean">
        <delete dir="${build.target.bin.dir}" />
        <mkdir dir="${build.target.bin.dir}" />
       </target>
      
       <!-- 主目錄編譯  -->
       <target name="main.compile" depends="main.clean">
        <javac srcdir="${src.main.java}" destdir="${build.target.bin.dir}" source="1.5" target="1.5" debug="on">
         <classpath refid="main.classpath" />
        </javac>
        <copydir src="${src.main.resources}" dest="${build.target.bin.dir}" />
       </target>
      
       <!--主目錄打包 -->
       <target name="package.main.jar" depends="main.compile">
        <jar destfile="${build.target.dir}/${build.target.assembly.name}.jar">
         <fileset dir="${build.target.bin.dir}" />
        </jar>
       </target>
      
       <!-- === 循環構建 === -->
       <target name="build" depends="clean,package.main.jar" />
      </project>
      復制代碼


      xml編寫和標簽解釋:
      1,關于xml的編寫:在獨立標簽的編寫上,應該選擇傾向于<el .../> 而不是<el></el>,很多開源的Java框架都推薦前者的寫法,比如Spring。
      2,project:default屬性指定默認執行target(命令行), basedir定義構建目標路徑 basedir="."指定為當前項目路徑(SystemUtils.getUserDir()),其實對于構建一個獨立的項目或者一個模塊下的多個項目,這樣設定相對路徑是一個很好的做法。
      3,target(目標):一個build.xml最為核心的標簽,它可以調用其它的target,也可以調用一些擴展的target,target的名稱不可重復,在名稱編寫上也最好遵照某些規則建立分組,這樣在一個Ant文件的Outline視圖中可以很清晰的分辨結構和依賴關系。目前官網上的文檔的task of list命令基本上都屬于target的范疇。
      4,特別說明關于上述build.xml中工具包任務的定義,也就是antcontrib,它定義了一些非常有用的擴展功能,比如for for each,更有意思的是try catch,try catch真沒用過,有興趣的可以試試。

      task淺析:
      1,property :資源標簽,它能定義單個屬性,也可以加載多個屬性。定義單個:<property name="life" value="time" />;加載多個:<property file="build.properties"/>
      2,taskdef :定義擴展,定義擴展有兩種方式,一種是引入擴展標簽,也就是上面的xml當中的格式,另一種可以自定義為<typedef name="urlset" classname="com.mydomain.URLSet"/> 和具體的處理類掛鉤,后一種我不太了解。
      3,關于delete 與 mkdir一類有關文件的操作,包括fileset這類提供作用域的標簽。這些在Ant官網中介紹的非常詳細,命令眾多,就不一一列舉了(關于刪除命令,個人推薦delete,因為它的容錯性要高一些,在目錄不存在時不會有任何動作)。
      4,javac,Ant整個構建體系當中最為核心的task之一,比較值得關注的屬性有debug="on",source="1.5" ,前者打開debug,后者定義編譯級別。
      5,jar,打包命令,既然有jar,自然就有zip,war,ear了,它們大同小異。
      6,fock 一個重要的屬性,在javac junit很多相對比較耗資源的任務當中都有這個屬性,只要開啟,一般的意思就是采用獨立jvm執行編譯或運行測試等等之類,對于出現內存不足的錯誤很有效果。當然小項目不需要這么做,大一點的項目也可以通過調整Ant和虛擬機的內存來實現。

       

      5 相對復雜的Ant文件

         實現的功能:編譯,打包,測試運行,代碼檢查,覆蓋率檢查。

       1) 主要插件:
          junit
          checkstyle 
          clover
         
      2)build.properties

      復制代碼
      #依賴資源包根目錄
      dependency.lib.path=../../web-libs
      dependency.resource.path=${dependency.lib.path}/resources
      #編譯源依賴包
      dependency.lib.main.path=${dependency.lib.path}/main
      #編譯測試依賴包
      dependency.lib.test.path=${dependency.lib.path}/test
      #工具包目錄
      dependency.lib.tool.path=${dependency.lib.path}/tool
      
      test.jar.names=junit-4.10,spring-test-3.0.5.RELEASE
      
      #源目錄
      src.main.java=src/main/java
      src.main.resources=src/main/resources
      src.test.java=src/test/java
      src.test.resources=src/test/resources
      
      src.webapp.folder=src/main/webapp
      
      #構建主目錄
      build.target.dir=target
      #構建源編譯目錄
      build.target.bin.dir=${build.target.dir}/bin
      #構建測試編譯目錄
      build.target.test.bin.dir=${build.target.dir}/test-bin
      #Junit 測試記錄
      build.target.junit.record.dir=${build.target.dir}/test-record
      
      clover.db.dir=${build.target.dir}/clover-db
      
      #測試報告
      build.target.test.report.dir=${build.target.dir}/output
      junit.test.report.dir=${build.target.test.report.dir}/junit.report
      checkstyle.report.dir=${build.target.test.report.dir}/checkstyle.report
      clover.report.dir=${build.target.test.report.dir}/clover.report
      
      #構建目標包名稱
      build.target.assembly.name=common-web-demo
      復制代碼


      3)build.xml

      復制代碼
      <?xml version="1.0" encoding="UTF-8"?>
      <project name="common-web-demo" default="build" basedir=".">
       <description>common project automatic build script</description>
      
       <!--加載資源文件 -->
       <property file="build.properties" />
      
       <!-- 源目錄classpath-->
       <path id="main.classpath">
        <fileset dir="${dependency.lib.main.path}" includes="**/*.jar" />
       </path>
      
       <!--測試目錄classpath -->
       <path id="test.classpath">
        <fileset dir="${dependency.lib.main.path}" includes="**/*.jar" />
        <fileset dir="${dependency.lib.test.path}" includes="**/*.jar" />
        <fileset dir="${dependency.lib.tool.path}" includes="**/*.jar" />
       </path>
      
       <!--工具包classpath -->
       <path id="tool.classpath">
        <fileset dir="${dependency.lib.tool.path}" includes="**/*.jar" />
       </path>
      
       <!--工具包任務定義 -->
       <taskdef resource="net/sf/antcontrib/antlib.xml">
        <classpath refid="tool.classpath" />
       </taskdef>
      
       <target name="clean">
        <delete dir="${build.target.dir}" />
        <mkdir dir="${build.target.dir}" />
       </target>
      
       <!-- 主目錄編譯清理  -->
       <target name="main.clean">
        <delete dir="${build.target.bin.dir}" />
        <mkdir dir="${build.target.bin.dir}" />
       </target>
      
       <!-- 主目錄編譯  -->
       <target name="main.compile" depends="main.clean">
        <javac srcdir="${src.main.java}" destdir="${build.target.bin.dir}" source="1.5" target="1.5" debug="on">
         <classpath refid="main.classpath" />
        </javac>
        <copydir src="${src.main.resources}" dest="${build.target.bin.dir}" />
       </target>
      
       <!--主目錄打包 -->
       <target name="package.main.jar" depends="main.compile">
        <jar destfile="${build.target.dir}/${build.target.assembly.name}.jar">
         <fileset dir="${build.target.bin.dir}" />
        </jar>
       </target>
      
       <!-- === 循環構建 === -->
       <target name="build" depends="clean,package.main.jar">
      
       </target>
      
       <!-- 測試目錄清理 -->
       <target name="test.clean">
        <delete dir="${build.target.test.bin.dir}" />
        <mkdir dir="${build.target.test.bin.dir}" />
       </target>
      
       <!-- 測試編譯 -->
       <target name="test.compile" depends="test.clean">
        <javac srcdir="${src.main.java}" destdir="${build.target.test.bin.dir}" source="1.5" target="1.5" debug="on">
         <classpath refid="test.classpath" />
        </javac>
        <copydir src="${src.main.resources}" dest="${build.target.test.bin.dir}" />
        <javac srcdir="${src.test.java}" destdir="${build.target.test.bin.dir}" source="1.5" target="1.5" debug="on">
         <classpath refid="test.classpath" />
        </javac>
        <copydir src="${src.test.resources}" dest="${build.target.test.bin.dir}" />
       </target>
      
       <target name="test.record.clean">
        <delete dir="${build.target.junit.record.dir}" />
        <mkdir dir="${build.target.junit.record.dir}" />
       </target>
      
       <path id="test.run.classpath">
        <path refid="test.classpath" />
        <pathelement path="${build.target.test.bin.dir}" />
       </path>
      
       <!-- 運行Junit測試 -->
       <target name="junit.test" depends="test.compile,test.record.clean">
        <junit printsummary="true" fork="true" showoutput="true" dir="${basedir}">
         <classpath>
          <path refid="test.run.classpath">
          </path>
         </classpath>
         <formatter type="xml" />
         <batchtest fork="true" todir="${build.target.junit.record.dir}">
          <fileset dir="${build.target.test.bin.dir}">
           <include name="org/wit/ff/dao/*Test.class" />
          </fileset>
         </batchtest>
        </junit>
       </target>
      
       <!--生成測試報告目錄 -->
       <target name="report.clean">
        <delete dir="${build.target.test.report.dir}" />
        <mkdir dir="${build.target.test.report.dir}" />
       </target>
      
       <!-- 生成Junit報告目錄 -->
       <target name="junit.report.clean">
        <delete dir="${junit.test.report.dir}" />
        <mkdir dir="${junit.test.report.dir}" />
       </target>
      
       <!-- Junit 測試報告 -->
       <target name="junit.report" depends="junit.report.clean,junit.test">
        <junitreport todir="${build.target.junit.record.dir}">
         <fileset dir="${build.target.junit.record.dir}" includes="**/TEST-*.xml" />
         <report todir="${junit.test.report.dir}" />
        </junitreport>
       </target>
      
       <!-- checkstyle報告 -->
       <target name="checkstyle.report.clean">
        <delete dir="${checkstyle.report.dir}" />
        <mkdir dir="${checkstyle.report.dir}" />
       </target>
      
       <target name="checkstyle.report" depends="checkstyle.report.clean">
        <taskdef resource="checkstyletask.properties" classpath="${dependency.lib.tool.path}/checkstyle-5.3-all.jar" />
        <checkstyle config="${dependency.resource.path}/test_ii_checks.xml" failureProperty="checkstyle.failure" failOnViolation="false">
         <formatter type="xml" tofile="${checkstyle.report.dir}/checkstyle.xml" />
         <fileset dir="${src.main.java}" includes="**/*.java" />
         <fileset dir="${src.test.java}" includes="**/*.java" />
        </checkstyle>
        <style in="${checkstyle.report.dir}/checkstyle.xml" out="${checkstyle.report.dir}/checkstyle.html" style="${dependency.resource.path}/checkstyle.xsl" />
       </target>
      
       <!-- clover覆蓋率報告 -->
       <taskdef resource="cloverlib.xml" classpath="${dependency.lib.tool.path}/clover.jar" />
       <taskdef resource="cloverjunitlib.xml" classpath="${dependency.lib.tool.path}/clover.jar" />
      
       <target name="clover.db.init" >
        <delete dir="${clover.db.dir}" />
        <mkdir dir="${clover.db.dir}" />
       </target>
      
       <!-- clover數據庫,其實就是類執行信息存儲單元 -->
       <target name="with.clover" depends="clover.db.init">
        <clover-setup initstring="${clover.db.dir}/coverage.db">
         <statementContext name="log" regexp="^log\..*" />
         <statementContext name="iflog" regexp="^if \(log\.is.*" />
         <methodcontext name="main" regexp="public static void main\(String\[\] args\).*" />
        </clover-setup>
       </target>
      
       <target name="clover.report.clean" >
        <delete dir="${clover.report.dir}" />
        <mkdir dir="${clover.report.dir}" />
       </target>
      
       <!-- 生成Clover測試報告-->
       <target name="clover.report" depends="clover.report.clean">
        <!-- 非常簡潔的循環語句 -->
        <foreach target="clover.single.report" param="prop" list="html;xml" delimiter=";" />
       </target>
      
       <!-- 類型參數化的clover 報告 -->
       <target name="clover.single.report">
        <clover-report initstring="${clover.db.dir}/coverage.db">
         <current outfile="${clover.report.dir}/clover.${prop}" title="${build.target.assembly.name}" summary="true">
          <format type="${prop}" filter="log,iflog,main" />
          <fileset dir="${src.main.java}">
           <exclude name="org/wit/ff/dao/Base*.java" />
           <exclude name="org/wit/ff/dao/impl/Base*.java" />
           <exclude name="org/wit/ff/model/*Entity.java" />
           <exclude name="org/wit/ff/dao/*DAO.java" />
          </fileset>
          <fileset dir="${src.test.java}">
           <exclude name="org/wit/ff/test/Base*.java" />
          </fileset>
         </current>
        </clover-report>
       </target>
      
       <!-- html 格式clover 報告 -->
       <target name="clover.html">
        <clover-html-report outdir="clover_html" title="${build.target.assembly.name}" />
       </target>
      
       <!-- xml 格式clover 報告 -->
       <target name="clover.xml">
        <clover-report>
         <current outfile="coverage.xml">
          <format type="xml" />
         </current>
        </clover-report>
       </target>
      
       <!-- 運行所有目標-->
       <target name="test" depends="with.clover,build,junit.report,checkstyle.report,clover.report" />
      
      </project>
      復制代碼

       

      結束語:

        關于Ant依賴的思考

        通常情況下,當我們使用Ant構建項目的時候,我們需要依賴某個目錄下的包來完成構建,對于很多很多個使用Ant腳本構建的項目而言,可能整個依賴包的目錄會非常的龐大,雖然我們可以依據模塊將依賴分為多個子目錄,但是在實際的運行構建中,通常還是依賴了多余的jar,甚至有時候依賴了很多不需要的jar。實際上要解決這個問題,我們可以使用原生的Ant精確定義classpath,但是如果依賴過多,ant文件太過龐大,遠不如**/*.jar好管理,很多情況下,模塊的劃分也是為了更簡化classpath的定義。但是這些其實遠遠不夠,因為項目之間的依賴,如果也是用Ant來解決的話看起來會有些復雜了,也難以控制,因為你不得不修改腳本或者修改properties文件。并且會產生很多人為因素的問題,比如依賴包需要同步時還得拷貝。
        關于Ant的精確依賴,其實有一種方法。eg:首先將依賴配置到一個properties文件,然后通過Ant引入;其次使用antcotrib的定義任務for將所有的依賴拷貝到本地或者本項目的目錄之下(hudson在構建Ant項目的時候就是采取這種策略)。最后按照普通Ant腳本編寫就可以了。
        雖說如此,但Ant的依賴控制難以精確的確是事實,并且它作為一個自定義程序化構建的工具,還是需要不少的腳本開發工作。雖然Ivy(Spring源碼也采用這種構建方式)的出現也能對依賴進行很好的管理,但是一個更有力的工具,Maven顯然更具競爭力。

      一段旅程,遠去所有昨天的昨天,如記事本翻開新的一頁,永遠的不漏痕跡的把記憶藏在一片潔白中。然后絢爛的開始新的故事。
      posted @ 2025-10-31 20:03  沐春風-燕南飛  閱讀(2)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 日本一区不卡高清更新二区| 天堂av在线一区二区| 性欧美vr高清极品| 久久这里都是精品二| 日韩精品欧美高清区| 内射干少妇亚洲69XXX| 成人无码h真人在线网站| 国产精品亚洲二区在线播放 | 久久66热人妻偷产精品| 亚洲欧洲日产国码久在线| 南江县| 色一情一乱一区二区三区码| 国产精品无码久久久久AV| 国产精品福利自产拍在线观看| 日本丰满少妇裸体自慰| 精品久久久bbbb人妻| 亚洲欧美综合人成在线| 资中县| 亚洲女同精品久久女同| 色婷婷久久综合中文久久一本| 日韩中文字幕人妻精品| 国产午夜精品福利视频| 成av免费大片黄在线观看| 蜜桃av一区二区高潮久久精品| 7878成人国产在线观看| 中文字幕av高清片| 粉嫩蜜臀av一区二区三区| 日韩中文字幕国产精品| 亚洲国产一区二区三区亚瑟| 中文字幕乱妇无码AV在线| av激情亚洲男人的天堂| 台南县| 亚洲一区二区偷拍精品| 亚洲精品中文字幕二区| 337p粉嫩大胆色噜噜噜| 日韩无专区精品中文字幕| 99久久伊人精品综合观看| 朔州市| 国产gaysexchina男外卖| 国产SM重味一区二区三区| 国产精品亚欧美一区二区三区|