Zarábaj až 6 000 € mesačne! Akreditované rekvalifikačné kurzy od 0 €. Viac informácií.

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.
Základná myšlienka tohto návrhu je oddelenie špecifikácie od implementácie. V budúcnosti môžeme napríklad napísať ďalší modul, v ktorom budeme chcieť napísať ďalší druh zdraviča. Môžeme to brať ako rozšírenie existujúcej implementácie.

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

 

Predchádzajúci článok
Classloader a prvý modul v Jave
Všetky články v sekcii
Moduly v Jave
Preskočiť článok
(neodporúčame)
ServiceLoader a služby pre moduly v Jave
Článok pre vás napísal Petr Štechmüller
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje primárně programování v Javě, ale nebojí se ani webových technologií.
Aktivity