2021年12月25日 星期六

3.2 使用requires相依模組外的套件

建立zoo.animal.care模組

接下來我們要建立zoo.animal.care模組,該模組有2個套件: 

  1. 套件zoo.animal.care.medical包含開放給其他模組使用的類別和方法。 
  2. 套件zoo.animal.care.details只供模組自己使用,不對外開放,可以視為動物的醫療隱私。

下圖顯示該模組的內容。記得所有模組都必須有1個模組資訊文件!

和建立模組zoo.animal.feeding的處理方式一樣:

  1. 使用Eclipse建立專案zoo.animal.care。
  2. 建立2個套件。
  3. 每個套件下建立各自類別。
  4. 建立模組資訊檔案module-info.java。

模組的2個類別如下,因為只是要驗證模組對存取控制的效果,基本上都沒有甚麼內容:

package zoo.animal.care.details;
import zoo.animal.feeding.Task;
public class HippoBirthday {
    private Task task;
}
package zoo.animal.care.medical;
public class Diet {
}
這次module-info.java比較特別:
module zoo.animal.care {
    exports zoo.animal.care.medical;
    requires zoo.animal.feeding;
}
行1指定模組的名稱,行2使用exports指出要公開的套件,以便後續其他模組可以使用它。到目前為止和模組zoo.animal.feeding是相似的。
在行3使用「requires」關鍵字指定本模組將相依於zoo.animal.feeding模組,這也是和先前模組最大差異的地方。
另外和前模組一樣,我們也在與src目錄的同一檔案階層建立了一個名為mods的目錄,然後將前一個專案打包好的zoo.animal.feeding.jar放入其中。前述步驟都完成後,專案結構如下:

編譯和打包zoo.animal.care模組

建立模組後,讀者可以發現某些*.java檔案在Eclipse內將編譯失敗,這是因為我們只使用Eclipse建立模組專案,但並未設定Eclipse專案間的相依關係,後續會再說明。而且目前編譯使用javac的指令進行,是否編譯失敗以管理者視窗的輸出結果為主。
仿照前之前的方式開啟以模組專案zoo.animal.care的根目錄為預設路徑的管理者視窗,執行以下指令進行編譯:

javac 
--module-path mods
-d src 
src/zoo/animal/care/details/*.java src/zoo/animal/care/medical/*.java src/module-info.java
編譯模組過程未出現錯誤訊息:
進行打包的指令如下:
jar  
-cvf mods/zoo.animal.care.jar 
-C src/ .

更新(refresh)專案後,可以看到src目錄下出現*.class檔案,而且mods目錄內有zoo.animal.care.jar檔案:

建立、編譯、打包zoo.animal.talks模組

接下來的模組相依情形會愈來愈明顯。

由圖7-1我們知道zoo.animal.talks模組相依於zoo.animal.feeding模組和 zoo.animal.care模組,這也表示著module-info.java檔案中必須有2個requires 關鍵字。模組zoo.animal.talks的內容可以參考圖7-2,這裡就不在重複。此外模組zoo.animal.talks具備的3個套件將全部開放。以下列舉各套件的各類別內容:

1. 套件zoo.animal.talks.content的類別ElephantScript內容如下:

package zoo.animal.talks.content;
public class ElephantScript {
}
2. 套件zoo.animal.talks.content的類別SeaLionScript內容如下:
package zoo.animal.talks.content;
public class SeaLionScript {
}
3. 套件zoo.animal.talks.media的類別Announcement 內容如下:
package zoo.animal.talks.media;
public class Announcement {
    public static void main(String[] args) {
        System.out.println("We will be having talks");
    }
}
4. 套件zoo.animal.talks.media的類別Signage 內容如下:
package zoo.animal.talks.media;
public class Signage {
}

5. 套件zoo.animal.talks.schedule的類別Weekday 內容如下:

package zoo.animal.talks.schedule;
public class Weekday {
}
6. 套件zoo.animal.talks.schedule的類別Weekend 內容如下:
package zoo.animal.talks.schedule;
public class Weekend {
}
7. 最後,模組資訊檔module-info.java內容如下:
module zoo.animal.talks {
    exports zoo.animal.talks.content;
    exports zoo.animal.talks.media;
    exports zoo.animal.talks.schedule;
    requires zoo.animal.feeding;
    requires zoo.animal.care;
}

另外和前模組一樣,我們也在與src目錄的同一檔案階層建立了一個名為mods的目錄,然後將前2個專案打包好的zoo.animal.feeding.jarzoo.animal.care.jar放入其中。前述步驟都完成後,專案結構如下:

模組專案建立完畢之後,仿照前之前的方式開啟以模組專案zoo.animal.talks的根目錄為預設路徑的管理者視窗,執行以下指令進行編譯:
javac 
--module-path mods
-d src 
src/zoo/animal/talks/content/*.java
src/zoo/animal/talks/media/*.java
src/zoo/animal/talks/schedule/*.java
src/module-info.java

執行以下指令進行打包:

jar  
-cvf mods/zoo.animal.talks.jar 
-C src/ .

更新(refresh)專案後,可以看到src目錄下出現*.class檔案,而且mods目錄內有zoo.animal.talks.jar檔案:

建立、編譯、打包zoo.staff模組

由圖7-1我們知道最後一個模組zoo.staff相依於其他3個模組,這也表示著module-info.java檔案中必須有3個requires 關鍵字。模組zoo.staff的內容如下:

唯一的套件與類別:

package zoo.staff;
public class Jobs {
}

模組資訊檔module-info.java內容如下:

module zoo.staff {
    requires zoo.animal.feeding;
    requires zoo.animal.care;
    requires zoo.animal.talks;
}

另外和前模組一樣,我們也在與src目錄的同一檔案階層建立了一個名為mods的目錄,然後將前3個專案打包好的zoo.animal.feeding.jar、zoo.animal.care.jar、zoo.animal.talks.jar都放入其中。前述步驟都完成後,專案結構如下:


模組專案建立完畢之後,仿照前之前的方式開啟以模組專案zoo.staff的根目錄為預設路徑的管理者視窗,執行以下指令進行編譯:
javac 
--module-path mods
-d src 
src/zoo/staff/*.java
src/module-info.java

執行以下指令進行打包:

jar  
-cvf mods/zoo.staff.jar 
-C src/ .

更新(refresh)專案後,可以看到src目錄下出現*.class檔案,而且mods目錄內有zoo.staff.jar檔案:



沒有留言:

張貼留言