1. diel - Úvod do modulov v Jave
Vitajte pri e-learning kurze, v ktorom sa zoznámime s dôležitou funkcionalitou jazyka Java, s modulmi. Dnešný tutoriál bude viac teoretický, vysvetlíme si dôvod ich vzniku, popíšeme základnú štruktúru modulov a ich kľúčové vlastnosti.
Slovo úvodom
Java moduly sa prvýkrát objavili vo verzii Java 9. Autori Javy sa rozhodli, že je potrebné urobiť poriadok v závislostiach jednotlivých balíčkov. Na obrázku nižšie si môžete urobiť predstavu o zmätku, ktorý medzi závislosťami balíčkov panoval:
Obrázok pochádza z oficiálnych stránok OpenJDK.
Ako vidíte, v závislostiach medzi balíčkami existujú tzv. cyklické závislosti, či už priame, alebo nepriame. V rámci modularizácie Javy boli odstránené deprecated triedy alebo celé balíčky. Zmazaním niektorých balíčkov bola docielená menšia veľkosť výslednej JRE. Niektoré časti boli síce z Javy odstránené, ale existujú ďalej vo forme knižníc. Krásnym príkladom je JavaFX. V Jave 8 bola súčasťou JRE, ale od verzie 9 ju v JRE už nenájdeme. Pokiaľ chceme JavaFX ďalej používať, musíme si jej samostatné knižnice do projektu pridať ako závislosti.
Na obrázku nižšie môžeme vidieť výsledok práce na modularizácii Javy 9.
Obrázok nájdeme v dokumentácii pre Javu 9.
V moduloch existuje jasná hierarchia a hlavne v grafe nenájdeme žiadne
cykly. Základný modul, na ktorom sú automaticky závislé všetky ďalšie
moduly, sa nazýva java.base
. Tento modul obsahuje
balíčky, ktoré sú - podľa autorov Javy - nepostrádateľnou súčasťou
každej aplikácie. Medzi tieto balíčky môžeme (okrem iného) nájsť:
java.lang
java.io
java.nio
java.net
java.time
java.util
java.base
module. Všetky ostatné moduly sa musia
explicitne pridať do závislostí (o závislostiach si povieme za
moment).
Štruktúra zložiek JDK
Než sa pustíme do modulov ako takých, treba si povedať niečo o štruktúre zložiek v JDK, pretože od Javy 9 sa veľmi zmenila. V Jave 8 bola štruktúra nasledujúca:
JDK8 predstavuje koreňovú zložku pre celé JDK:
JDK8/bin/
obsahuje všetky nástroje, ktorými JDK disponuje: javac, jar, javadoc a ďalšie,JDK8/db/
obsahuje Java databázy,JDK8/include/
obsahuje hlavičkové súbory pre podporu natívnych jazykov za pomoci JNA,JDK8/lib/
obsahuje knižnice používané na vývoj,JDK8/man/
obsahuje dokumentáciu JDK nástrojov,JDK8/jre/
obsahuje súbory Java Runtime Environment teda to, čo si inštalujú používatelia, aby mohli spúšťať programy v Jave,JDK8/jre/bin/
obsahuje nástroje iba pre spustenie Java aplikácií (.java
) aJDK8/jre/lib/
obsahuje knižnice špecifické iba pre JRE.
Pozrime sa teraz na nové usporiadanie zložiek v Jave 9 a vyššie:
JDK9 predstavuje koreňovú zložku pre celé JDK:
JDK9/bin/
má rovnaký význam ako v Jave 8, sú v nej uložené nástroje JDK,JDK9/conf/
obsahuje konfiguračné súbory,JDK9/lib/
obsahuje privátne knižnice systému, ktoré nie sú určené na použitie mimo systému a nemali by byť modifikované,JDK9/include/
rovnako ako v Jave 8 obsahuje súbory pre podporu natívnych jazykov,JDK9/legal/
obsahuje licencie jednotlivých modulov aJDK9/jmods/
- obsahuje všetky používané moduly tohto JDK.
Ďalej vidíme, že JDK9 priamo obsahuje samostatnú zložku pre moduly -
jmods. V nej nájdeme jednotlivé moduly. Každý súbor v tomto
priečinku má príponu .jmod
. V skutočnosti je to ale obyčajný
zip
archív. V archíve nájdete (okrem iného) skompilované
.class
súbory, konfiguráciu modulu a použité licencie.
Vlastnosti modulov
Keď už sme si povedali dôvody, prečo sa Java modularizovala, poďme sa zamerať na základné vlastnosti modulov. Sú celkom tri:
- silná enkapsulácia (strong encapsulation),
- definícia verejného rozhrania,
- explicitná definícia závislostí.
Z OOP určite poznáte modifikátory prístupu tried:
public
, private
, protected
a tzv.
package-private (trieda bez modifikátora prístupu). Moduly
pridávajú ďalšiu úroveň zapuzdrenia. Táto vlastnosť nám hovorí, že v
základe sú všetky triedy, ktoré vytvoríme v rámci modulu,
neverejné. To znamená, že nebudú dostupné ostatným
modulom.
Definícia verejného rozhrania
Aby bolo možné používať triedy z iných modulov, je potrebné v moduloch špecifikovať, ktoré balíčky budú verejne dostupné. Otvorenie tried vo vnorených balíčkoch sa nedeje automaticky a je potrebné ho špecifikovať manuálne.
Explicitná definícia závislostí
Keď už máme definované, ktoré balíčky budú verejne dostupné, musíme tiež definovať, ktoré balíčky budeme vyžadovať na beh našej aplikácie. Tu je dôležité, aby sme si pojem definície závislostí neplietli s použitím závislostí pomocou Mavenu či Gradlu. Maven / Gradle nám (okrem iného) sprístupní knižnicu požadovanej verzie. Avšak aj knižnica môže obsahovať viac modulov. A moduly, ako už vieme, musia definovať verejné rozhranie.
Classpath a Modulepath
Classpath by sme už mali poznať z predchádzajúcich
tutoriálov. Len na pripomenutie - jedná sa o zoznam ciest, na ktorých môže
kompilátor Javy a JVM samotná hľadať jednotlivé triedy (.class
súbory):
java --classpath cesta/k/vasi/knihovne.jar
Modulepath je novinka zavedená práve kvôli modulom.
Podobne ako classpath obsahuje cesty k zložkám, kde sa moduly
nachádzajú. Každá cesta je oddelená ;
:
java --module-path cesta/k/modulum;dalsi/cesta/k/modulum
Dnes sme si vysvetlili, prečo Java zaviedla moduly a aké výhody nám to prináša. Čaká nás ešte trocha teórie, potom si všetko postupne ukážeme na konkrétnych príkladoch. Teším sa na vás pri ďalších lekciách.
V ďalšej lekcii, Classloader a prvý modul v Jave , si predstavíme classloader a jednotlivé druhy modulov a ukážeme si, ako taký modul definujeme.