建立模組專案
建立套件、類別與模組資訊檔案
首先建立專案zoo.animal.feeding與套件zoo.animal.feeding,本例專案名稱與套件名稱相同;然後建立簡單的類別Task.java,內容如下:package zoo.animal.feeding; public class Task { public static void main(String... args) { System.out.println("All are fed!"); } }
接下來是建立模組資訊(module info)檔案。模組資訊檔案和一般Java類別之間有一些主要區別:
- module-info檔案必須位於模組的根目錄中,一般Java類別應該在套件中。
- module-info檔案內容宣告模組時使用關鍵字module而不是class、interface或enum。
- 模組檔案名稱遵循套件名稱的命名規則,它的名稱中通常包含「.」。一般類別和套件名稱不允許有「-」,但模組可以。
module zoo.animal.feeding { }
此外,我們在與src目錄的同一檔案階層建立了一個名為mods的目錄,我們將在本章稍後部分使用它來存放與自身模組相依的其他模組。這個目錄可以任意命名,但mods是一個比較通用名稱。完成後專案目錄結構如下:
專案結構的src目錄是模組目錄,模組資訊檔案就在它根目錄。我們也有zoo.animal.feeding套件,以作業系統的角度來看每一層套件就表示一個子目錄,可以由Eclipse的Project Explorer和Navigator比較。Task類別位於其套件的相應子目錄中。
使用Eclipse建立的專案預設會將*.java檔案自動編譯為*.class檔案,並存放在專案內的bin目錄中。不過我們只是使用Eclipse協助建立專案,後續編譯將以指令進行。
編譯模組專案
在可以執行模組化程式碼之前,需要先予以編譯,指令如下。為了說明指令列選項讓讀者容易理解,因此拆解成4行,實際執行時必須合併為1行,或是使用作業系統的斷行符號,如Linux使用「\」:
javac --module-path mods -d src src/zoo/animal/feeding/*.java src/module-info.java
說明:
2 |
使用選項「--module-path」指示任何自定義模組檔案的位置,本例是mods目錄。由於mods目前沒有任何相依模組檔案,因此可以忽略本選項。此外選項「--module-path」和大家熟悉的選項「-classpath」相似,當處理模組化程式時,可以將「--module-path」視為替換「-classpath」選項。 |
3 |
使用選項「-d」指定放置編譯完成的類別檔案的目錄。 |
4 |
指令的結尾是要編譯的Java檔案清單。可以單獨列出這些檔案,也可以對子目錄中的所有Java檔案使用萬用字元「*.java」。使用空白(space)區隔清單內容。 |
就像類別路徑一樣,我們可以在指令列中使用縮寫。選項「--module-path」和「-p」是等效的,因此前述指令列可以修改如下:
javac -p mods -d src src/zoo/animal/feeding/*.java src/module-info.java
以本例而言,執行指令時必須在src資料夾。要找出src目錄的路徑可以在src目錄的節點上以滑鼠右鍵點擊,選擇Properties:
彈出「Properties for src」視窗後點擊以下Location圖式:在彈出的檔案總管視窗的資料夾路徑處,改鍵入「cmd」文字並點擊鍵盤Enter鍵:
彈出系統管理員視窗,且目前路徑即為專案的src目錄:
範例專案每一個的*.java將伴隨著*.class檔案:
在一開始學習Java時理解java與javac指令是必要的。但實際在開發專案時,如果繼續組裝指令列會發現它們變得冗長而復雜。我們使用Eclipse開發時,編譯和執行都由IDE代勞;若要結合DevOps的開發流程,大多數開發人員會使用自動化構建工具,例如Maven或Gradle。讀者若對這些進階內容有興趣,可以參考「Spring Boot情境式網站開發指南:使用Spring Data JPA、Spring Security、Spring Web Flow」一書的「CH1. 使用Maven管理Java專案」。
執行模組專案
在打包模組之前,我們應該先確認該模組是否可以正確執行。為此我們需要了解完整的語法。假設有一個名為lab.module的模組,該模組中具備org.some的套件,和帶有一個main()方法的Test的類別。下圖顯示了執行模組的語法,特別注意lab.module/org.some.Test部分。請務必記住指定的模組名稱後跟著「/」,之後才是完整的類別名稱。現在我們已經理解了語法,可以編寫指令來執行zoo.animal.feeding套件中的Task類別。在以下指令中,套件名稱和模組名稱相同,都是zoo.animal.feeding。模組名稱經常會與套件的完整名稱相同,或是取套件開頭的幾個名稱空間(namespace),如zoo.animal。java
--module-path src
--module zoo.animal.feeding/zoo.animal.feeding.Task
2 |
使用「--module-path」選項指定模組路徑,也可以使用「-p」。 |
3 |
使用「--module」指定執行對象,也可以使用「-m」。 執行對象以「/」區隔。之前為模組名稱,之後為完整的套件和類別名稱。 |
在本範例中行2使用src作為模組路徑,是因為這是本專案、同時也是前一個範例編譯後產出*.class的地方。後續範例打包模組成為JAR檔案時,執行時就會改指定JAR檔案位置。
執行「java -p src
-m zoo.animal.feeding/zoo.animal.feeding.Task」後可以得到視窗輸出「All are fed!」字樣:
打包模組專案
如果我們只能在建立模組的路徑如src目錄中執行它,那程式模組化的用處就不大。我們的下一步是打包它,讓模組可以在其他地方執行,或是給其他模組使用。指令如下:
jar
-cvf mods/zoo.animal.feeding.jar
-C src/ .
2 |
使用「-cvf」選項指定要打包為JAR檔案。 本例中「mods」是JAR檔案的產出目錄,要事先建立。「zoo.animal.feeding.jar」是JAR檔案名稱。 |
3 |
使用「-C」指定編譯好的*.class檔案位置。 本例中「src/ .」表示路徑src內的所有檔案。 |
事實上該指令不只可以打包Java的模組化程式為一個JAR檔案,即便「非模組化」程式也是相同的打包指令。打包完成後該Java程式就可以給其他專案使用!
以指令「jar -cvf
mods/zoo.animal.feeding.jar -C src/ .」進行打包:
更新(refresh)專案後,可以看到mods目錄出現zoo.animal.feeding.jar檔案:
現在讓我們以打包後的模組化JAR檔案執行程式:
java
--module-path mods
--module zoo.animal.feeding/zoo.animal.feeding.Task
執行「java -p mods -m
zoo.animal.feeding/zoo.animal.feeding.Task」後可以得到視窗輸出「All are fed!」字樣:
沒有留言:
張貼留言