欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Eclipse In Action - 第5章. 用Ant構建


本章內容:
  • 一個(gè)正式的構建過(guò)程可以做什么
  • 為進(jìn)行正式構建組織項目
  • 回顧一個(gè)舊標準:Make
  • 新的標準Java構建工具:Ant
  • Ant項目,目標,任務(wù)及屬性
  • 一個(gè)簡(jiǎn)單的Ant構建文件

  盡管編程--編寫(xiě)和編譯代碼--是軟件開(kāi)發(fā)中最明顯的部分,但并不意味著(zhù)就是唯一的部分。就像你已經(jīng)看到過(guò)的,測試也很重要。但交付一個(gè)完成的產(chǎn)品還需要更多的步驟:你還需要文檔,打包,以及部署你所開(kāi)發(fā)的軟件。手工進(jìn)行這些工作是煩悶的、重復性的,還容易出錯。這是個(gè)迫切需要自動(dòng)化進(jìn)行的任務(wù)。

5.1 需要一個(gè)正式的構建過(guò)程


  你已經(jīng)經(jīng)歷了測試--編碼,測試--編碼的循環(huán),并最終得到了一些人們可以實(shí)際使用的東西。那么該如何交付該功能呢?
  下一步就是要以確切的詞匯來(lái)標明這個(gè)產(chǎn)品到底是什么。它是一個(gè)API嗎?還是一個(gè)具有圖形界面的可執行程序?它是被打包在一個(gè)JAR文件中嗎?它是否包含文檔?示例代碼呢?是否所有這些東西都要刻錄在一張光盤(pán)上?還是要壓縮在一塊兒以便通過(guò)因特網(wǎng)上交付使用?
  一旦你作出了決定,Eclipse會(huì )簡(jiǎn)化這些步驟的執行。在你保存了源代碼并編譯了所有東西之后,就能立刻運行單元測試,用Javadoc向導創(chuàng )建文檔(假設這對于你的讀者來(lái)說(shuō)足夠了),把你的類(lèi)導出到一個(gè)JAR文件,并把所有的東西放到一個(gè)p文件中。如果你只是要非正式地把你正在做的游戲的最新版本發(fā)給一個(gè)朋友,這個(gè)過(guò)程是不錯的,但如果你要把一個(gè)產(chǎn)品交付給一個(gè)客戶(hù)或公眾,你是不會(huì )這么做的。有太多的事情會(huì )出錯:忘了刷新源碼樹(shù),忘了運行單元測試,沒(méi)注意到一個(gè)失敗的測試,生成一個(gè)Javadoc時(shí)選擇了錯誤的選項,漏拷了源碼文件,打錯了p文件名--可能的問(wèn)題是無(wú)窮無(wú)盡的。當從事該項目的人不止一個(gè)時(shí),這些問(wèn)題會(huì )變得更加復雜。
  進(jìn)行一個(gè)獨立的構建過(guò)程的主要原因之一是可重復性。最理想的是,你希望能夠只需在一臺工作站打入一條命令,機器就會(huì )攪拌一會(huì )兒它的硬盤(pán),并且在最后(如果一切順利并且成功運行了單元測試),吐出一個(gè)p文件或者一張光盤(pán)。減少了人工干預也就減少了構建過(guò)程中出錯的幾率,并且任何發(fā)生的錯誤都可以被持續改正。
  因為使用圖形界面來(lái)自動(dòng)化過(guò)程比較困難,構建過(guò)程通常設計為在命令行下運行。那樣的話(huà),通過(guò)使用一條簡(jiǎn)單的命令,或者使用Unix/Linux的 chron命令或Windows的at命令設置每天的指定時(shí)間自動(dòng)進(jìn)行,就可以擺脫這個(gè)問(wèn)題。
  使用外部的、獨立的構建過(guò)程的額外好處是,它讓開(kāi)發(fā)者能夠自由使用自己選擇的開(kāi)發(fā)環(huán)境。這看起來(lái)不像是一個(gè)緊迫的需求,但是強迫開(kāi)發(fā)者--尤其是那些很有經(jīng)驗的--放棄他們已經(jīng)精通的工具,對生產(chǎn)力是有害的。

5.1.1 創(chuàng )建構建目錄結構

  在我們查看特定的構建工具之前,讓我們來(lái)考慮一下這個(gè)任務(wù):利用你在前面的章節中作為示例開(kāi)始開(kāi)發(fā)的基于文件的持久組件(Persistence),計劃和組織構建過(guò)程。想象一下,由于某些原因,你(或你的主管)決定將該產(chǎn)品實(shí)用化。規范化構建過(guò)程的第一步就是組織你的文件,以便能夠清晰的區分源代碼和其他資源,臨時(shí)文件,以及可交付文件。

5.1.2 分離源碼和構建目錄

  在你創(chuàng )建了persistence對象之后,你沒(méi)有停下來(lái)考慮目錄結構。你簡(jiǎn)單的接受了Eclipse提供的默認配置:項目目錄等同于源碼目錄。這種結構的結果是,源碼文件、測試類(lèi)、編譯好的類(lèi)文件都混在一起了:

\persistence
  \org
    \eclipseguide
      \astronomy
        *.class
        *.java

          \persistence
            *.class
            *.java

  因為在源碼文件和生成文件之間沒(méi)有明確的界限,在開(kāi)始一個(gè)新構建之前,刪除生成文件就需要你在某些目錄中刪除某些文件。這不難,但使用一個(gè)獨立的目錄更加簡(jiǎn)單可靠,這樣你就能在開(kāi)始構建之前把整個(gè)目錄弄走--這就避免了過(guò)期的文件意外地弄糟了構建過(guò)程,從而導致莫名其妙的錯誤的可能性。
  與混合源碼文件和類(lèi)文件相比,一個(gè)更好的設計是在項目目錄中,為兩者創(chuàng )建單獨的目錄,像這樣:

\persistence
  \src
    \org
      \eclipseguide
        \astronomy
          *.java
        \persistence
          *.java
  \bin
    \org
      \eclipseguide
        \astronomy
          *.class
        \persistence
          *.class

  Eclipse在項目結構上十分靈活。如果你一開(kāi)始就已經(jīng)知道你需要一個(gè)正式構建過(guò)程,當你創(chuàng )建項目時(shí)就已經(jīng)能指定src作為源碼目錄。那你就不會(huì )在輸入名稱(chēng)后立即點(diǎn)[完成]來(lái)接受默認配置,而可以點(diǎn)[下一步]前進(jìn)到另一個(gè)對話(huà)框,那里提供了選項以增加一個(gè)新的源碼目錄;在[源]頁(yè)面上點(diǎn)擊[添加文件夾]就可以創(chuàng )建新的文件夾名(參看圖5.1)。

圖5.1 新的源碼文件夾。你可以在創(chuàng )建一個(gè)新項目時(shí)定義一個(gè)單獨的源碼文件夾,然后Eclipse會(huì )幫助建立一個(gè)單獨的輸出文件夾。


  但別擔心--你不必全部倒回去重新照做一遍。所謂敏捷開(kāi)發(fā)指的就是增量開(kāi)發(fā)--按部就班,并且如果沒(méi)有好的理由,絕不以吃力的方式做任何事情。就像你至今可能預想的那樣,Eclipse輕松地完成這些變換。你所需做的一切只是新建一個(gè)源碼文件夾(src)并把你的源碼移動(dòng)到里面。由Eclipse負責建立新的獨立的輸出文件夾(bin)及其子目錄。(此外,當你用Eclipse構建時(shí),它會(huì )將所有的class文件放置到正確的位置。)
  在Java透視圖中,在項目名稱(chēng)(Persistence)上右擊鼠標,選擇[新建]->[源碼文件夾],然后輸入 src 作為文件夾名(參看圖5.2)。注意對話(huà)框頂部的注釋?zhuān)簽楸苊庵貜?,現有的項目源碼文件夾入口將被替換,并且輸出文件夾將被設置為‘Persistence/bin‘。這正是你所想要的,那么就點(diǎn)擊[完成]。(如果你不想把輸出文件夾命名為bin--比如說(shuō)想把它命名為build--你可以在稍后通過(guò)從項目的快捷菜單中選擇[屬性]->[Java 構建路徑]->[源]來(lái)改變缺省的輸出文件夾。)

圖5.2 將一個(gè)源碼文件夾添加到一個(gè)現存的項目中。Eclipse自動(dòng)創(chuàng )建一個(gè)新的輸出目錄。


  現在,要把源碼文件移動(dòng)到新的src目錄中,右鍵點(diǎn)擊頂層源碼目錄(org),選擇[重構]->[移動(dòng)],并選擇Persistence下面的src目錄(參看圖5.3)。(你可以安全地忽略那個(gè)警告:到缺省包的引用將不會(huì )被更新。)或者--甚至更簡(jiǎn)單--在包瀏覽器中點(diǎn)擊org文件夾并拖動(dòng)到src文件夾上。

圖5.3 更多的重構:將源碼樹(shù)移動(dòng)到新的src目錄。


5.1.3 為可發(fā)布文件創(chuàng )建一個(gè)目錄

  創(chuàng )建一個(gè)獨立的輸出目錄是一個(gè)好的開(kāi)始,但不是發(fā)布軟件的全部。一堆目錄里面的一堆類(lèi)不是一個(gè)產(chǎn)品。你需要決定要將哪一片發(fā)布給你的客戶(hù),并把它們干凈地包裝在一個(gè)JAR文件中。任何好的軟件產(chǎn)品都要求有文檔,因為你的產(chǎn)品是為開(kāi)發(fā)者設計的一個(gè)軟件組件,它很可能只需包含Javadoc就足夠了。(在前面章節的代碼中,你對于包含Javadoc注釋是不嚴格的,這種情形下,你應當考慮更正--但現在,讓我們把它作為讀者--你的一個(gè)借口。)
  假定Persistence組件是普遍關(guān)心的唯一部分。你需要將persistence類(lèi)和astronomy類(lèi)、test類(lèi)分離開(kāi)來(lái)。記住你仍需構建所有的類(lèi)以便測試persistence類(lèi),要這么做,一個(gè)好的方法是再創(chuàng )建另一個(gè)目錄,里面僅放置那些組成可發(fā)布產(chǎn)品的文件。你將把它稱(chēng)為dist(distribution的簡(jiǎn)稱(chēng)),而它將包含Persistence組件的JAR文件和Javadoc:

\persistence
  \src
    \...
  \bin
    \...
  \dist
    \lib
      persistence.jar
    \doc
      *.html

  在你更改src目錄中的Java源文件時(shí),Eclipse自動(dòng)保持bin目錄中的類(lèi)文件最新,但除此之外的事情都得你來(lái)做。如前所述,你可以用Eclipse手動(dòng)去做;但為了可靠性和一致性,使用一個(gè)構建工具來(lái)自動(dòng)化這個(gè)過(guò)程會(huì )好很多。

5.2 Make:一個(gè)回顧


  在我們考慮事實(shí)上的Java標準構建工具Ant之前,讓我們來(lái)快速地回顧一下傳統的構建工具--Make--以便從其他角度看看Ant所帶來(lái)的優(yōu)點(diǎn)。有許多不同的增強版Make,包括各種Unix變種,Gnu make,以及微軟的NMAKE(New Make),不過(guò)它們大體上都是相似的。
  Make接收一個(gè)make文件,文件中包含一個(gè)目標列表,每個(gè)目標后都接著(zhù)一個(gè)腳本,當調用對應目標時(shí)運行。(默認狀況下,Make查找一個(gè)特定名字的文件,通常是makefile,但你一般可以在命令行強制指定一個(gè)其他名字的文件。)一個(gè)目標和它的命令有時(shí)稱(chēng)為 規則(rules)。
  一個(gè)目標可以有依賴(lài)(dependencies);也就是其他的必須首先被評估的目標。當Make運行時(shí),它查找第一個(gè)目標的依賴(lài)以查看它們是否已經(jīng)存在。如果目標是文件,并且依賴(lài)也是文件,Make會(huì )比較它們的時(shí)間戳;如果依賴(lài)比目標新,Make會(huì )運行規則以更新目標。
  這是一個(gè)make文件規則的一般格式:

TARGET: dependencies ...
  commands
  ...

  一個(gè)小的,簡(jiǎn)單的,用來(lái)從兩個(gè)C源文件構建一個(gè)程序的make文件看起來(lái)可能會(huì )是這樣:

myapp.exe: main.obj aux.obj
  link main.obj aux.obj -o myapp.exe

main.obj: main.c
  cc main.c

aux.obj: aux.c
  cc aux.c

  如果你不熟悉C,別擔心具體細節,只要注意從C源代碼創(chuàng )建一個(gè)可執行程序一般需要的兩個(gè)步驟:編譯源代碼為目標文件(示例中的.obj文件)以及把所有的目標文件鏈接為一個(gè)單一的可執行文件(示例中的.exe文件)。
  第一個(gè)目標,myapp.exe,是一條規定了如何通過(guò)連接兩個(gè)目標文件以構建可執行文件的規則。默認情況下,make文件中的第一個(gè)目標就是由Make執行的。Make計算依賴(lài)鏈以確保鏈上的每個(gè)東西都是最新的。你第一次運行這個(gè)make文件時(shí),它首先編譯main.obj和aux.obj,然后把它們連接起來(lái)以構建程序myapp.exe。
  如果你修改了aux.c并再次運行make文件,main.obj仍然是最新的。因此,Make僅編譯aux.obj文件,之后就連接新的aux.obj和已有的main.obj以創(chuàng )建myapp.exe。
  除了一個(gè)構建程序的目標外,你還可以添加其他的目標來(lái)執行特定任務(wù),例如刪除所有生成的文件以便強制完全重建。你可以將以下兩個(gè)目標添加到文件末尾:

CLEANALL: CLEAN
  del *.exe
  echo Deleted executable
CLEAN:
  del *.obj
  echo Deleted object files

  因為它們并沒(méi)有標識一個(gè)要構建的真正目標,像這樣的目標通常稱(chēng)為“偽目標”(pseudo-targets)。這兩個(gè)目標并沒(méi)有包含在默認目標的依賴(lài)鏈中,因此執行它們的唯一途徑就是在啟動(dòng)Make時(shí)在命令行中明確指定它們。
  指定CLEAN會(huì )刪除所有中間目標文件。指定CLEANALL會(huì )首先刪除所有中間目標文件(因為它依賴(lài)于CLEAN目標),然后刪除可執行文件--以這種方式使用的依賴(lài)和方法調用的效果類(lèi)似。
  除了規則之外,一個(gè)make文件還能對變量賦值以及訪(fǎng)問(wèn)環(huán)境變量。因為本概述只是打算提供一個(gè)對Make的概覽,在這里我們不會(huì )談及這些問(wèn)題。
  正如例子中所示范的那樣,Make具有一些批處理文件和shell腳本所不具有的重要優(yōu)點(diǎn):
  • Make減少了構建時(shí)間。Make能夠計算哪些構建目標比它們的源碼更舊,并且只會(huì )構建對于更新構建目標來(lái)說(shuō)必要的那些。當你在做一個(gè)在編譯時(shí)可能需要花費很長(cháng)時(shí)間的大系統時(shí),這能夠節省大量時(shí)間。
  • Make是說(shuō)明性的。你不需要去一步一步地告訴它如何構建。相反的,你只需將需要構建的東西指定為一組相關(guān)的目標集。執行順序,或者說(shuō)控制流程,不會(huì )被正規地顯式規定--盡管你在必要時(shí)可以用偽目標來(lái)順序執行一組命令。
  • Make是可擴展的。命令是由Shell來(lái)執行的,所以如果你需要任何shell命令沒(méi)有提供的功能,你可以編寫(xiě)你自己的工具程序--比如,用C語(yǔ)言。
  除了一些古怪行為外(就比如令每個(gè)Make用戶(hù)至少發(fā)瘋一次的對空格和制表符(Tab)的過(guò)度區分),Make是一個(gè)完美的可用的構建工具。但示例用C來(lái)寫(xiě)的一個(gè)原因是:為了更好的演示Make的增量構建的能力。將Make運用在Java中則無(wú)法在這點(diǎn)上提供相當的益處,因為絕大多數的Java編譯器自動(dòng)地計算了依賴(lài)關(guān)系。假如你有一個(gè)Java類(lèi), HelloWorld

// HelloWorld.java

public class HelloWorld
{
  public static void main(String[] args)
  {
    Printer printer = new Printer();
    printer.out("Hello, world");
  }
}

  它使用這個(gè)Java類(lèi),Printer

// Printer.java

public class Printer
{
  void out(String s)
  {
    System.out.println(s);
  }
}

  你可以用一條命令來(lái)編譯這兩個(gè)類(lèi):

javac HelloWorld.java

  Java編譯器,javac,計算了HelloWorld.java并判斷它使用了Printer.java。如果還沒(méi)有編譯Printer.java,或者如果Printer.java比Printer.class要新,javac就會(huì )編譯Printer.java。換句話(huà)說(shuō),這一條命令實(shí)際上等同于你先前看到的那個(gè)C程序的make文件的第一部分--也就是開(kāi)頭那三條指定了如何構建程序的規則。
  因為增量編譯是Make與批處理文件或者shell腳本相比所能提供的最大優(yōu)點(diǎn),Java編譯器能自動(dòng)判斷依賴(lài)關(guān)系的能力看來(lái)減少了在Java開(kāi)發(fā)中對Make工具的需求。然而,這并沒(méi)有完全消除對某些類(lèi)型的構建工具的需求,因為對象的類(lèi)型在編譯時(shí)并不總是知道。類(lèi)能包含集合引發(fā)了問(wèn)題,因為一個(gè)集合可以存放任意類(lèi)型的對象;例如,一個(gè)Company類(lèi)可能包含有一個(gè)Employee的Vector,而編譯器可能無(wú)法在編譯時(shí)判斷出來(lái)。如果你需要可靠的增量編譯,你仍會(huì )需要某些類(lèi)型的構建工具。
  最后也是最重要的一點(diǎn),編譯并不是構建工具所做的唯一一件事。正如示例所示,傳統的make文件一般也執行一些像刪除舊文件這樣的簡(jiǎn)單的“管家”任務(wù)。Java項目經(jīng)常需要額外的步驟,例如生成Javadoc以及把包歸檔。

5.3 新的Java標準:Ant


  將傳統的Make工具應用到Java中有一個(gè)嚴重的缺點(diǎn):這些工具運行的是shell命令,而它們在各個(gè)平臺上都不一樣。這個(gè)事實(shí)使得采用Java開(kāi)發(fā)的主要因素之一:一次編寫(xiě),到處運行的能力,變得毫無(wú)用處。明顯的解決方案就是實(shí)現一個(gè)能說(shuō)得上是“Java上的Make”的工具。Ant,一個(gè)來(lái)自Apache軟件基金會(huì )(ASF)的開(kāi)源構建工具,走上了這條路。除了成為了比Make更好的跨平臺解決方案之外,Ant還更新了make文件的語(yǔ)法,采用了標準說(shuō)明格式:XML。由于這些緣故,Ant迅速地成為了Java上的標準構建工具,并被緊密地集成到Eclipse中;這種集成包括了一個(gè)特殊的編輯器,用來(lái)和Ant構建腳本一起工作。

注意
目前為止,因為你一直在使用Eclipse來(lái)編譯你的Java源代碼,你還不需要一個(gè)單獨的Java編譯器。如前所述,Eclipse包含了它自己的特殊的增量編譯器;你所需添加的只是一個(gè)Java運行時(shí)環(huán)境(JRE)。
要用Ant來(lái)構造,尤其是在命令行下,你需要有一個(gè)完整的Java開(kāi)發(fā)工具包(JDK)。依據你的平臺而定,你可能會(huì )有許多選擇;但至少你應該使用JDK 1.3.x(JDK 1.4.x更好),Sun的或是其它公司的都行。確保在你的PATH環(huán)境變量中,該JDK的bin目錄要比其它任何包含有JRE的目錄靠前。同樣應確保,在你的CLASS環(huán)境變量中,刪除所有到舊的JDK和JRE的引用。你不需要在classpath中包含任何JDK的標準目錄或者JAR,因為它們會(huì )依據Java編譯器的可執行文件(Windows中是javac.exe)和Java虛擬機(java.exe)的位置來(lái)自動(dòng)定位。

5.3.1 一個(gè)對XML的非常簡(jiǎn)短的介紹

  XML(可擴展標記語(yǔ)言,Extensible Markup Language)已經(jīng)成為了表述任何類(lèi)型語(yǔ)言,因此你可能已經(jīng)用過(guò)它諸多功能中的其中一些了。如果你還沒(méi)有用過(guò)它,或者已經(jīng)用過(guò)但對它的一些技術(shù)還不了解,這份介紹可以讓你能更容易地理解后面對Ant構建文件的討論。
  XML來(lái)源于SGML(標準廣義標記語(yǔ)言,Standard Generalized Markup Language),與其很相似的HTML(超文本標記語(yǔ)言,Hypertext Markup Language)也是如此。都使用標簽,也就是用尖括號括起來(lái)的標識符,就像這樣:

<TITLE>

  不過(guò)在HTML和XML之間還是有少數一些重要的不同點(diǎn)。因為HTML是設計用來(lái)為一個(gè)較有限的目標--描述如何將數據顯示為一個(gè)網(wǎng)頁(yè)--提供服務(wù)的,它定義了一組標準標簽。TITLE是一個(gè)有效的HTML標簽,但ORDER_NUMBER不是。然而,XML是可擴充的。由你正在使用的應用程序來(lái)定義哪些標簽是有效的。在一個(gè)使用XML來(lái)表示一個(gè)在線(xiàn)商店的數據的程序中,ORDER_NUMBER就很有可能是一個(gè)有效的標簽。
  一個(gè)像<TITLE>這樣的標簽稱(chēng)為一個(gè)開(kāi)標簽(Opening Tag);它標記了一段數據的開(kāi)頭。開(kāi)標簽通常需要有一個(gè)閉標簽,也就是和開(kāi)標簽名字相同,前面有個(gè)斜杠的標簽。下面定義了一個(gè)網(wǎng)頁(yè)的標題:

<TITLE>A very brief introduction to XML</TITLE>

  HTML對語(yǔ)法要求相當松。開(kāi)標簽并不總是要求有閉標簽。例如,標簽<P>被用來(lái)標記段落開(kāi)頭,而</P>應該是用來(lái)標記末尾。然而實(shí)際上,你可以簡(jiǎn)單地使用<P>來(lái)在一個(gè)網(wǎng)頁(yè)上表明文字段落間的間隔。這在XML中絕對不是如此--每個(gè)開(kāi)標簽都 必須要有一個(gè)閉標簽。
  有時(shí)候在HTML中你可以回避不正確的嵌套的開(kāi)標簽和閉標簽;但在XML中就不行了。以下代碼由于嵌套不正確,在XML中是無(wú)效的:

<B><I>This is not valid in XML!</B></I>

  HTML和XML的一個(gè)最大不同就是XML是大小寫(xiě)敏感的。在HTML中,<TITLE>和<title>都是有效且是等價(jià)的。在XML中,取決于應用程序,它們都可能有效,但并不等價(jià)。

元素和屬性
  一個(gè)開(kāi)標簽和一個(gè)閉標簽定義了一個(gè)元素(element)。每個(gè)XML文檔必須有一個(gè)根元素(或文檔元素)來(lái)把文檔中的所有其它元素包圍起來(lái)。
  每個(gè)元素的開(kāi)標簽可能包含了形式為名字-值對(name-value pairs)的與元素相關(guān)的附加信息,我們稱(chēng)之為屬性(attributes)。其中的值必須總是用引號包圍。按標簽不同,特定的屬性可能是必需的,或是可選的。比如,Ant定義了一個(gè)<target>標簽來(lái)標識構建目標。這個(gè)target標簽接受好幾個(gè)屬性,例如depends和description,但只有name屬性是必需的:

<target name="Compile" depends="Init">
  <!-- do compilation stuff here-->
</target>

 ?。ㄗ⒁饬?,如同在HTML中一樣,你可以插入以<!--開(kāi)頭,-->結尾的注釋。)
  有時(shí)候元素會(huì )沒(méi)有任何內容。例如,用來(lái)運行Java程序的Ant標簽,<java>,允許你在屬性中給定所需的所有信息。如果你有一個(gè)類(lèi)文件Hello.class,你可以放置在一個(gè)target里面來(lái)運行它,如下所示:

<target name="SayHello">
  <java classname="Hello.class"> </java>
</target>

  作為一種便捷的形式,像這里那個(gè)具有/<java>標簽的空元素可以把開(kāi)標簽寫(xiě)成以/>結尾,然后忽略閉標簽。以下和前面的例子是等同的:

<target name="SayHello">
  <java classname="Hello.class"/>
</target>

用屬性和嵌套元素來(lái)表示數據
  屬性(例如<target>標簽中的name屬性)和嵌套元素(例如被<TITLE>和</TITLE>標簽所包圍的文本)在XML中都能被用來(lái)說(shuō)明數據。由應用程序來(lái)選擇。有時(shí)應用程序會(huì )同時(shí)支持兩種格式并讓用戶(hù)來(lái)選擇。Ant有時(shí)會(huì )提供屬性以選擇單個(gè)選項(例如classname),復雜些的就用嵌套標簽,例如文件集,或是路徑與個(gè)別文件的組合。
  舉個(gè)例子,標簽<java>,讓你既可以用一個(gè)屬性來(lái)指定類(lèi)路徑(classpath),也可以用嵌套元素。你可以用classpath來(lái)將路徑設置為預定義好的屬性java.class.path(Ant把它設為你的環(huán)境的類(lèi)路徑),如下所示:

<target name="SayHello">
  <java classname="Hello.class" classpath="${java.class.path}"/>
</target>

  或者你可以使用一個(gè)嵌套的classpath元素,兩者是等價(jià)的:

<target name="SayHello">
  <java classname="Hello.class">
    <classpath path="${java.class.path}"/>
  </java>
</target>

  嵌套元素可以依次包含嵌套元素。例如,你可以用一個(gè)或多個(gè)的嵌套<pathelement>元素來(lái)替換掉<classpath>標簽中的path屬性,別的元素也可如此:

<target name="SayHello">
  <java classname="Hello.class">
    <classpath>
      <pathelement path="${java.class.path}"/>
      <pathelement location="c:/junit/lib/junit.jar"/>
    </classpath>
  </java>
</target>

  由于允許像這樣的多個(gè)選項,有時(shí)Ant和其它使用XML的程序會(huì )讓人難以理解。嵌套元素提供了比屬性強得多的靈活性,后者局限于單個(gè)值。如果你僅僅需要一個(gè)值,使用簡(jiǎn)單些的語(yǔ)法來(lái)設置選項會(huì )很方便。
  使用嵌套元素這種方式來(lái)擴展選項顯示了XML的主要問(wèn)題:冗長(cháng)。你包含進(jìn)去的每一點(diǎn)點(diǎn)的數據都添加了另一對開(kāi)標簽和閉標簽。好在(或者說(shuō)是因為很有必要),大多數基于XML的程序都提供了工具,以使得編寫(xiě)XML的工作更輕松些。

5.3.2 一個(gè)簡(jiǎn)單的Ant示例

  在探究Ant及其構建腳本的細節之前,讓我們通過(guò)“Hello,World.”的Ant等價(jià)物來(lái)看看Eclipse中的Ant的使用技巧。如同Make默認將一個(gè)make文件命名為makefile一樣,Ant的默認構建腳本名為build.xml。和Make一樣,你可以通過(guò)在調用Ant時(shí)顯式指定一個(gè)文件來(lái)跳過(guò)默認設置。然而,通常還是遵守這個(gè)約定較好,尤其是因為Eclipse也同樣將構建腳本默認命名為build.xml,并且會(huì )自動(dòng)用Ant腳本編輯器打開(kāi)叫這個(gè)名字的文件。(你可以到[窗口]->[首選項]->[工作臺]->[文件關(guān)聯(lián)]對話(huà)框去更改它的行為,但把它修改為打開(kāi)所有的.xml文件并不是個(gè)好主意--將來(lái)你會(huì )見(jiàn)到其它類(lèi)型的XML文件,它們將更能從其它專(zhuān)用編輯器獲益。如果你不愿把你的構建腳本叫做build.xml,在[文件關(guān)聯(lián)]對話(huà)框中逐個(gè)輸入所有的構建腳本名,以便用Ant編輯器打開(kāi)它們。)
  要創(chuàng )建構建文件,可以在一個(gè)現存的項目(比如你的老項目Hello)上右擊鼠標,然后在快捷菜單中選擇[新建]->[文件]。輸入build.xml作為文件名并點(diǎn)擊[完成]。如果編輯器沒(méi)有自動(dòng)為你打開(kāi)build.xml,那么就雙擊build.xml文件。輸入以下內容:

<?xml version="1.0"?>
<project name="Hello" default="print message">
  <target name="print message">
    <echo message="Hello from Ant!"/>
  </target>
</project>

  Ant編輯器并不像Java編輯器那么有用,但是它提供了一些基本的方便,例如你可以在任何時(shí)候通過(guò)按下[Ctrl]+[空格]鍵來(lái)調用自動(dòng)代碼完成功能。在標簽外時(shí),它會(huì )顯示有效的標簽;在標簽里時(shí),它將顯示該標簽的有效屬性。(后面的功能尤其有用,因為各個(gè)標簽的屬性名并不相同。)同時(shí),Ant編輯器還提供了語(yǔ)法高亮和一個(gè)大綱視圖。
  要運行這個(gè)腳本,首先保存它,然后在[包瀏覽器]中右擊build.xml,在快捷菜單中選擇[運行Ant]。這樣將打開(kāi)一個(gè)已經(jīng)選定了默認目標的對話(huà)框(參看圖5.4)。

圖5.4 運行一個(gè)Ant文件。默認目標已經(jīng)被自動(dòng)選定。


  點(diǎn)擊對話(huà)框底部的[運行]按鈕,Eclipse的控制臺視圖會(huì )輸出如下內容:

Buildfile: c:\eclipse\workspace\hello\build.xml

print message:
  [echo] Hello from Ant!
BUILD SUCCESSFUL
Total time: 2 seconds

在Eclipse外部運行Ant
  除了可以在Eclipse內部運行Ant腳本外,你也可以在Eclipse外部使用構建腳本。要這么做,你需要從Apache軟件基金會(huì )(ASF,Apache Software Foundation)(Ant項目可以在http://ant.apache.org找到)下載并安裝完整的Ant發(fā)行版。如果當前版本和Eclipse自帶的那個(gè)不同(或者不兼容),你就得找到舊版來(lái)下載或是升級Eclipse自帶的Ant。
  要升級Eeclipse自帶的Ant,在Eclipse主菜單中選擇[窗口]->[首選項]->[Ant]->[運行時(shí)]。然后從classpath中清除1.5.1版的ant.jar和optional.jar,并添加新版的這兩個(gè)JAR文件的路徑。
  在下載適合于你系統的p文件(或tar文件)并解壓之后,將bin目錄路徑添加到你的path,lib目錄路徑添加到classpath。如果你將Ant安裝在Windows上的c:\jakarta-ant-1.5.1目錄,你可以通過(guò)在命令行下鍵入如下命令來(lái)將這些目錄加入到你的path中:

SET PATH=c:\jakarta-ant-1.5.1\bin;%PATH%
SET CLASSPATH= c:\jakarta-ant-1.5.1\lib;%CLASSPATH%

  這些更改只會(huì )對當前命令行窗口有效。要想讓設置長(cháng)期生效,需要用Windows NT/2000/XP中的[控制面板]的[系統],或是Windows 95/98/ME中的autoexec.bat文件來(lái)修改它們,之后你打開(kāi)的任何命令行窗口都將設置適合于A(yíng)nt的選項。在執行這些步驟后,現在你可以進(jìn)入c:\eclipse\workspace\Hello目錄,輸入 ant以運行Ant:

C:\eclipse\workspace\Hello>ant
Buildfile: build.xml

print message:
  [echo] Hello from Ant!

BUILD SUCCESSFUL
Total time: 2 seconds

  如果你在項目的正式構建中使用Ant,但在日常工作中繼續使用Eclipse的自動(dòng)編譯(這非常方便),你可能要在Eclipse中--或者更愿意在命令行下,偶爾運行 ant來(lái)構建。這么做可以確保你沒(méi)有干擾正式構建過(guò)程,并且在構建中包含了你最近創(chuàng )建的任何文件。
  在你制作一個(gè)更大的構建文件前,讓我們首先來(lái)看看構成一個(gè)Ant的make文件的重要標簽及屬性的相關(guān)細節。

5.3.3 項目

  一個(gè)構建文件必須具備的文檔元素是<project>標簽,它必須指定一個(gè)默認目標,還可以指定一個(gè)名字(可選的)。此外,還可以標明項目的基本目錄。表5.1中列出了它的屬性:

表5.1 <project>標簽屬性
屬性 描述 是否必需
default 要運行的默認目標
name 項目名稱(chēng)
basedir 基本目錄
description 項目描述

  在basedir屬性中,你既可以指定相對路徑也可以指定絕對路徑;不管哪種情況,這都將被解析為其他標簽可以使用的絕對路徑。然而使用一個(gè)相對路徑會(huì )較好,因為這樣能讓構建更具可移植性。在進(jìn)行一次構建時(shí),其它開(kāi)發(fā)者的機器以及正式構建用機不需要設置得和你的一樣。以下示例將basedir屬性設置為當前路徑(.)--也就是說(shuō),定位到build.xml所在的目錄:

<project name="Hello" default="compile" basedir="." description = "Hello, world build file">

<project>標簽可以有以下嵌套元素:
  • <desciption>--如果你需要將描述擴展到超過(guò)一行,你可以用嵌套元素來(lái)包含項目描述,而非用一個(gè)屬性。強烈推薦寫(xiě)上描述。
  • <target>--如5.3.4節所述。
  • <property>--如5.3.6節所述。

5.3.4 目標

  一個(gè)目標(target)就是一個(gè)任務(wù)或是一組相關(guān)任務(wù)的容器標簽,可以(粗略地)比喻為一個(gè)方法(method)。它可具有如表5.2所列屬性:

表5.2 <target>標簽屬性
屬性 描述 是否必需
name 目標名稱(chēng)
depends 依賴(lài)關(guān)系列表
if 僅當設置了指定屬性時(shí)執行
unless 僅當未設置指定屬性時(shí)執行
description 目標描述

  為你的主要目標給出一份描述是個(gè)好主意,因為Ant提供了一個(gè)-projecthelp選項來(lái)列出所有具有描述的目標,并把它們作為主要目標。這個(gè)選項令你的構建文檔在一定程度上可以進(jìn)行自我文檔編制。
  這里是一個(gè)例子:

<target name="compile" depends="init" description="Compile all sources">

5.3.5 任務(wù)

  如果把一個(gè)目標比喻為一個(gè)方法,一個(gè)任務(wù)(task)可以比喻為方法中的一條語(yǔ)句。Ant提供了大量的任務(wù)--超過(guò)100條,如果你把核心任務(wù)和可選任務(wù)都算上。
  Ant的巨大優(yōu)點(diǎn)之一是它對跨平臺問(wèn)題是透明處理的。例如,在UNIX中,一個(gè)文件路徑在目錄和文件間用的是向前的斜線(xiàn)(/),而在Windows中,用的是一個(gè)反斜線(xiàn)(\)。在A(yíng)nt中,你都可以使用,然后Ant會(huì )提供對你正在使用的系統來(lái)說(shuō)正確的格式。對于類(lèi)路徑來(lái)說(shuō)也是一樣的。在UNIX中,一個(gè)類(lèi)路徑中不同的路徑是用一個(gè)冒號分隔的,而在Windows中使用的則是一個(gè)分號;你兩個(gè)都可以用,剩下的事情就交給Ant了。
  以下是一些常見(jiàn)的人物,它們都有一組基本屬性--足以理解示例并開(kāi)始編寫(xiě)你自己的構建文件。需要一份所有任務(wù)及其選項的完整描述的話(huà),請參考http://ant.apache.org/manual/index.html上的Ant文檔。

<buildname>
  該任務(wù)從一個(gè)文件中讀取構建號(build number),將屬性build.number設置為該號碼,然后將build.number的值+1后寫(xiě)回文件。它只有一個(gè)屬性,如表5.3中所列:

表5.3 <buildname>任務(wù)屬性
屬性 描述 是否必需
file 要讀取的文件(默認:build.number)

  這里是一個(gè)例子:

<buildnumber file="buildnum.txt" />

<copy>
  該任務(wù)復制一個(gè)或一組文件。要拷貝單個(gè)的文件,用file屬性即可。要拷貝多個(gè)文件,需要用一個(gè)嵌套的<fileset>元素。
  通常,該任務(wù)僅當目標文件不存在或比源文件舊時(shí)才執行復制,但你可以通過(guò)設置override屬性為true來(lái)改變默認行為。<copy>任務(wù)的屬性如表5.4中所列:

表5.4 <copy>任務(wù)屬性
屬性 描述 是否必需
file 源文件名 是,除非使用了<fileset>
tofile 目標文件名 是,除非使用了todir
todir 目標目錄 是,如果拷貝一個(gè)以上的文件
overwrite 覆蓋更新的目標文件 否;默認是false
includeEmptyDirs 復制空目錄 否;默認是true
failonerror 如果找不到文件則停止構建 否;默認是true
verbose 列出已復制的文件 否;默認是false

  一個(gè)<fileset>嵌套元素可以用來(lái)指定一個(gè)以上的文件。(參看5.3.7節。)
  這里是一個(gè)示例:

<copy file="log4k.properties" todir="bin"/>

<delete>
  該任務(wù)刪除一個(gè)或一組文件,或者一個(gè)目錄。要刪除單個(gè)的文件,用file屬性即可。要刪除多個(gè)文件,則要用一個(gè)嵌套的<fileset>元素。要刪除目錄,用directory屬性即可。<delete>任務(wù)的屬性如表5.5中所列:

表5.5 <delete>任務(wù)屬性
屬性 描述 是否必需
file 要刪除的文件 是,除非使用了<fileset>或dir
dir 要刪除的目錄 是,除非使用了<fileset>或file
verbose 列出已刪除的文件 否;默認是false
failonerror 如果出錯則停止構建 否;默認是true
includeEmptyDirs 使用<fileset>時(shí)刪除文件夾 否;默認是false

  一個(gè)嵌套的<fileset>元素可以用來(lái)指定一個(gè)以上的文件。(參看5.3.7節。)
  這里是兩個(gè)例子:

<delete file="ant.log"/>
<delete dir="temp"/>

<echo>
  該任務(wù)將一條信息寫(xiě)到System.out(默認),一個(gè)文件,一份日志,或者一個(gè)偵聽(tīng)器。它的屬性如表5.6中所列:

表5.6 <echo>任務(wù)屬性
屬性 描述 是否必需
message 要寫(xiě)入的文本 是,除非用了文本作為元素內容
file 輸出文件
append 附加到文件(而非覆蓋) 否;默認是false

這里有一些例子:

<echo message="Hello"/">
<echo>
  This is a message from Ant.
</echo>

<jar>
  該任務(wù)將一組文件壓縮到一個(gè)JAR文件中。允許的選項如表5.7中所示:

表5.7 <jar>任務(wù)屬性
屬性 描述 是否必需
destfile JAR文件名
basedir 要打包的文件的基本目錄
includes 要打包的文件的模式列表
excludes 要排除的文件的模式列表

  模式列表是由逗號或空格分隔的文件匹配模式列表。<jar>接受如同<fileset>元素的嵌套元素。(參看5.3.7節。)
  這里是一些例子:

<jar destfile="dist/persistence.jar"
  basedir="bin"
  includes=
  "org/eclipseguide/persistence/**, org/eclipseguide/astronomy/**"
  excludes="*Test*.class "/>

<jar destfile="dist/persistence.jar">
  <include name="**/*.class"/>
  <exclude name="**/*Test*"/>
</jar>

<java>
  任務(wù)java使用一個(gè)JVM(Java虛擬機)來(lái)調用一個(gè)類(lèi)。默認情況下,所用的JVM和Ant用的是同一個(gè)。如果你是在調用一個(gè)穩定的自定義構建工具,這樣可以節省時(shí)間;但如果你是在用它運行沒(méi)測試過(guò)的代碼,你將冒錯誤代碼乃至構建進(jìn)程崩潰的風(fēng)險。你可以將fork選項設置為true來(lái)調用一個(gè)新的JVM。該任務(wù)的屬性如表5.8中所列:

表5.8 <java>任務(wù)屬性
屬性 描述 是否必需
classname 要運行的類(lèi)的名稱(chēng) 是,除非指定了jar
jar 要運行的可執行JAR文件的名稱(chēng) 是,除非指定了classname
classpath 要用的Classpath
fork 用一個(gè)新的JVM運行類(lèi)或JAR 否;默認是false
failonerror 當發(fā)生錯誤時(shí)停止構建 否;默認是false
output 輸出文件
append 附加或覆蓋默認文件

  任務(wù)<java>可用以下嵌套元素:
  • <classpath>--可用于代替classpath屬性
  • <arg>--可用于指定命令行參數
  這是一些例子:

<java classname="HelloWorld"/>
<java classname="Add" classpath="${basedir}/bin">
  <arg value="100"/>
  <arg value="200"/>
</java>

<javac>
  該任務(wù)編譯一個(gè)或一組Java文件。它有一組復雜的選項(參看表5.9),但它比你所想象的要更容易使用,因為很多選項是提供給你以控制編譯器選項的。Ant設定的選項是面向目錄工作的,而非單個(gè)的Java文件,這讓構建項目更容易。

表5.9 <javac>任務(wù)屬性
屬性 描述 是否必需
srcdir 源碼樹(shù)的根 是,除非使用了嵌套的<src>
destdir 輸出目錄
includes 要編譯的文件的模式列表 否;默認包含所有的.java文件
excludes 用忽略的文件的模式列表
classpath 要用的Classpath
debug 包含調試信息 否;默認是false
optimize 使用優(yōu)化 否;默認是false
verbose 提供詳細輸出
failonerror 發(fā)生錯誤時(shí)停止構建 否;默認是true

  默認情況下,<javac>編譯時(shí)包含調試信息。這樣做通常適合于將被用于產(chǎn)品環(huán)境的構建。你可能希望有一種方法來(lái)打開(kāi)或關(guān)閉這個(gè)選項,也許會(huì )采取分開(kāi)調試構建和發(fā)布構建的目標的方法。
  <javac>可用以下嵌套元素:
  • <classpath>--可用于代替classpath屬性。
  • <jar>接受如同一個(gè)<fileset>元素那樣的嵌套元素。(參看5.3.7節。)
  這是一些例子:

<javac srcdir="src" destdir="bin"/>

<javac srcdir="${basedir}" destdir="bin"
  includes="org/eclipseguide/persistence/**"
  excludes="**/*Test*">
  <classpath>
    <pathelement path="${java.class.path}"/>
    <pathelement location="D:/log4j/jakarta-log4j-1.2.7/dist/lib/log4j-1.2.7.jar"/>
  </classpath>
</javac>

<javadoc>
  任務(wù)<javadoc>從Java源代碼文件生成一份Javadoc。任務(wù)jar、 java中用于選擇要包含哪些文件的選項應該比較熟悉了。指定給javadoc的首要選項設定了要包含哪些Javadoc注釋?zhuān)粎⒖幢?.10。

表5.10 <javadoc>任務(wù)屬性
屬性 描述 是否必需
sourcepath 源碼樹(shù)的根 是,除非指定了sourcefiles或者sourcepathref
sourcepathref 到一個(gè)指定源碼樹(shù)根的路徑結構的引用 是,除非指定了sourcepath或者sourcefiles
sourcefiles 源碼文件的逗號分隔列表 是,除非指定了sourcepath或者sourcepathref
destdir 目標目錄 是,除非已經(jīng)指定了doclet
classpath 類(lèi)路徑(Classpath)
public 僅顯示公共類(lèi)及成員
protected 顯示公共和保護的類(lèi)及成員 否;默認是true
package 顯示包,保護和公共的類(lèi)及成員
private 顯示所有的類(lèi)及成員
version 包含@version信息
use 包含@use信息
author 包含@author信息
failonerror 出錯時(shí)停止構建 否;默認是true

  任務(wù)<javadoc>可用以下嵌套元素:
  • <fileset>--可用于選擇一組文件。Ant自動(dòng)把**/*.java添加到每個(gè)組。
  • <packageset>--可用于選擇目錄。目錄路徑默認為和包名稱(chēng)一致。
  • <classpath>--可用于設置classpath。
  這是一些例子:

<javadoc destdir="doctest"
  sourcefiles ="src/org/eclipseguide/persistence/ObjectManager.java"/>

<javadoc destdir="doc"
  author="true"
  version="true"
  use="true"
  package="true">
  <fileset dir = "${src}/org/eclipseguide/astronomy/">
    <include name="**/*.java"/>
    <exclude name="**/*Test*"/>
  </fileset>
  <classpath>
    <pathelement path="${java.class.path}"/>
    <pathelement location ="D:/log4j/jakarta-log4j-1.2.7/dist/lib/log4j-1.2.7.jar"/>
  </classpath>
</javadoc>

<mkdir>
  該任務(wù)創(chuàng )建一個(gè)目錄。它具有如表5.11所示的一個(gè)屬性。如果指定了一個(gè)嵌套目錄,那么若必要的話(huà)會(huì )連父目錄也一起創(chuàng )建。

表5.11 <mkdir>任務(wù)屬性
屬性 描述 是否必需
dir 要創(chuàng )建的目錄

  這是一個(gè)示例:

<mkdir dir="dist/doc">

<tstamp>
  該任務(wù)設置屬性DSTAMP,TSTAMP以及TODAY。一個(gè)嵌套元素,<format>,可用于使用Java類(lèi)SimpleDateFormat定義的格式來(lái)改變它們的格式,但默認情況下,這些格式如下所示:

DSTAMP yyyyMMdd
TSTAMP hhmm
TODAY MMM dd yyyy

  關(guān)于<tstamp>和<format>元素的更多信息,請參看Ant文檔。

5.3.6 屬性

  屬性是你可以在一個(gè)構建文件中用作符號常數的名稱(chēng)-值對。屬性的值是通過(guò)用${和}括起名字的方式來(lái)引用的。例如,如果一個(gè)屬性junit_home已經(jīng)用值D:/junit/junit3.8.1定義,你可以使用該屬性以在編譯時(shí)添加junit的JAR文件到classpath中:

<javac srcdir="src" destdir="bin" classpath="${junit_home}/lib/junit.jar"/>

  屬性可以用幾種方式定義:
  • 由Ant預定義
  • 在A(yíng)nt命令行,用-D選項(例如,ant -Djunit_home=D:/junit/junit3.8.1)定義
  • 在一個(gè)構建文件中用<property>任務(wù)定義
  由Ant預定義的屬性包含了所有的標準Java系統屬性,包括了以下內容:
  • java.class.path
  • os.name
  • os.version
  • user.name
  • user.home
  Ant特有的屬性包括:
  • ant.version
  • ant.file
  • ant.project.name

<property>和名字屬性
  在一個(gè)Ant構建文件中設置屬性的最常用方式是利用<property>任務(wù)及其屬性name,以及屬性value或location。屬性value用于設置一個(gè)直接的值:

<property name="jar_name" value="myapp.jar"/>
<property name="company" value="Acme Industrial Software Inc."/>

  屬性location用于設置一個(gè)絕對路徑或文件名。如果你設定了一個(gè)相對路徑,Ant會(huì )認為它是基于basedir屬性的,然后把它轉換為一個(gè)絕對路徑并解析它。此外,文件路徑分隔符會(huì )被轉換為適合于平臺的字符(/,\,或者是:)。例如:

<property name="junit_home" location= "D:/junit/junit3.8.1"/>
<property name="src" location="src"/>

  第一個(gè)例子不會(huì )被改動(dòng)(除了文件路徑分隔符外),因為它表示一個(gè)絕對路徑。第二個(gè)例子會(huì )被擴展,因為它是個(gè)相對路徑;假設basedir(基本路徑)是c:\eclipse\workspace\persistence,${src}就等同于"c:\eclipse\workspace\persistence\src"。

<property>和文件屬性
  你可以用file屬性使用標準Java屬性文件格式來(lái)從一個(gè)文件中讀取屬性。假設有個(gè)叫build.properties的文件放在基本目錄中或是在classpath中:

# build.properties
junit_home= D:/junit/junit3.8.1
log4j_home=D:/log4j/jakarta-log4j-1.2.7

  你可以用以下標簽來(lái)讀取這些屬性:

<property file="build.properties"/>

<property>和環(huán)境屬性
  通過(guò)用environment屬性給環(huán)境設置前綴的方法,像讀取屬性那樣去讀取環(huán)境變量也是可行的。以下給環(huán)境設置了前綴myenv:

<property environment="myenv">

  之后,你只要使用前綴myenv就可以像訪(fǎng)問(wèn)屬性一樣訪(fǎng)問(wèn)環(huán)境變量。例如,如果環(huán)境中定義了JUNIT_HOME,你可以用${myenv.JUNIT_HOME}獲取它的值。
  你應該小心使用該技術(shù),因為并不是在所有操作系統上都支持它。同時(shí),即使底層操作系統是大小寫(xiě)不敏感的,在A(yíng)nt中,屬性名也是大小敏感的。這很容易在各版本的Windows中因疏忽而導致問(wèn)題,因為系統保留了環(huán)境變量的大小寫(xiě)而執行比較時(shí)卻不區分大小寫(xiě)。
  例如,如果有一個(gè)變量CLASSPATH,其值是c:\mylibs,以下既不會(huì )創(chuàng )建一個(gè)叫classpath的新變量,也不會(huì )改變原CLASSPATH變量的大小寫(xiě):

set classpath=.%classpath%;c:\anotherlib

  相反的,這樣做會(huì )更新原CLASSPATH變量的值為c:\mylibs;c\anotherlib。要確保大小寫(xiě)像你期望的那樣,你可以先清除該變量然后重新定義它。以下幾行可以放在命令行或是一個(gè)批處理文件中,它們可以強制把classpath變成小寫(xiě):

set tmpvar=%classpath%
set classpath=
set classpath=%tmpvar%;c:\anotherlib

  如果你正要為Ant設置環(huán)境變量,像這樣使用Windows批處理文件來(lái)預防問(wèn)題是值得考慮的──尤其是當該批處理文件會(huì )用在其它系統上時(shí)。

5.3.7 文件集和路徑結構

  由于A(yíng)nt的特性,許多Ant任務(wù),如<javac>和<jar>要求你設置路徑和文件集。Ant提供了元素以使你能給它們指定足夠多的細節,你既可以明確地選擇文件和目錄,也可以使用模式(patterns)來(lái)包含或排除一組文件或目錄。因為這些元素除了引用對象以外,什么事情也不做,所以被稱(chēng)為類(lèi)型(types)。在這里你僅使用兩種類(lèi)型:<fileset>和<classpath>。

<fileset>
  正如其名字所表述的那樣,<fileset>元素讓你選擇文件集。一個(gè)<fileset>必需的屬性只有基本目錄。如果你別的什么也沒(méi)有設定,該目錄下的所有文件及其子目錄都將被選定──特定的臨時(shí)文件以及特定工具(如CVS)生成的文件除外。(這樣的文件通常都有特殊的名字,用一個(gè)波紋號(~)或#開(kāi)頭和結尾,或者具有像CVS和SCCS這樣的特定的名字和擴展名;它們和一個(gè)典型項目的一般文件相同的情況極為罕見(jiàn)。要獲得一份Ant要默認排除的完整的模式列表,請參考Ant文檔。)
  你也可以選擇或排除那些和你提供的模式相匹配文件。模式可以包含以下通配符:

匹配一個(gè)任意字符
* 匹配零或多個(gè)字符
** 匹配零或多個(gè)目錄

  考慮這兩個(gè)常見(jiàn)的例子:你可以在include屬性中用模式**/*.java來(lái)包含所有的Java源文件,也可以在exclude屬性中用模式**/*Test*來(lái)排除測試用例。共同使用時(shí),它們指定了除測試用例外的所有Java文件。
  <fileset>元素的屬性如表5.12所列。

表5.12 <fileset>元素屬性
屬性 描述 是否必需
dir 目錄樹(shù)的根
defaultexcludes 排除通常的臨時(shí)文件和工具文件 否;默認是true
includes 要包含的文件的模式列表
excludes 要排除的文件的模式列表
followsymlinks 使用符號鏈接所指定的文件

  嵌套元素<include>和<exclude>可以分別用來(lái)代替includes屬性和excludes屬性。
  這是一些例子:

<fileset dir = "src/org/eclipseguide/astronomy"
  includes = "**/*.java"
  excludes = "**/*Test*"/>

<fileset dir = "src/org/eclipseguide/astronomy/">
  <include name="**/*.java"/>
  <exclude name="**/*Test*"/>
</fileset>

<classpath>
  <classpath>元素讓你可以指定哪些目錄和JAR文件是當類(lèi)要運行時(shí)(或者,對于Java編譯器來(lái)說(shuō),要編譯時(shí)),程序應該搜索的。默認情況下,Ant繼承了環(huán)境的類(lèi)路徑,但你都需要為特定程序(如JUnit)添加額外的目錄或JAR文件。使用類(lèi)路徑的任務(wù)提供了一個(gè)classpath屬性,但有時(shí)使用一個(gè)<classpath>嵌套元素會(huì )更方便些──尤其是當類(lèi)路徑很長(cháng)的時(shí)候。路徑可以包含用一個(gè)冒號或一個(gè)分號隔開(kāi)的多個(gè)文件或目錄;Ant會(huì )將分隔符轉換為適合于當前操作系統的字符。
  表5.13中列出了<classpath>元素的屬性。

表5.13 <classpath>元素屬性
屬性 描述 是否必需
path 冒號或分號分隔的路徑
location 單個(gè)文件或目錄

  一個(gè)或多個(gè)<pathelement>元素可以通過(guò)嵌套來(lái)構造一個(gè)更長(cháng)的類(lèi)路徑。<pathelement>接受和<classpath>:path以及l(fā)ocation相同的屬性。
  此外,一個(gè)<fileset>可以用于指定文件。
  這是一些例子:

<classpath path = "bin"/>
<classpath>
  <pathelement path="${java.class.path}"/>
  <pathelement location="${junit_path}"/>
  <pathelement location="${log4j_path}"/>
</classpath>

5.3.8 Ant的額外能力

  這里講述的基本知識已經(jīng)足以讓你開(kāi)始用Ant來(lái)工作而不會(huì )不知所措了。當你用Ant做更多的事情之后,你很可能會(huì )遇到一種情況──也許會(huì )發(fā)覺(jué)你一直在反復使用相同的<filelist>──并想知道有沒(méi)有一種比剪切、粘貼更優(yōu)雅的解決方案。通常,你會(huì )發(fā)現在A(yíng)nt中,幾乎沒(méi)有什么是不可能的。
  減少冗余代碼的一種方法是使用引用。例如,Ant中的每個(gè)元素都能指定一個(gè)ID;并且(取決于涉及的元素的類(lèi)型)你可以在構建文件中的其它地方使用ID來(lái)引用那個(gè)元素。例如,你可以使用id屬性給一個(gè)<classpath>指定一個(gè)標識符:

<classpath id="common_path">
  <pathelement path="${java.class.path}"/>
  <pathelement location="${junit_path}"/>
  <pathelement location="${log4j_path}"/>
</classpath>

  這樣一來(lái),這個(gè)類(lèi)路徑就可以在別的地方用refid屬性來(lái)引用:

<javac srcdir="src" destdir="bin">
  <classpath refid=common_path/>
</javac>

  Ant提供了任務(wù)和類(lèi)型以供你過(guò)濾文件,如同以文本來(lái)復制、替換符號一樣,這樣你就能夠在你的構建中包含版本信息──例如,使用帶有一個(gè)<filterset>的<copy>任務(wù)。它讓你可以通過(guò)使用選擇器類(lèi)型(如<contains>,<date>和<size>)來(lái)按照復雜的條件選擇文件。在很罕見(jiàn)的情況下,Ant沒(méi)有可以符合你需求的任務(wù),你會(huì )發(fā)現編寫(xiě)自己的Ant任務(wù)是很簡(jiǎn)單的事情。

5.4 一個(gè)Ant構建的示例


  以下是你的構建過(guò)程需要做的主要步驟:
  • 編譯程序,輸出到bin目錄
  • 在bin目錄中運行單元測試
  • 生成一份Javadoc文檔,輸出到dist/doc目錄
  • 將程序的類(lèi)文件打包到dist目錄下的一個(gè)JAR文件中
  因為你可能需要能逐步完成這些工作,它們在A(yíng)nt構建文件中是獨立的目標。然而通常,你會(huì )需要一次性完成所有步驟,所以你也需要有一個(gè)目標依賴(lài)于這些獨立的目標。
  通常這些獨立的目標都有共通的安裝需求。你可以創(chuàng )建一個(gè)初始化目標來(lái)執行安裝,該目標可以以依賴(lài)的方式包含這些獨立目標。因為這是一個(gè)相當簡(jiǎn)單的示例,在這里,你所需要做的一切只是通過(guò)調用tstamp任務(wù),初始化屬性DSTAMP,TSTAMP和TODAY為當前的日期和時(shí)間,然后打印日期和時(shí)間。

5.4.1 創(chuàng )建構建文件build.xml

  要創(chuàng )建構建文件,請遵循以下步驟:
  1.   
  2. 在[包資源管理器]中的項目Persistence上右擊鼠標,選擇[新建]->[文件]。
  3.   
  4. 在[新建文件]對話(huà)框中鍵入build.xml并點(diǎn)擊[完成]。
  在定義任何目標前,讓我們來(lái)創(chuàng )建一些屬性,之后就可以像符號常量那樣使用,而無(wú)需在構建文件中雜亂地堆放實(shí)際值。這個(gè)方法會(huì )讓構建文件更容易維護。這是build.xml的開(kāi)頭:

<?xml version="1.0"?>
<project name="Persistence" default="BuildAll" basedir=".">

  <description>
  Build file for persistence component,
  org.eclipseguide.persistence
  </description>

    <!-- Properties -->
    <property name="bin" location="bin"/>
    <property name="src" location="src"/>
    <property name="dist" location="dist"/>
    <property name="doc" location="${dist}/doc"/>
    <property name="jardir" location="${dist}/lib"/>
    <property name="jarfile" location="${jardir}/persistence.jar"/>
    <property name="logpropfile" value="log4j.properties"/>
    <property name="relpersistencepath" value="org/eclipseguide/persistence"/>
    <property name="alltests" value="org.eclipseguide.persistence.AllTests"/>
    <property name="junit_path" location="D:/junit/junit3.8.1/junit.jar"/>
    <property name="log4j_path" location="D:/log4j/jakarta-log4j-1.2.7/dist/lib/log4j-1.2.7.jar"/>

  如你所料,目錄一般是用location屬性來(lái)指定的,Ant會(huì )基于項目的基本目錄將它擴展為絕對路徑。有一個(gè)例外:relpersistencepath,這是一個(gè)你會(huì )在多個(gè)不同地方會(huì )用到的相對路徑,它是基于不同目錄的;要避免Ant將它轉變?yōu)榻^對路徑,你需要用value屬性來(lái)設置它。
  也請注意你顯式指定了幾個(gè)類(lèi)路徑。這不是最好的方法──因為這意味著(zhù)該構建只能在一臺以特殊方式配置的機器上工作──但這是最簡(jiǎn)單的。你可能想知道你能否用你在Eclipse中設置的classpath變量來(lái)代替。答案是肯定的,使用一個(gè)定制的第三方Ant任務(wù)可以實(shí)現;但這將意味著(zhù)你只能在Eclipse中使用該構建過(guò)程。(如果你不介意這個(gè)限制,你可以通過(guò)到eclipse.tools新聞組搜索一個(gè)定制的Ant任務(wù)的代碼。)
  除了該方法之外,特別是當你在Eclipse外部用命令行構建時(shí),你可以用其它幾種方法來(lái)設置這些類(lèi)路徑。第一個(gè)方法,也可能是最簡(jiǎn)單的,就是通過(guò)以下命令將它們添加到環(huán)境的CLASSPATH變量中:

  <Set CLASSPATH=%CLASSPATH%;D:/junit/junit3.8.1/junit.jar;D:/log4j/jakarta-log4j-1.2.7/dist/lib/log4j-1.2.7.jar>

  第二個(gè)方法是在命令行顯式用-D選項把它們傳遞給Ant:

  <ant -Djunit_path=D:/junit/junit3.8.1/junit.jar -Dlog4j_path=D:/log4j/jakarta-log4j-1.2.7/dist/lib/log4j-1.2.7.jar>

  更好一點(diǎn)的方法是將這些路徑存在它們自己的環(huán)境變量中。你可以在構建文件中用以下屬性標簽讀取它們:

  <property environment="env"/>
  <property name="junit_path" value="${env.JUNIT_HOME}/lib"/>
  <property name="log4j_path" value="${env.LOG4J_HOME}/lib"/>

  或者是在命令行中像這樣來(lái)傳遞它們:

  <ant -Djunit_path=%JUNIT_HOME%\lib -Dlog4j_path=%LOG4J_HOME%\lib>

  最后,其它的選項是使用一個(gè)屬性文件。你可能有一個(gè)名為build.properties的文件,其中有如下幾行:

  <cjunit_path=D:/junit/junit3.8.1/junit.jar>
  <log4j_path=D:/log4j/jakarta-log4j-1.2.7/dist/lib/log4j-1.2.7.jar>

  要在文件中使用這些值,需要在build.xml包含如下標簽:

  <property file="build.properties"/>

  在設置了屬性之后,就需要包含主要目標了。先放置默認目標不是必要的(就像用Make時(shí)一樣),但由于這是個(gè)特殊的目標──它僅僅是以一組依賴(lài)性的方式來(lái)把其它目標鏈接起來(lái),你就需要這樣寫(xiě):

  <!-- Main targets -->
  <target name="BuildAll"
    depends="-Init, -Prep, Compile, Test, Javadoc, Jar"
    description="Complete rebuild. Calls Init, Compile, Test, Javadoc, Package"/>
    <echo message="Build complete."/>
  </target>

  按照被BuildAll調用的順序包含剩下的主目標:下一個(gè)是編譯目標。注意,通過(guò)將源目錄標識為org,你可以編譯org.eclipseguide.persistence包和 org.eclipseguide.astronomy包中的任何東西,包括單元測試。該技術(shù)是拷貝任何所需資源──在這個(gè)例子中是log4j.properties文件──的極好方法:

  <target name="Compile"
    depends="-Init"
    description="Compile all Java classes">
    <!-- Compile org.* (${src}) -->
    <javac srcdir="${src}" destdir="${bin}">
      <classpath>
        <pathelement path="${java.class.path}"/>
        <pathelement location="${junit_path}"/>
        <pathelement location="${log4j_path}"/>
      </classpath>
    </javac>
    <!-- Copy log4j.properties files -->
    <copy file="${logpropfile}" todir="${bin}"/>
    <echo message="Compiled."/>
  </target>

  下一個(gè)目標是運行單元測試。要在Eclipse外部運行JUnit測試,你需要用到一個(gè)JUnit的TestRunner類(lèi)。由于你需要能夠在命令行下運行該構建文件并且記錄到一個(gè)文件中,你需要使用基于文本的TestRunner,即 junit.textui.TestRunner,而不是漂亮的圖形界面版本。要作為一個(gè)Java應用程序運行,需要用Ant的java任務(wù)。要確保它不會(huì )連同你的構建過(guò)程一同崩潰,你需要指定它使用獨立的JVM,通過(guò)設置fork屬性為true就可以了。同時(shí),你還必需以嵌套值的方式提供其它的一些值,包括TestRunner要運行的測試類(lèi)名以及需要用到的類(lèi)路徑:

  <target name="Test" depends="-Init " description="Run JUnit
    <!-- Run test suite using separate JVM -->
    <java fork="yes" classname="junit.textui.TestRunner" taskname="junit" failonerror="true">
      <arg value="${alltests}"/>
      <classpath>
        <pathelement path="${java.class.path}"/>
        <pathelement location="${bin}"/>
        <pathelement location="${log4j_path}"/>
        <pathelement location="${junit_path}"/>
      </classpath>
    </java>
    <echo message="Tested!"/>
  </target>

  Javadoc目標包括了你在這里用到的絕大多數復雜任務(wù)。首先,你需要在javadoc標簽中,以屬性來(lái)指定包名(packagename)和你要包含的Javadoc備注。然后,由于要排除掉單元測試,你要使用一個(gè)嵌套的<fileset>,里面依次包含嵌套的標簽<include>和<exclude>:

  <target name="Javadoc" depends="-Init" description="Create Javadoc">
    <!-- Javadoc, only for persistence classes -->
    <javadoc destdir="${doc}" author="true" version="true" use="true" package="true">
      <fileset dir="${src}/${relpersistencepath}">
        <include name="**/*.java"/>
        <exclude name="**/*Test*"/>
      </fileset>
      <classpath>
        <pathelement path="${java.class.path}"/>
        <pathelement location="${junit_path}"/>
        <pathelement location="${log4j_path}"/>
      </classpath>
    </javadoc>
    <echo message="Javadoc complete."/>
  </target>

  目標Jar相當明了。正如你在javadoc任務(wù)中所做的一樣,你在這里使用一個(gè)<fileset>來(lái)指定要排除的測試文件。由于用戶(hù)需要log4j.properties文件,你還得拷貝它:

  <target name="Jar" depends="-Init ">
    <!-- Jar for persistence classes -->
    <jar destfile="${jarfile}"
      basedir="${bin}"
      includes="${relpersistencepath}/*.class"
      excludes="**/*Test*"
    />
    <echo message="${bin}${relpersistencepath}/**"/>
    <!-- Copy log4j.properties to provide a sample -->
    <copy file="log4j.properties" todir="${dist}"/>
    <echo message="Packaging complete"/>
  </target>

  最后,該是內部目標了:-Init和-Prep。(它們的名字用一個(gè)連字符開(kāi)頭,這可以避免它們被直接使用。雖然這不是必需的,但實(shí)踐證明這是個(gè)好辦法,因為這能令你的意圖更明確清晰。)-Init打印時(shí)間。所有的主目標都依賴(lài)于它:

  <!-- Internal targets -->
  <target name="-Init"> <!-- private target, omit description-->
    <!-- Set timestamp and print time -->
    <tstamp/>
    <echo message="Build time: ${TODAY} ${TSTAMP}"/>
  </target>

  -Prep僅當你指定了BuildAll目標時(shí)調用。它從以前的構建中刪除所有東西──特別是bin和dist目錄:

  <target name="-Prep">
    <!-- Delete output directories -->
    <delete dir="${bin}"/>
    <delete dir="${dist}"/>
    <delete dir="${jardir}"/>
    <!-- Create output directories -->
    <mkdir dir="${bin}"/>
    <mkdir dir="${dist}"/>
    <mkdir dir="${jardir}"/>
  </target>
</project>

5.4.2 執行一個(gè)構建

  運行Ant構建文件和以前一樣──在build.xml上右擊鼠標并選擇[運行Ant]。但現在你有更多的選項,這是因為你有更多目標。注意,默認目標BuildAll已經(jīng)被自動(dòng)選中了,不過(guò)你可以用復選框選擇其它目標。例如,你可以選擇Compile和Javadoc(見(jiàn)圖5.5)。

圖5.5 你可以在A(yíng)nt構建對話(huà)框中顯式選擇目標


  你也可以設置目標執行的順序,只需點(diǎn)擊[排序]按鈕來(lái)打開(kāi)如圖5.6所示的對話(huà)框。點(diǎn)擊一個(gè)目標并點(diǎn)擊[上移]或[下移]來(lái)改變它的構建順序。選擇好之后,點(diǎn)擊[確定]并點(diǎn)擊[運行]來(lái)開(kāi)始構建。

圖5.6 目標排序對話(huà)框。在這里,你可以改變目標執行的順序。


  和以前一樣,輸出會(huì )顯示在控制臺視圖。不同類(lèi)型的消息會(huì )用不同顏色顯示:Ant狀態(tài)消息是綠色,<echo>消息是橙色,而錯誤──有的話(huà)──是紅色。
  如果你很小心,而且沒(méi)有作出僅對當前Eclipse環(huán)境有效的假定(例如所依賴(lài)的類(lèi)路徑設置只有你的Eclipse配置才有),你應該能夠在命令行構建。要這么做的話(huà),只需在命令行下鍵入ant,就像你在示例Hello中所做的一樣。
  你已經(jīng)注意包含了項目描述和主目標,這樣一來(lái),別人能比較容易使用你的構建文件,因為他們可以在命令行下鍵入ant -projecthelp。這樣會(huì )輸出以下內容:

C:\eclipse\workspace\persistence>ant -projecthelp
Buildfile: build.xml

Build file for persistence component,
org.eclipseguide.persistence

Main targets:

BuildAll Complete rebuild. Calls Init, Compile, Test, Javadoc, Pa
Compile Compile all Java classes
Javadoc Create Javadoc
Test Run JUnit tests

Default target: BuildAll

  不過(guò)由于A(yíng)nt和Eclipse集成在一起,在Eclipse里運行構建文件有不少好處──尤其是當你剛開(kāi)始開(kāi)發(fā)時(shí)。

5.4.3 調試構建

  雖然Eclipse和Ant沒(méi)有為Ant提供一個(gè)調試器,但它們可以幫助識別和糾正可能發(fā)生的多種類(lèi)型的錯誤。抵御錯誤的最前線(xiàn),自然是由編輯器提供的語(yǔ)法高亮了。在A(yíng)nt編輯器中,備注一般是紅色的,文本內容是黑色的,標簽和屬性是藍色的,屬性值是綠色的。如果什么東西的顏色和應有的不同(例如有幾行代碼顯示為紅色),這會(huì )很明顯,而你就能知道有什么錯了。
  然而,Ant編輯器的語(yǔ)法高亮并不能標識所有錯誤;除了備注缺少括號和閉標簽之外,你你還需要保存你的構建文件以便能夠正確解析它。在你保存文件之后,錯誤會(huì )被標識在A(yíng)nt編輯器旁邊的大綱視圖中,也會(huì )標識在編輯器的右邊空白處。點(diǎn)擊邊緣的紅框,就會(huì )直接跳到錯誤處(如圖5.7)。

圖5.7 Ant編輯器在右邊空白處標識了一個(gè)語(yǔ)法錯誤。


  有些錯誤只有在你運行構建文件時(shí)才能識別出來(lái)。比如在你使用了一個(gè)無(wú)效屬性時(shí)。假設你記得<javac>使用了<fileset>所使用的屬性和嵌套元素的一個(gè)超集,并且寫(xiě)了如下內容:

<javac dir="${src}" destdir="${bin}">

  確實(shí),<javac>幾乎具有<fileset>所使用的所有屬性;但唯一的不同之處是,<javac>使用srcdir而<fileset>用的是<dir>。如果運行帶有該錯誤的構建文件,當Ant嘗試執行該任務(wù)時(shí),會(huì )導致在調試器窗口顯示如下問(wèn)題:

[javac] BUILD FAILED: file:C:/eclipse/workspace/persistence/
build.xml:38: The <javac> task doesn‘t support the "dir" attribute.

  點(diǎn)擊該錯誤,會(huì )導致Ant嘗試跳轉到非法代碼。當你在文本[javac]上點(diǎn)擊時(shí)──這時(shí)就成功地找到問(wèn)題了。(點(diǎn)擊任何方括號中的任務(wù)名,不只是那些有錯誤的,都會(huì )跳轉到構建文件中的對應代碼。)
  當然,一旦你解決了最初的一些在構建過(guò)程和構建文件中的問(wèn)題,構建問(wèn)題經(jīng)常都涉及到源代碼了。這正是Ant和Eclipse集成的閃光點(diǎn),因為在一個(gè)編譯錯誤上點(diǎn)擊,就會(huì )跳轉到源代碼中產(chǎn)生問(wèn)題的地方。
  例如,假設在FileObjectManager類(lèi)的createObjectManager()方法的參數列表中,你把變量type的名字錯拼為typo。當編譯時(shí),你會(huì )得到一個(gè)“未解析的符號”的錯誤(見(jiàn)圖5.8)。

圖5.8 Ant調試輸出。在一個(gè)錯誤上點(diǎn)擊就會(huì )跳轉到源代碼中的對應行。


  在調試視圖中的錯誤信息上點(diǎn)擊,就會(huì )在編輯器中打開(kāi)相應的源文件,同時(shí)光標會(huì )跳到錯誤所在行。

5.5 總結


  團隊開(kāi)發(fā)對開(kāi)發(fā)過(guò)程提出了新的需求。其中之一就是對協(xié)同團隊中不同開(kāi)發(fā)者的工作并給出一個(gè)正式構建的需求。因為這應該是一個(gè)可重復的過(guò)程,簡(jiǎn)單地給出一個(gè)特別的構建是不夠的。執行一個(gè)正式構建的傳統方法是使用一個(gè)叫做Make的命令行工具;這個(gè)工具具有廣泛的兼容性,在多種不同平臺上都有其對應版本,但它們都有一個(gè)共同的格式,而且語(yǔ)法有些晦澀。
  你當然可以使用Make來(lái)構建Java產(chǎn)品,但Java和傳統編程語(yǔ)言(如C/C++)在需求上有些許不同;首要的一點(diǎn)就是,Java很努力地要成為一門(mén)跨平臺語(yǔ)言,這就使得Make不夠理想。開(kāi)發(fā)Ant很大程度上就是為了滿(mǎn)足這個(gè)需求。同時(shí),除了保留Make的精神外,它還引入了一些新特性,包括XML語(yǔ)法和使用Java類(lèi)的可擴展性。
  因為它和Eclipse的是集成的,一個(gè)Ant構建過(guò)程既可以在Eclipse內部運行,也可以在外部用命令行運行。這樣,在命令行下運行的正式過(guò)程,可以完全獨立于Eclipse。這個(gè)能力提供了額外的好處──開(kāi)發(fā)者們將可以使用任何自己喜歡的開(kāi)發(fā)環(huán)境。
  盡管團隊開(kāi)發(fā)需要一個(gè)構建工具,但Ant的使用并不只局限于團隊。即便是在一個(gè)像Eclipse這樣能夠自動(dòng)編譯代碼并且為創(chuàng )建Javadoc文檔、JAR文件以及p文件提供了很易用的向導的開(kāi)發(fā)環(huán)境中,個(gè)人也可以從Ant的使用中獲益。一個(gè)構建過(guò)程由多個(gè)步驟組成,雖然簡(jiǎn)單,但可能冗長(cháng)乏味并很容易出錯,所以花一點(diǎn)時(shí)間用Ant把構建過(guò)程自動(dòng)化將是一項值得考慮的投資。
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
java 打包
Maven 2.0:編譯、測試、部署、運行
用Maven做項目管理
Openfire服務(wù)端源代碼開(kāi)發(fā)配置指南
phonegap3.4.0 生成PHONEGAP.JAR
Android Studio導入項目的幾種方法
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久