指令java除了可以執行Java SE類別裡的main()方法之外,還有與模組相關的選項,常見有以下3個:
java指令選項 |
作用 |
--describe-module |
描述模組內容 |
--list-modules |
列舉可用模組清單 |
--show-module-resolution |
解析模組執行時的步驟 |
因為專案zoo.staff的mods目錄內有打包好的全部的模組JAR檔案,因此執行指令時預設的路徑是專案zoo.staff的根目錄,以本書為例是C:\java11\code\zoo.staff。
後續將逐一說明與示範。
使用選項--describe-module
假設我們拿到一個模組zoo.animal.feeding的JAR檔案,並且想了解它的模組結構。我們可以把該JAR檔案與以解壓縮並瀏覽module-info.java檔案如下。檔案內容顯示該模組exports一個套件並且不需要任何模組:
module zoo.animal.feeding {
exports zoo.animal.feeding;
}
不過還有一種更簡單的方法,就是使用java指令的「--describe-module」選項來描述一個模組:java -p mods --describe-module zoo.animal.feeding指令選項「--describe-module」可以使用「-d」簡化,所以執行指令「java -p mods -d zoo.animal.feeding」時可以得到相同的結果:
摘錄文字結果:
1 |
zoo.animal.feeding
file:///C:/java11/code/zoo.animal.feeding/mods/zoo.animal.feeding.jar |
2 |
exports zoo.animal.feeding |
3 |
requires java.base mandated |
說明:
1 |
輸出模組名稱與JAR實體檔案路徑。 |
2 |
exports套件zoo.animal.feeding,這部分與模組資訊檔內容相同。 |
3 |
這一行是模組系統自動加上的。 如同編寫類別程式碼時會自動imports基礎java.lang套件,模組系統也會自動註記所有模組都需要基本的java.base模組,關鍵字「mandated」就是如此意含,指出如java.base模組並沒有明確宣告在模組資訊檔中,但因為規格授權還是會自動出現。 |
類似的情境,針對模組zoo.animal.care,再比較模組資訊檔與java指令描述模組的差異。模組資訊檔如下:
module zoo.animal.care {
exports zoo.animal.care.medical;
requires transitive zoo.animal.feeding;
}
執行指令「java -p mods -d
zoo.animal.care」將得到以下結果:
zoo.animal.care
file:///C:/java11/code/zoo.animal.care/mods/zoo.animal.care.jar |
|
2 |
exports
zoo.animal.care.medical |
3 |
requires
java.base mandated |
4 |
requires zoo.animal.feeding
transitive |
5 |
contains zoo.animal.care.details |
指令結果比模組資訊檔多了行3與行5。行3在前例已經解釋,行5則是點出了模組內未以exports公開的套件。
使用選項--list-modules
除了描述模組之外,還可以使用java指令列出可用的模組。未指定模組JAR檔案路徑時,將列出屬於JDK的模組:以下是指令java --list-modules
的執行結果:
輸出的行數很多,這裡只節錄開頭幾行。內容是Java內建的所有模組及其版本號的列表,可以看出執行指令是Java的11.0.12版。
若指令中包含zoo專案的所有模組JAR檔案:
java -p mods --list-modules
則執行結果就是前述的行內容加上4個zoo專案的模組JAR檔:
使用選項--show-module-resolution
java --show-module-resolution
-p src
-m zoo.animal.feeding/zoo.animal.feeding.Task
以下節錄過程的一些輸出內容,最後一行是執行結果:
root zoo.animal.feeding
file:///C:/java11/code/zoo.animal.feeding/src/ |
java.base binds jdk.localedata
jrt:/jdk.localedata |
java.base binds jdk.zipfs
jrt:/jdk.zipfs |
java.base binds jdk.charsets
jrt:/jdk.charsets |
java.base binds jdk.security.auth
jrt:/jdk.security.auth |
... |
java.security.sasl requires
java.logging jrt:/java.logging |
java.naming requires
java.security.sasl jrt:/java.security.sasl |
jdk.security.jgss requires
java.logging jrt:/java.logging |
... |
All are fed! |
它首先列出根(root)模組,本例是zoo.animal.feeding;然後列出了java.base模組所包含的多行套件,也會列出具有相依關係的模組。最後它輸出指定類別zoo.animal.feeding.Task的執行結果。
沒有留言:
張貼留言