Jenkinsant介紹(學習筆記五)
轉載自:https://www.cnblogs.com/pixy/p/4792887.html
Ant的由來(序)
James Duncan Davidson當年用純Java開發Tomcat的時候,不僅想讓它跨平臺執行,還想要在不同的作業系統上都能夠進行開發和構建。這種較大的專案的編譯構建過程是很複雜,需要用到很多工具和指令碼(比如GNU make,Shell指令碼,批處理檔案等等)處理資源、處理依賴項、控制編譯過程、打包(Jar,War),某些特別的Java技術如EJB、RMI在編譯打包時還需要特別處理。James嘗試了很多工具和方案,最後的結論就是太TM難用了。
首先是慢。舉個例子,編譯java程式碼要用javac,javac其實就是包裝了下java用於編譯的Java工具類(JDK工具都是用純Java寫的,JDK目錄下的那些exe檔案實際上都是呼叫Java類來實現具體功能的)。但是用make,shell這些工具每次呼叫javac,都要開新程式建立新的VM例項,如果每編譯一個檔案呼叫一次javac,開銷就老大了,不慢才怪呢。呼叫命令後還必須要解析控制檯輸出資訊才能知道執行情況,更不可能使用Java提供的異常和錯誤資訊來確定執行狀態。
然後是累。make,shell指令碼要跨平臺太困難,在不同的系統上要用不同的版本;而且要編寫shell指令碼和make指令碼(make只是shell基礎上的語言擴充套件),得有linux程式設計基礎,門檻還是比較高的;這類指令碼編寫起來容易出錯(Makefile的tab問題能煩死人),難以除錯。總之,如果構建過程用了一堆這樣的指令碼,維護起來肯定是又煩又累。慢的問題還能通過一次編譯一批檔案來緩解,但這個問題可就無解了。
James實在受不了了,就自己用Java開發了一個小工具,就是Ant,用來編譯和打包Java專案。構建中用到JDK中工具時都是直接呼叫Java類,而不是從命令列呼叫,慢的問題就解決了。構建中直接向Java編譯類提供或獲取資料,編譯過程中有什麼問題,也能進行錯誤或異常處理。因為是用Java寫的,天然就是可以跨平臺的使用的。Ant從配置檔案中讀取資料來控制構建過程,剛開始的時候用Properties檔案,但是Properties檔案難用表達比較複雜的層次結構關係,當他把Ant解決方案設計成”工程-目標-任務”的層次結構時,改用XML作為構建配置檔案,XML檔案是很好理解和掌握的,學習門檻變得非常低。再後來又利用反射功能,支援自定義任務,Ant的功能就不再僅限於構建Java專案了,可以使用在更廣泛的場合。至此Ant就基本成型了。
James完成這個工具之後,自己用著很爽並且在網上共享,然後就沒怎麼再關注了,直到後來有一天忽然發現老多人都已經在用他的這個傑作了。James說他很慶幸當時沒有把精力一直花在這上面,否則可以能會不自覺的加入很多更本不必要的功能,讓Ant變得臃腫複雜,反而不好了。
這個故事除了說了Ant的來源和特點外,還有一點啟示:如果遇到問題,已有的工具都不能滿足需求,就應當另找一個。如果不存在這樣的工具,就自己動手建立一個。然後與大家共享,其他數以千計的人可能有著類似的難題。
第一章 Ant入門
ant的使用非常簡單:安裝好Ant後(最好配置Path環境變數),在構建檔案中(預設名字為build.xml)配置好構建任務,然後呼叫ant命令,配置的任務就開始執行了。
1.編寫構建檔案
建立一個用於編譯和打包Java專案的配置檔案build.xml(名字可以隨便起,如mybuild.xml,執行的時候用-f 選項指定這個檔案就可以):
這個配置檔案很好理解,用任何文字編輯器都能編寫,只要保證是一個合法的XML檔案並且用了正確的標籤和屬性,就可以使用ant執行。
根據這個配置檔案就可以看出。Ant把任何任務都分成了3層。
最頂層的Project
目標Target(可以在ant命令中呼叫的基本單位)。如clean, compile, jar 等,在命令列可以這樣呼叫:ant clean或 ant clean jar。Target之間可以存在依賴關係,一個Target執行前會先執行它依賴的那些Target。Project可以設定一個預設的Targe, ant命令中不指定任何target時就呼叫這個預設的。
任務Task。
各種Task可以執行各種不同的具體任務。如mkdir, delete, javac, jar等。Task可以分3種,核心任務和可選任務有100多種,常用的功能全都覆蓋了
核心Task。Ant內建的任務
可選任務。第三方提供的,把相應的Jar包放到Ant安裝目錄的lib目錄下就能使用。
自定義任務
Task詳細說明可以檢視官方文件:http://ant.apache.org/manual/tasklist.html
Ant檔案中還能用Property標籤配置屬性值,在定義之後的其他地方就可以引用,避免硬編碼。
所有的構建檔案都要有且只能有一個元素,其中至少要有一個 元素。project的defualt屬性沒有預設值,如果這個屬性沒有設定,不指定Target執行ant不會呼叫任何target。
2.執行Ant
ant命令語法如下,詳細選項說明列在後面。
ant [option [option…]] [target [target…]]
呼叫Ant時預設會在當前目錄中查詢預設的構建檔名:build.xml。
當然也可以用ant -f buildfile的方式手動指定構建檔案(-f, -buildfile, -file都是等效的)。
呼叫Ant時可以指定一個或多個要執行的Target。如果不指定就呼叫Project標籤default屬性中配置的預設Target(上面這個例子中就是compile目標)。
以上面的構建配置檔案為例,下面的幾種呼叫都可以:
ant呼叫預設構建檔案(build.xml)中的預設目標(compile)ant -f mybuild.xml jar呼叫構建檔案mybuild.xml中的jar目標ant clean jar呼叫預設構建檔案(build.xml)中的clean和jar目標。需要注意多個目標會按呼叫先後順序執行。如果呼叫ant jar clean就是先編譯打包(jar),然後全清理掉(clean),就白乾了。
Ant執行時會按執行順序顯示每個Target的名字,也會顯示每個任務的名字([任務名])和任務中輸出的資訊。直接呼叫ant的輸出結果為:
Buildfile: e:wsJavaAntDemouild.xml
clean:
[delete] Deleting directory e:wsJavaAntDemouild
prepare:
[mkdir] Createddir: e:wsJavaAntDemouild
[mkdir] Createddir: e:wsJavaAntDemouildclasses
[mkdir] Createddir: e:wsJavaAntDemouildlib
compile:
[javac] Compiling 2 sourcefilesto e:wsJavaAntDemouildclasses
jar:
[jar] Building jar: e:wsJavaAntDemouildlibantDemo.jar
all:
BUILD SUCCESSFUL
Total time: 0 seconds
3.檢視構建檔案中所有目標
構建檔案中的目標description屬性可有可無,除了方便人看外沒什麼卵用。有沒有這個屬性叫法也不一樣的(沒有實際作用),有該屬性的叫主目標,沒有的叫子目標。下面這個命令可以列出構建檔案中的所有目標和description資訊。
ant [-f BUILDFILE] -projecthelp
4.Ant命令選項
-h, -help 檢視幫助資訊
-p, -projecthelp 檢視構建檔案中的所有目標資訊
-version 顯示Ant版本
-q, -quiet 抑制並非由構建檔案中echo任務所產生的大多數輸出訊息
-S, -silent 只顯示Task輸出和構建失敗資訊
-v, -verbose 顯示構建過程中每個操作的詳細訊息, 不能和-debug同時使用
-d, -debug 顯示Ant和任務開發人員已經標誌位除錯資訊的訊息。不能與-verbose同時使用
-e, -emacs 對日誌訊息進行格式化,使其能夠Emacs的shell模式解析。具體就是列印任務訊息時不縮排也不輸出前面的 [任務名]
-diagnostics 顯示對除錯有用的資訊
-f , -buildfile , -file 指定一個構建檔案,而不是使用預設的build.xml
-D=通過命令列向構建過程中傳遞屬性值
-propertyfile 從property檔案中載入屬性值並傳遞到構建過程
-s , -find 指定Ant應當使用的構建檔案,如果指定的filename檔案在當前目錄中沒找到,就到父目錄中進行搜尋,直到到達檔案系統的根,還找不到則構建失敗。
-k, -keep-going 執行不依賴失敗目標的所有目標。
-lib 指定查詢jars和classes的目錄
-l , -logfile 將日誌重定向到指定檔案
-logger 指定一個類來處理Ant的日誌記錄。該類必須實現了org.apache.tools.ant.BuildLogger介面
-listener 為Ant設定一個監聽類,將其增加到Ant的監聽器列表中。Ant與IDE或其他程式整合時非常有用,後面會專門寫這個。
-inputhandler 指定用於處理輸入請求的類
-main 覆蓋Ant正常的入口點
-noinput 不允許互動式輸入
-autoproxy Java1.5+,使用OS的代理設定
-nice number
-nouserlib
-noclasspath
第二章 安裝和配置
基本使用
下載ant釋出包
解壓縮到一個目錄既可
將該目錄下的子目錄bin新增到PATH環境變數
高階配置
留坑待填….
第三章 構建檔案
構建檔案需要根據具體專案的特性編寫,不過同一型別的專案基本上是可以使用一套構建配置的。
Java提供了用於構建的Java工具庫,使用Java語言編寫Ant是最容易實現和維護的。XML有豐富的解析類庫,並且被開發人員廣泛使用,也能夠表達Ant的資料模型,使用XML作為構建檔案時最好的選擇。
XML是一種樹形的文件物件模型(DOM),其中的Project,Target等元素與Ant的模型元件相對應。
1.Ant的構建塊
Project(工程) 任何構建檔案的第一個元素必須是標籤,而且只能有一個。
name屬性 工程的名字,也是構建檔案的識別符號。
default屬性 執行Ant不指定Target時,預設執行的Target。可以設定成一個構建檔案中定義的Target名字。推薦預設Target顯示構建檔案的幫助資訊或者執行完成的構建。
basedir屬性 定義工程的根目錄,一般情況下都是” . “,也就是構建檔案所在的目錄(不是執行Ant命令是的目錄)。在一個多層次的專案中,basedir還可以定義不同的參考點。
Target(目標) 一個Project可以包含多個Target,一個總的任務過程可以拆分成幾個target,每個Target可以單獨呼叫。可以把target理解成能夠單獨執行的一個個步驟(階段)。具體怎麼拆分這個總任務,拆分粒度是粗還是細,把哪些Task放在哪幾個Target中,都是編寫構建檔案要考慮的問題。一般來說,粒度更小可以更靈活的組合,有些target失敗也不會影響另一些的執行。但是粒度也不能太小,太小了會很瑣碎不好維護。
name屬性
depends屬性
description屬性
前面的build.xml例項中,編譯打包拆成了兩個target,如果每次這兩個target都是一起被呼叫的,把他們放在一個target中也是可以的。
Task(任務) 任務是構建檔案中的最小構建單位。通過Target把一個總過程組織成了幾個大的Target目標(步驟),但是Target並不做任何具體的工作,Target下面有包含一些Task,所有的具體工作都是靠這些task來完成。Ant提供非常多的Task,如編譯,大包,檔案系統操作等等。Ant中每個任務對應於Ant物件模型中的一個Java物件,要自定義新的任務就是要編寫執行該任務類然後提供給Ant呼叫。很多系統命令也都是用Task包裝,而不是直接呼叫shell命令,在不同的作業系統上Task的使用方式是完全一致的。
構建檔案中任務標籤內部也可以有很多層次。但是Task內部的這些層次結構和Java類的層次結構沒有任何關係了。
Task標籤不再有統一的屬性和子元素,內部層次完全取決於具體的任務。
2.資料元素(data element)
構建檔案中除了與任務構建過程相關的元素外。還包括了儲存資料的變數和抽象資料型別等元素。資料元素有兩類:Property和DataType
Property
表示字串型的“鍵-值”對,只能用在可使用字串的位置。
Propery和Java中的Property物件是相容的,可以使用Property檔案或JVM命令列-Dproperty=value選項,在執行ant時動態定義。
可以使用${propName}的形式引用Property資料。
property資料定義和引用
載入config.properties檔案中定義的property資料
通過命令列在執行時動態定義propery資料
ant mytarget -Dname=value
DataType
Property資料值都是字串,ant並不知道這些字串代表了什麼物件。如果將包含很多個Jar檔案的長串路徑儲存在Property資料中,就很容易出錯,修改也不方便。
Ant還提供了很多種具體的資料型別(DataType),各種資料型別能夠更清晰地描述特定型別的資料,如Path(路徑), FileSet(檔案集合,可以使用萬用字元)等,修改起來更加方便。
使用Property表示路徑和使用Path/FileSet物件表示路徑的對比:
3.工程結構和構建檔案
要編寫工程的構建檔案,必須要了解專案的結構。專案型別不同,專案結構往往存在較大的差異(如Web專案和GUI專案),沒有最佳的工程組織模式。工程結構是比較複雜的,需要考慮跨平臺(使用相對路徑),依賴自包含無外部需求,功能模組和不同型別檔案分離等等。
以下面的專案結構為例:
projectName
build.xml 構建檔案
src/
api
module
doc/ 專案相關文件(非JavaDoc文件,不能自動生成),如readme,license等
lib/ 依賴的外部庫,統一依賴
bin/ 可選目錄,包含安裝、執行等指令碼或者是難找的、定製的可執行工具(為跨平臺,最好不要使用可執行程式)
build/ 構建產出目錄
classes/
doc/ javadoc產出
lib/
bin/
dist/ 最終用於釋出的目錄(內容一般都是從其他目錄複製而來)
lib/
bin/
doc/
config/
編寫構建檔案
相關文章
- webpack 學習筆記:入門介紹Web筆記
- uboot-uboot介紹-學習筆記boot筆記
- 學習筆記二--Weex語法介紹筆記
- DG學習筆記(1)_入門介紹筆記
- [PyTorch 學習筆記] 5.1 TensorBoard 介紹PyTorch筆記ORB
- JVM 學習筆記(五)JVM筆記
- cmake學習筆記(五)筆記
- Javascript 學習 筆記五JavaScript筆記
- Java學習筆記:Javaweb的伺服器介紹Java筆記Web伺服器
- 學習筆記-React的簡單介紹&工作原理筆記React
- Java IO學習筆記五Java筆記
- android學習筆記五Android筆記
- Spss 學習筆記(五)SPSS筆記
- c++學習筆記(五)C++筆記
- golang 學習筆記:第 1 節:GO 語言介紹Golang筆記
- Java 多執行緒學習筆記(四)yield 介紹Java執行緒筆記
- TestNG簡單介紹以及安裝—學習筆記1筆記
- gcc簡介(學習筆記)GC筆記
- 字典--Python學習筆記(五)Python筆記
- 大資料學習筆記(五)大資料筆記
- Android學習筆記(五)——FragmentAndroid筆記Fragment
- 《機器學習》西瓜書學習筆記(五)機器學習筆記
- Spring框架學習筆記(一):官方文件介紹,IoC與AOP概念學習Spring框架筆記
- UI自動化學習筆記- PO模型介紹和使用UI筆記模型
- VisionPro學習筆記(1)——軟體介紹和基本使用筆記
- 以太坊學習筆記————10、錢包、以太幣、Gas介紹筆記
- E-Learning企業應用介紹(學習筆記)筆記
- celery筆記五之訊息佇列的介紹筆記佇列
- Kinect開發學習筆記之(一)Kinect介紹和應用筆記
- 遊戲引擎學習筆記:介紹、架構、設計及實現遊戲引擎筆記架構
- Kubernetes學習筆記(五):卷筆記
- hive學習筆記之五:分桶Hive筆記
- TypeScript學習筆記之五類(Class)TypeScript筆記
- Activiti 學習筆記五:流程變數筆記變數
- Qt學習筆記(五)QString 字串QT筆記字串
- OS學習筆記五:儲存模型筆記模型
- Python3.6學習筆記(五)Python筆記
- Delphi5學習筆記之五筆記