iT邦幫忙

DAY 3
5

Modern Java Programming 技術漫談系列 第 3

認識 Gradle 專案建置自動化工具

Gradle 簡單說就是 Java 世界的 Makefile,它可以幫忙打理那些在專案開發過程中的瑣事,舉凡編譯、測試、檢查程式碼、產生文件、清理或壓縮檔案、上傳、發佈、重新啟動伺服器到送出電子郵件,都可以利用 Gradle 撰寫的 Script 來自動完成作業。

它的應用不僅只用於 Java 的開發領域,它和其他語言的開發環境也可以搭配使用,同樣可以有很多派上用場的機會。


(Building and Testing with Gradle)
Gradle 的優點很多,主要包括:

* 簡單易用:它以 Groovy 語言為基礎,用簡單易懂的 DSL 語法定義任務,開發者不必瞭解 Java 語言就能上手。
* 套件豐富:內建的 Plug-in 設計讓它有愈來愈豐富的套件可用,可依照專案的需求尋找合適的套件或自己開發一個。
* 後台強硬:由於 Java 長久發展累積豐富的函式庫,可以用 JasperReport 產生專業報表、用 JavaMail 處理電子郵件、執行 Jetty 內嵌網頁伺服器、透過 Rhino 執行 JavaScript 程式、以 JGit 處理專案版本控管任務等。
* 跨平台:在裝有 Java 的作業系統,就能執行定義好的 Gradle 程式。像是 Makefile 就必須考慮用的指令需要在其他作業系統也能有相應的程式。

很多 Groovy 或 Java 的開發者,早在 2011-2012 年就開始使用 Gradle 作為專案的建置工具,只是早期(1.0版以前)它有不少 Bug 並且效能不彰;但這一切都在今年有所改變---Gradle 正在以更快的速度成長,愈來愈多開發者使用它。

Google 在 2013 年將 Gradle 正式用於 Android SDK 的 Build System,這是再適合不過的選擇,對於 Java 專案的開發來說,目前並沒有比 Gradle 更好的選擇。

對於 Java 開發者來說,「自動建置」一直存在許多問題:

* 受歡迎的 Eclipse IDE 「專案」僅內建陽春的編譯和測試、打包流程;過去通常搭配 Ant 來處理進階的自動建置需求。
* Ant 可以處理相當多任務,但 Ant 本身無法管理 Dependency 問題,需要搭配 Ivy 處理函式庫依賴關係。
* 時至今日專案更講究套件管理(Package Management)的觀念,Maven 及許多 Open Source Maven Repository 的出現,終於有解決方案;但是使用及定義 Maven 又有不低的學習門檻。

Maven 的出現讓 Java Library 有統一的形式定義 metadata,並讓 Open Source 的 Library 更容易共享。例如專案如果用到 Apache Commons Codec 這個 Library,就只要用一段 XML 宣告依賴關係。

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.8</version>
</dependency>

在過去 Java 開發者經常要尋找 *.jar 下載到專案的 lib/ 資料夾下,如果 A.jar 依賴其他 Library 如 B.jar 或 C.jar,還要另外下載並避免相依性不足或衝突的問題。當一個專案變得龐大,這些套件檔案佔用磁碟容量變得相當大,不只造成版本管理系統無謂的負擔,而且需要耗費人力去維護更新及清理用不到的檔案。

在 Groovy 語言加入 Grapes(the GRoovy Adaptable Packaging Engine)的 Grab() 功能後,想使用一個 3rd Party 的 Open Source Java Library 變得非常簡單,只要在程式開頭加入一行宣告。事實上它使用的就是來自 Maven 建立的套件庫(Maven Repositories)。

@Grab('commons-codec:commons-codec:1.8')

多數常用的 Java Library 可以在 MVNRepository 網站找到可用的版本定義:

http://mvnrepository.com

對於一家具有規模的資訊服務公司,也可以自行定義專屬的 Maven Repository 供內部專案使用,讓可以重複利用的 Java Library 變成套件方式定義,並管理其版本以及和其他套件之間的相依性。

例如 Grails(Groovy 的 MVC Framework)就將其 Plug-ins 建立專屬的 Maven Repository,無論是官方或第三方開發者製作的 Plug-in,都可以放到集中的 Repository 伺服器,讓全世界的 Grails 開發者共享這些 Plug-ins 資源,並只要在設定檔中做簡單的宣告定義即可。

Gradle 建立在這些基礎資源上:

* 用 Groovy 提供簡單的 DSL 程式語法定義任務,比 XML 提供更強的可程式特性
* 從 Maven Repository 獲取豐富的套件庫,並徹底簡化定義及使用方式
* 融合 Ant 既有的任務功能,且使用 Groovy DSL 語法定義

對於已經使用 Ant 定義過的 build.xml 設定,仍可用 ant.importBuild 引入既有的任務定義並直接在 Gradle Script 中使用。

ant.importBuild 'build.xml'

安裝 Gradle

Gradle 需要 Java 環境,所以需要先裝好 Java(1.6以上)並正確設定 JAVA_HOME 環境變數。

推薦的 Gradle 安裝方式,是透過 GVM 的 gvm install gradle 指令自動下載安裝最新版(請參考先前有關 GVM 安裝的介紹)。

手動安裝則需要下載檔案(例如:gradle-1.8-bin.zip)並解壓縮,然後正確將執行檔路徑增加到 PATH 環境變數設定(如 C:\gradle
-1.8\bin
路徑)。

下載 Gradle 的網址 http://www.gradle.org/downloads

使用 Gradle

Gradle 也能撰寫 Hello World 程式,最精簡的程式如下。

task hello {
    println "Hello"
}

將檔案儲存為 build.groovy,這個範例包含一個最簡單的 hello 任務定義。

在 build.groovy 的同一個路徑下,執行 gradle -q hello 指令,就可以看到執行結果。

$ gradle -q hello
Hello

與其他建置工具如 Ant 有一個很大的差異,就是 Gradle 並不使用 XML 格式定義任務,而使用 Groovy DSL 語法,所以 Groovy 的程式碼理所當然也能在 Gradle 的任務中使用,例如一個從 1 數到 10 的 Groovy 迴圈程式:

task hello {
    (1..10).each {
        println it
    }
}

因此我們如果要在資料夾中建立文字檔,使用簡單的 Groovy 程式碼就能搞定。以下範例會產生 1.txt ~ 10.txt 文字檔。

task hello {
    (1..10).each {
        new File("${it}.txt") << it
    }
}

在 Gradle 任務中調用 Ant 功能也相當容易,以下範例將 [em].txt 先壓縮成 archive.zip 檔案,再把 [/em].txt 檔案移除,用到 ant.zip 與 ant.delete 功能。

task hello {
    (1..10).each {
        new File("${it}.txt") << it
    }
    ant.zip(destfile: 'archive.zip', basedir: '.', includes: '*.txt')
    ant.delete(dir: '.', includes: '*.txt')
}

若要在任務中執行外部程式,可以使用 Groovy 的方式。

task hello {
    'javac Hello.java'.execute()
}

當然 Gradle 提供更好的做法,若要執行外部程式可以對 Exec 任務進行擴充,用 DSL 的語法讓新任務看起來更有自動化建置工具的風格,例如定義一個「停用 Tomcat 伺服器」專用的任務(到指定資料夾下執行一個程式):

task stopTomcat(type:Exec) {
    workingDir '../tomcat6/bin'

    commandLine './stop.sh'

    standardOutput = new ByteArrayOutputStream()

    ext.output = {
        return standardOutput.toString()
    }
}

是的!您可以將許多需要自動化執行的瑣事,透過 Gradle 定義好任務,然後利用持續整合(CI)或系統自動排程(如 Crontab)自動執行。例如資料庫的維護作業,您甚至可以先用 JDBC 連線到資料庫下完某些查詢後,再去執行 command-line 的工具進行維護作業。

Gradle 賦予任務更明確的定義,使得任務可以被擴充進而重複使用,像是使用 doFirst 或 doLast 讓某個任務的執行前或後先做點其他工作。

本篇先撇開 Java 專案的建置不談,因為 Gradle 可以應用的範圍很廣。但實際上 Gradle 的發展,最初就是為 Java 及 Groovy 專案而生,它對 Java 專案自動化建置流程的處理,肯定會讓第一次使用 Gradle 的開發者有種相見恨晚的感覺。

讓我們明天繼續…


上一篇
GVM - Groovy 的版本管理工具 - Modern Java Programming
下一篇
使用 Gradle 自動化建置 Java 專案(一)
系列文
Modern Java Programming 技術漫談6

2 則留言

0
fillano
iT邦超人 1 級 ‧ 3 年前

沙發 終於搶到沙發

0
pajace2001
iT邦研究生 1 級 ‧ 2 年前

讚讚

我要留言

立即登入留言