3. diel - Vytvorenie prvého modulu v Jave
V predchádzajúcej lekcii, Classloader a prvý modul v Jave , sme sa dozvedeli, čo je to classloader a ako funguje načítanie tried v Jave. Popísali sme si rôzne typy modulov a ukázali sme si, ako takýto modul definujeme.
V dnešnej lekcii nášho Java tutoriálu si ukážeme, ako vytvoriť moduly a ako funguje komunikácia medzi nimi. Projekt bude riadený Mavenom. Cieľom bude prepísať Zdravičov z OOP lekcií na zdravičov z modulov.
Štruktúra projektu
Budeme mať celkom tri moduly:
- hlavné - tu bude main metóda,
- api - tu bude jedno rozhranie definujúce metódu pre zdravičov,
- impl - implementácia rôznych zdravičov.
Tvorba projektu
Začneme tvorbou nového projektu. Ako už bolo povedané, projekt bude riadený Mavenom.
Pretože budeme tvoriť vlastnú štruktúru projektu, nepoužijeme žiadny archetyp, ktorý nám Maven ponúka. Zároveň budeme zložky vytvárať mimo nášho vývojového prostredia.
Najskôr si založíme novú zložku s projektom. Zložku nazveme
cz.itnetwork.moduly
. Do nej pridáme tri podzložky:
cz.itnetwork.moduly.zdravic
,
cz.itnetwork.moduly.zdravic.api
,
cz.itnetwork.moduly.zdravic.impl
a súbor pom.xml
. V
každom podpriečinku tiež vytvoríme ďalší súbor pom.xml
.
Ďalej do každej podzložky pridáme vnorené zložky:
src/main/java/
.
Vznikne nám nasledujúca adresárová štruktúra:
cz.itnetwork.moduly |-cz.itnetwork.moduly.zdravic | |-src | | |-main | | | |-java | |-pom.xml |-cz.itnetwork.moduly.zdravic.api | |-src | | |-main | | | |-java | |-pom.xml |-cz.itnetwork.moduly.zdravic.impl | |-src | | |-main | | | |-java | |-pom.xml |-pom.xml
Maven konfigurácia
Teraz postupne vyplníme jednotlivé pom.xml
súbory. Hlavný
konfiguračný pom.xml
súbor bude zatiaľ obsahovať iba
základné informácie o projekte. Ďalej bude obsahovať zoznam (maven)
submodulov:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cz.itnetwork.moduly</groupId> <artifactId>cz.itnetwork.moduly</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <name>cz.itnetwork.moduly</name> <properties> <!-- https://maven.apache.org/general.html#encoding-warning --> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>18</maven.compiler.source> <maven.compiler.target>18</maven.compiler.target> </properties> <modules> <module>cz.itnetwork.moduly.zdravic</module> <module>cz.itnetwork.moduly.zdravic.api</module> <module>cz.itnetwork.moduly.zdravic.impl</module> </modules> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>${maven.compiler.source}</source> <target>${maven.compiler.target}</target> </configuration> </plugin> </plugins> </pluginManagement> </build> </project>
Je veľmi dôležité, aby bolo prítomné nastavenie maven
compiler pluginu. Najmä definícia source
a target
.
Pokiaľ toto nastavenie vynecháme, budeme sa neskôr stretávať s problémami,
pretože kompilátor nebude schopný nájsť Java modul!
Konfiguračné súbory pom.xml
v submoduloch budú všetky
zatiaľ vyzerať rovnako. Líšiť sa budú iba v názve. Prípadné ďalšie
úpravy vykonáme až budú potrebné:
<?xml version="1.0"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>cz.itnetwork.moduly</groupId> <artifactId>cz.itnetwork.moduly</artifactId> <version>1.0-SNAPSHOT</version> </parent> <version>1.0-SNAPSHOT</version> <artifactId>cz.itnetwork.moduly.zdravic</artifactId> <!-- na tomto řádku upravte artifactId dle modulu zdravic/zdravic.api/zdravic.impl --> <name>cz.itnetwork.moduly.zdravic</name> <!-- na tomto řádku upravte name dle modulu zdravic/zdravic.api/zdravic.impl --> </project>
Otvorenie projektu vo vývojovom prostredí
Keď už máme založený projekt, otvoríme si vývojové prostredie av ňom si projekt naimportujeme podľa zvyklostí daného IDE. V prípade IntelliJ zvolíme otvoriť existujúci projekt a vyberieme koreňovú zložku projektu. IntelliJ je dostatočne múdre, aby rozpoznalo, že sa jedná o Maven projekt a synchronizuje si všetky zložky.
Definícia rozhrania
Začneme v module zdravic.api
, ktorý bude obsahovať jedno
rozhranie s jednou metódou definujúcou spôsob, ako sa bude užívateľ
zdraviť. Najskôr tu v zložke src/main/java/
založíme nový
balíček s názvom cz.itnetwork.moduly.zdravic.api
. V balíčku
potom založíme rozhranie IZdravic
s metódou
pozdrav()
:
package cz.itnetwork.moduly.zdravic.api; public interface IZdravic { String pozdrav(String jmeno); }
Implementácia rozhrania
Presunieme sa do modulu zdravic.impl
a opäť vytvoríme nový
balíček, tentoraz s názvom cz.itnetwork.moduly.zdravic.impl
. V
balíčku založíme triedu ZdravicZakladni
, ktorá bude
implementovať rozhranie IZdravic
:
package cz.itnetwork.moduly.zdravic.impl; import cz.itnetwork.moduly.zdravic.api.IZdravic; public class ZdravicZakladni implements IZdravic { private static final String FORMAT_POZDRAVU = "Ahoj uživateli %s"; @Override public String pozdrav(String jmeno) { return FORMAT_POZDRAVU.formatted(jmeno); } }
Importom balíčka cz.itnetwork.moduly.zdravic.impl
sme
vytvorili priamu závislosť. IntelliJ nás upozorní, že
túto závislosť musíme oznámiť Mavenu. V module zdravic.impl
teda otvoríme konfiguračný súbor pom.xml
, kam pridáme Maven
závislosť:
<dependencies> <dependency> <groupId>cz.itnetwork.moduly</groupId> <artifactId>cz.itnetwork.moduly.zdravic.api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
Zadrátovanie
Nakoniec prejdeme do posledného (hlavného) modulu a rovnako ako v
predchádzajúcich moduloch, aj tu vytvoríme nový balíček s názvom
cz.itnetwork.moduly.zdravic
. V ňom založíme novú triedu
pomenovanú Aplikace
:
package cz.itnetwork.moduly.zdravic; import cz.itnetwork.moduly.zdravic.api.IZdravic; import cz.itnetwork.moduly.zdravic.impl.ZdravicZakladni; public class Aplikace { public static void main(String[] args) { IZdravic zdravicZakladni = new ZdravicZakladni(); System.out.println(zdravicZakladni.pozdrav("Karel")); } }
Aby nám tu fungovali importy balíčkov zdravic.api
a
zdravic.impl
, musíme opäť upraviť Maven konfiguráciu v
pom.xml
súbore hlavného modulu a pridať do neho závislosti na
predchádzajúcich moduloch:
<dependencies> <dependency> <groupId>cz.itnetwork.moduly</groupId> <artifactId>cz.itnetwork.moduly.zdravic.api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>cz.itnetwork.moduly</groupId> <artifactId>cz.itnetwork.moduly.zdravic.impl</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
Keď teraz skompilujeme celý projekt a spustíme hlavnú triedu, dostaneme nasledujúci výpis:
Konzolová aplikácia
Ahoj uživateli Karel
Pridanie Java modulov
Teraz prišiel čas na pridanie Java modulov. Z predchádzajúcej lekcie už
vieme, že moduly sa zapisujú do špeciálneho súboru
module-info.java
, ktorý je umiestnený v src
zložke
daného modulu. V prípade Mavenu sa nachádza v zložke
src/main/java/
.
Na nasledujúcich riadkoch sa bude často vyskytovať slovo modul. Niekedy bude myslené Maven modul a niekedy zase Java modul. Typ bude vždy špecifikovaný.
V Maven moduloch cz.itnetwork.moduly.zdravic
,
cz.itnetwork.moduly.zdravic.api
a
cz.itnetwork.moduly.zdravic.impl
založíme nové Java moduly s
názvom zodpovedajúcim Maven modulu:
module cz.itnetwork.moduly.zdravic { } module cz.itnetwork.moduly.zdravic.api { } module cz.itnetwork.moduly.zdravic.impl { }
Keď sa teraz pokúsime projekt skompilovať, tak nám kompilácia neprejde a skončí s chybou:
package cz.itnetwork.moduly.zdravic.api is not visible
Otvoríme si module-info
Java modulu
cz.itnetwork.moduly.zdravic.api
. Tento modul slúži primárne ako
verejné API. To znamená, že chceme, aby mohol rozhranie použiť ktokoľvek.
To zaistíme tým, že budeme exportovať daný balíček. V
našom prípade sa jedná o balíček
cz.itnetwork.moduly.zdravic.api
. Celá definícia Java modulu bude
nasledovná:
module cz.itnetwork.moduly.zdravic.api { exports cz.itnetwork.moduly.zdravic.api; }
Pri pokuse o kompiláciu by sme opäť neuspeli a uvideli by sme navyše stále rovnakú chybovú hlášku. Je to logické. Rozhranie sme "otvorili svetu". Teraz musíme urobiť druhý krok a povedať, ktorý modul toto rozhranie bude používať.
Otvoríme si module-info
Java modulu
cz.itnetwork.moduly.zdravic.impl
. Do modulu pridáme závislosť na
module cz.itnetwork.moduly.zdravic.api
, zároveň
exportujeme balíček
cz.itnetwork.moduly.zdravic.impl
. Balíček opäť musíme
exportovať, pretože obsahuje konkrétnu implementáciu triedy, ktorej
inštanciu vytvárame v triede Aplikace
. Celá definícia Java
modulu bude nasledovná:
module cz.itnetwork.moduly.zdravic.impl { requires cz.itnetwork.moduly.zdravic.api; exports cz.itnetwork.moduly.zdravic.impl; }
Ďalší pokus o kompiláciu by vypísal chybovú hlášku, ktorá sa môže zdať rovnaká, ale týka sa iného artefaktu:
package cz.itnetwork.moduly.zdravic.api is not visible package cz.itnetwork.moduly.zdravic.impl is not visible
Presunieme sa teda ešte do module-info
hlavného Java modulu a
pridáme závislosť na modul s rozhraním a modul s implementáciou. Celá
definícia Java modulu bude nasledovná:
module cz.itnetwork.moduly.zdravic { requires cz.itnetwork.moduly.zdravic.api; requires cz.itnetwork.moduly.zdravic.impl; }
Napokon sa nám podarí projekt skompilovať bez žiadnych chýb. Keď teraz aplikáciu spustíme, dostaneme rovnaký výsledok, ako keď sme ju spúšťali bez modulov:
Konzolová aplikácia
Ahoj uživateli Karel
Gratulujem, práve sme spoločne modularizovali základnú aplikáciu.
V ďalšej lekcii, ServiceLoader a služby pre moduly v Jave , si predstavíme služby (Services) a triedu ServiceLoader. Vďaka nim vylepšíme projekt zdraviča. Zároveň sa naučíme používať kľúčové slová na konfiguráciu modulov.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 9x (10.09 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java