module com.jenkov.mymodule {
exports com.jenkov.mymodule;
exports com.jenkov.mymodule.util;
}
Tomáš Pitner, Radek Ošlejšek, Marek Šabo, Jakub Čecháček pitner@muni.cz
struktura (třídy, balíky, moduly)
zavádění (classloaders)
další zdroje (resources)
reflexe
Javový program sestává z alespoň jedné třídy s alespoň jednou metodou
Má-li být spustitelný z příkazové řádky, pak s metodou main
Ve spoustě nasazení - webové aplikace, aplikační kontejnery - není main
třeba
Třídy se obvykle sdružují do balíků - deklarace package xx.yy.zz
Nově od Java 9 jsou balíky - přinejmenším v Core API - sdruženy do modulů (Modules)
Moduly kromě tříd samotných mohou obsahovat další zdroje (resources) a obsahují popisovač (module descriptor file)
Cílem je lepší znovupoužitelnost a potřeba u rozsáhlých programů lépe organizovat kód
zabalit celou aplikaci nebo API jako samostatný modul
umožnit sledování a zajištění závislostí mezi moduly
napodobit "dohnat" to, co už jazyky jako JavaScript nebo Python mají
technicky jde o soubor JAR s celým modulem, tzn. popisovačem, třídami, příp. dalšími zdroji
dříve bylo třeba umísťovat zdroje do kořenové úrovně projektu a ručně je spravovat
nyní lze na jemnější úrovni modulů - podle toho, který zdroj je kde potřeba
název modulu (pojmenování modulů podobně jako u balíků, tj. tečky jsou povoleny, pomlčky nikoli; časté je pojmenování ve stylu projektu (my.module
) nebo ve stylu Reverse-DNS jako u balíků (com.baeldung.mymodule
)
seznam dalších modulů, na kterých tento modul závisí
seznam všech balíků, které chceme mít přístupné mimo modul (ve výchozím nastavení jsou všechny balíky soukromé)
můžeme poskytovat implementace služeb (services), které mohou být využívány jinými moduly
seznam služeb využívaných tímto modulem
explicitně povoluje ostatním třídám používat reflexi pro přístup k soukromým (private
) prvkům balíku (ve výchozím nastavení jsou všechny třídy nepřístupné pro reflexi)
veřejné balíky, viditelné zvnějšku
module com.jenkov.mymodule {
exports com.jenkov.mymodule;
exports com.jenkov.mymodule.util;
}
je třeba exportovat skutečně jaždý balík, který chceme zviditelnit ven - tzn. i ten …util
závislost na ostatních balících
module com.jenkov.mymodule {
requires com.jenkov.mymodule;
requires com.jenkov.mymodule.util;
}
cyklické závislosti nejsou přípustné: module.a
závisí na module.b
, který závisí na module.a
NE, jeden balík smí být současně exportován v max jednom modulu
v jedné aplikaci se nesmí potkat balík exportovaný současně dvěma moduly, dvěma cestami
a to ani v případě, že by ve skutečnosti jedna třída byla vždy jen v jednom modulu
Ani uvedené dva exporty nejsou možné:
module cz.muni.fi.pb162.mod1 {
exports cz.muni.fi.pb162.bank;
}
balík cz.muni.fi.pb162.bank
v tomto modulu obsahuje jen třídu Bank
...
module cz.muni.fi.pb162.mod2 {
exports cz.muni.fi.pb162.bank;
}
balík cz.muni.fi.pb162.bank
v tomto modulu obsahuje jen třídu Account
kompilace: javac -d out --module-source-path src/main/java --module com.jenkov.mymodule
spuštění aplikace v modulu: java --module-path out --module com.jenkov.mymodule/com.jenkov.mymodule.Main
vytvoření JAR archívu s modulem: jar -c --file=out-jar/com-jenkov-mymodule.jar -C out/com.jenkov.mymodule .
(-c
create, --file
soubor s výsledným JAR, -C
change directory změna adresáře před sbalením JARu)
spuštění z JAR: java --module-path out-jar -m com.jenkov.mymodule/com.jenkov.mymodule.Main
spuštění hlavní třídy (Main-Class) z JAR: java -jar out-jar/com-jenkov-javafx.jar
Moduly umožňují pohodlně vytvořit spustitelný JAR se všemi závislostmi bez ručního jednotlivého "přibalování"
Nástroj jlink
jlink --module-path "out;C:\Program Files\Java\jdk-9.0.4\jmods" --add-modules com.jenkov.mymodule --output out-standalone
--module-path
složka jmods
obsahuje standardní Core API moduly a out
je složka s našimi předkompilovanými moduly
--add-modules
které moduly se mají do aplikace sbalit, v tomto případě com.jenkov.mymodule
--output
cílová složka pro umístění JAR s aplikací
Spuštění výsledného JAR: java --module com.jenkov.mymodule/com.jenkov.mymodule.Main