認識 Gradle


若要使用 Spring,在 Spring 3.x 或之前的版本中,可以在 Spring 官方網站直接下載 JAR 檔案,然而從 4.x 開始,推薦使用 Gradle 或 Maven 來下載,Spring 本身是使用 Gradle 來管理,為了要能更方便地使用 Spring,認識 Gradle 是必要的課題。

在 Java 中要開發應用程式,必須撰寫原始碼、編譯、執行,過程中必須指定類別路徑、原始碼路徑,相關應用程式檔案必須使用工具程式建構,以完成封裝與部署,嚴謹的應用程式還有測試等階段。

像這類的工作, IDE 解決了部份問題,然而,對於重複需要自動化的流程,單靠 IDE 提供之功能不易解決,因而 Java 的世界中,提供有建構工具來輔助開發人員,在建構工具中元老級的專案是 Ant(Another Neat Tool),使用Ant在專案結構上有很大的彈性,然而彈性的另一面就是鎖碎的設定。

另一方面,類似專案會有類似慣例流程,如果能夠提供預設專案及相關慣例設定,對於開發將會有所幫助,這就是 Maven 後來興起的原因之一,除了提供預設專案及相關慣例設定之外,對於 Java 中程式庫或框架相依性問題, Maven 也提供了集中式貯藏室(Central repository) 解決方案;對於相依性管理問題 Ant 也結合了 Ivy 來進行解決。

然而無論是 Ant Ivy、Maven,主要都使用 XML 進行設定,設定繁鎖,而且有較高的學習曲線,Gradle 結合了 Ant 與 Maven 的一些好的概念,並使用 Groovy 語言作為腳本設定,在設定上有了極大的簡化,並可以輕易地與 Ant、Maven 進行整合,種種優點吸引了不少開發者,有些重大專案,像是 Spring、Hibernate 等,也宣佈改用 Gradle 做為建構工具。

接下來要介紹的,就是 Gradle 的下載與設定,可以在〈Gradle | Release〉下載 Gradle 的 zip 壓縮版本,撰寫本文之時的版本是 4.10.2,解壓縮之後會有個 gradle-4.10.2 資料夾,其中 bin 資料夾放置了 gradle 執行檔,為了便於使用,可以在 PATH 環境變數中增加該 bin 資料夾的路徑,之後開啟文字模式,就可以使用 gradle 指令,可使用 gradle -v 得知 Gradle 版本。

在文字模式中編譯、執行 Java 應用程式有些麻煩,實際上在編譯 .java 原始碼時,如果有多個 .java 檔案及已經編譯完成的 .class 檔案的話,必須指定 -classpath-sourcepath 等,這些都可以讓 Gradle 來代勞。

首先可以建立一個 HelloWorld 資料夾,Gradle 的慣例期待 .java 原始碼會置放在 src\main\java 資料夾,依套件階層放置,假設在 HelloWorld\src\main\java\cc\openhome 中有個 Main.java:

package cc.openhome;

public class Main {
    public static void main(String[] args) {
        System.out.printf("Hello, %s%n", args[0]);
    }
}

接著需要在專案資料夾中建立一個 build.gradle 檔案:

apply plugin: 'java'
apply plugin:'application'
mainClassName = "cc.openhome.Main"

run {
    args username
}

'java' 的 plugin 為 Gradle 專案加入了 Java 語言的原始碼編譯、測試與打包(Bundle)等能力;'application' 的 plugin 擴充了語言常用的相關任務,像是執行應用程式等;mainClassName 指出了從哪個位元碼檔案的 main 開始執行。run 這個任務中,使用 args 指定了執行位元碼檔案時給定的命令列引數。

接著可以在 HelloWorld 資料夾中如下執行 Gradle:

>gradle run -Pusername=Justin

> Task :run
Hello, Justin

BUILD SUCCESSFUL in 1s
2 actionable tasks: 2 executed

方才的範例中,必須自行建立 .java 對應的套件資料夾,若能結合IDE的話會省事許多,目前最新版本的 Eclipse 內建了 Gradle 的支援,最簡單的方式使用 Eclipse 內建的 Gradle Project,在預設的 build.gradle 中,已經撰寫了一些定義:

apply plugin: 'java-library'

repositories {
    // 預設的相依程式庫來源
    jcenter()
}

dependencies {
    // 這邊可以宣告相依的程式庫資訊
    api 'org.apache.commons:commons-math3:3.6.1'
    implementation 'com.google.guava:guava:21.0'
    testImplementation 'junit:junit:4.12'
}

Gradle 會自動下載這些相依的JAR檔案,預設會將 JAR 檔案儲存在使用者資料夾的 .gradle\caches 之中,並自動設定好專案的類別路徑資訊,如果需要新的程式庫,例如 JavaMail,可以在 build.gradle 中定義:

接著在專案上按右鍵執行「Gradle/Refresh Gradle Project」,就會下載相依的 JAR 檔案,如果程式庫還有相依於其他程式庫,相關的 JAR 檔案也會一併下載,這就是使用 Gradle 的好處,不用為了程式庫間複雜的相依性而焦頭爛額。

想要執行程式的話,同樣只需要在原始碼上按右鍵執行「Run As/Java Application」就可以了。

如果是既有的 Java 應用程式專案,可以直接在專案上按右鍵執行「Configure/Add Gradle Nature」,讓既有的專案支援最基本的 Gradle 特性,接著在專案上按右鍵執行「New/File」建立 build.gradle 檔案,在其中撰寫定義。

同樣地,接著在專案上按右鍵執行「Gradle/Refresh Gradle Project」,就會下載相依的 JAR 檔案,如果程式庫還有相依於其他程式庫,相關的 JAR 檔案也會一併下載。

想要執行程式的話,同樣只需要在原始碼上按右鍵執行「Run As/Java Application」就可以了。

在 Eclipse 中匯入 Gradle 專案之後,記得在專案上按右鍵執行「Gradle/Refresh Gradle Project」,重新整理專案中相依的程式庫資訊。