[[:oktatas:programozás:java|< Java]]
====== A Java modulrendszer ======
* **Szerző:** Sallai András
* Copyright (c) 2025, Sallai András
* Licenc: [[https://creativecommons.org/licenses/by-sa/4.0/|CC BY-SA 4.0]]
* Web: https://szit.hu
===== Bevezetés =====
A Java 9 Platform Module System, röviden JPMS. A Java 9-ben vezették be
a modulok kezelésére.
A modul nevét, függőségeit, láthatósági szabályait
a **module-info.java** fájlban írjuk le.
==== Egy modul felépítése ====
Miket tartalmazhat egy modul?
* osztályok
* interfészek
* csomagok
* erőforrások
Minden modul gyökérkönyvtárában lennie kell egy **module-info.java**
fájlnak, például:
module com.example {
requires javafx.controls;
requires javafx.fxml;
exports com.example.ui;
opens com.example.controllers to javafx.fxml;
}
==== A module-info.java fő kulcsszavai ====
^ Kulcsszó ^ Jelentés ^
| module | A modul neve (pl. com.example) |
| require | Függőség megadása |
| require transitive | A függőséget a modulunkat használók is elérhetik |
| exports | Egy csomagot más modulok számára elérhető tesz |
| opens | Egy csomagot reflektív hozzáférésre nyit meg. |
| opens ... to | Egy csomagot célzottan egy adott modul számára nyit meg |
| uses | A ServiceLoader((Dinamikus szolgáltatás betöltés a Java nyelvben)) által betöltött szolgáltatást jelez. |
| provides ... with | Egy interfészt és annak megvalósítását \\ adja meg a ServiceLoader számára |
===== Egyszerű függőség =====
module com.example {
requires java.sql;
}
===== Tranzitív függőség =====
module com.example {
requires transitive javafx.graphics;
}
===== Csomagok exportálása =====
A com.example.api csomag látható más modulok számára.
module com.example {
exports com.example.api;
}
===== Reflektív hozzáférés biztosítása =====
module com.example {
opens com.example.model to com.google.gson;
}
Ez azt jelenti, hogy a com.example.model csomagot csak
a Gson könyvtár érheti el reflektíven, más modulok nem.
===== Modulok között szolgáltatás nyújtá (ServiceLoader) =====
module com.example {
provides com.example.MyService with com.example.impl.MyServiceImpl;
}
Ez azt jelenti, hogy a com.example.impl.MyServiceImpl osztály az com.example.MyService interfész megvalósítása.
Ha egy másik modul ezt használni szeretné, így teheti meg:
module com.client {
requires com.example;
uses com.example.MyService;
}
===== Modulári és nem modulári könyvtárak használata =====
Ha egy nem moduláris (régi) JAR-t szeretnél használni, akkor:
* Az --add-modules kapcsolóval futtatáskor hozzá lehet adni a modulpath-hoz.
* Az Automatic-Module-Name attribútummal lehet segíteni a kompatibilitást.
===== Moduláris és nem moduláris alkalmazások közötti különbségek =====
^ Jellemző ^ Moduláris alkalmazás ^ Hagyományos alkalmazás ^
| Modulok láthatóság | Csak exportált csomagok láthatók | Minden public látható |
| Függőségek | A requires használatával szabályozott | Classpath alapján működik |
| Egységbezárás | Jobban ellenőrizhető | Gyengébb láthatóság-kezelés |
| Visszafelé kompatibilitás | Kezdeti nehézségek | Klasszikus Java mód |
===== Tranzitív függőség =====
Ha modulárisan programozunk, a modulunk neve
lehet com.example, lan.zold, de nevezzük most egyszerűen
"A" modulnak.
A module-info.java fájlban egy függőséget így jelölhetünk meg:
requires javafx.controls;
vagy:
requires javafx.fxml;
Legyen egy másik modul, nevezzük "B" modulnak, amely használja
az "A" modult.
Ebben az esetben "B" nem fér hozzá javafx.controls és a javafx.fxml
modulokhoz, mert azokat "A" csak saját használatra jelölte meg.
Most vizsgáljunk meg egy másik függőséget:
requires transitive javafx.graphics;
Mivel "A" modul ezt a függőséget tranzitív módon jelöli meg,
a "B" modul is automatikusan hozzáfér javafx.graphics modulhoz,
anélkül, hogy külön requires javafx.graphics; sort kellen írnia.
===== Forrás =====
* https://www.oracle.com/corporate/features/understanding-java-9-modules.html (2025)