Do verze Java 9 byl balíček prvkem nejvyšší úrovně organizace kódu Java. Počínaje změnou Java 9: nad balíčkem je nyní modul. Modul shromažďuje související balíčky společně.
Systém Java Platform Module System (JPMS) je struktura na úrovni kódu, takže to nic nemění na tom, že balíme Javu do souborů JAR. Nakonec je vše stále spojeno v souborech JAR. Modulový systém přidáním nového, vyššího deskriptoru, který mohou JAR používat, začleněním modul-info.java
soubor.
Rozsáhlé aplikace a organizace využijí výhody modulů k lepší organizaci kódu. Ale každý bude spotřebovávat moduly, protože JDK a jeho třídy jsou nyní modularizovány.
Proč Java potřebuje moduly
JPMS je výsledkem projektu Jigsaw, který byl realizován s následujícími stanovenými cíli:
- Usnadněte vývojářům organizaci velkých aplikací a knihoven
- Vylepšete strukturu a zabezpečení platformy a samotné JDK
- Zlepšete výkon aplikací
- Lepší zvládnutí rozkladu platformy pro menší zařízení
Stojí za zmínku, že JPMS je funkce SE (Standard Edition), a proto od základu ovlivňuje všechny aspekty Javy. Změna je navržena tak, aby umožňovala většina Při přechodu z prostředí Java 8 na prostředí Java 9 bude kód fungovat beze změn. Existují určité výjimky, které si všimneme dále v tomto přehledu.
Hlavní myšlenkou modulu je umožnit shromažďování souvisejících balíčků, které jsou viditelné pro modul, a zároveň skrýt prvky před externími spotřebiteli modulu. Jinými slovy, modul umožňuje další úroveň zapouzdření.
Cesta třídy vs. cesta modulu
V Javě dosud byla cesta ke třídě spodním řádkem toho, co je k dispozici spuštěné aplikaci. Ačkoli cesta třídy slouží tomuto účelu a je dobře srozumitelná, končí jako velký nediferencovaný segment, do kterého jsou umístěny všechny závislosti.
Cesta modulu přidává úroveň nad cestu třídy. Slouží jako kontejner pro balíčky a určuje, jaké balíčky jsou aplikaci k dispozici.
Moduly v JDK
Samotný JDK se nyní skládá z modulů. Začněme tím, že se podíváme na matice a šrouby JPMS.
Pokud máte ve svém systému JDK, máte také zdroj. Pokud nejste obeznámeni s JDK a jak jej získat, podívejte se na tento článek.
Uvnitř instalačního adresáře JDK je a / lib
adresář. Uvnitř tohoto adresáře je a src.zip
soubor. Rozbalte to do a / src
adresář.
Podívejte se dovnitř / src
adresáře a přejděte do složky /java.base
adresář. Zde najdete modul-info.java
soubor. Otevři to.
Po komentářích Javadoc v čele najdete sekci s názvemmodul java.base
následuje řada vývoz
řádky. Nebudeme se zde zabývat formátem, protože se stává docela esoterickým. Podrobnosti naleznete zde.
Můžete vidět, že mnoho známých balíčků z Javy, jako java.io
, jsou exportovány z java.base
modul. To je podstata modulu, který shromažďuje balíčky.
Odvrácená stranavývoz
je vyžaduje
návod. To umožňuje, aby modul byl vyžadován definovaným modulem.
Při spuštění kompilátoru Java proti modulům určíte cestu k modulu podobným způsobem jako cestu ke třídě. To umožňuje vyřešit nedostatky.
Vytvoření modulárního projektu Java
Pojďme se podívat na to, jak je strukturovaný projekt Java.
Chystáme se vytvořit malý program, který má dva moduly, jeden, který dodává závislost a druhý, který tuto závislost používá a exportuje spustitelnou hlavní třídu.
Vytvořte nový adresář kdekoli ve vašem souborovém systému. Říkejte tomu /com.javaworld.mod1
. Podle konvence žijí moduly Java v adresáři, který má stejný název jako modul.
Nyní v tomto adresáři vytvořte a modul-info.java
soubor. Uvnitř přidejte obsah ze seznamu 1.
Výpis 1: com.javaworld.mod1 / module-info.java
modul com.javaworld.mod1 {exportuje com.javaworld.package1; }
Všimněte si, že modul a balíček, který exportuje, mají různé názvy. Definujeme modul, který exportuje balíček.
Nyní vytvořte soubor na této cestě uvnitř adresáře, který obsahuje modul-info.java
soubor: /com.javaworld.mod1/com/javaworld/package1
. Pojmenujte souborNázev.java
. Vložte do něj obsah výpisu 2.
Výpis 2: Name.java
balíček com.javaworld.package1; public class Název {public String getIt () {return "Java World"; }}
Výpis 2 se stane třídou, balíčkem a modulem, na kterém budeme záviset.
Nyní vytvořme další adresář paralelně s /com.javaworld.mod1
a zavolej to /com.javaworld.mod2
. V tomto adresáři vytvořme modul-info.java
definice modulu, která importuje modul, který jsme již vytvořili, jako v seznamu 3.
Výpis 3: com.javaworld.mod2 / module-info.java
modul com.javaworld.mod2 {vyžaduje com.javaworld.mod1; }
Výpis 3 je docela vysvětlující. Definuje com.javaworld.mod2
modul a vyžaduje com.javaworld.mod1
.
Uvnitř /com.javaworld.mod2
adresář, vytvořte cestu třídy takto: /com.javaworld.mod2/com/javaworld/package2
.
Nyní přidejte dovnitř soubor s názvem Ahoj.java
, s kódem uvedeným v seznamu 4.
Výpis 4: Hello.java
balíček com.javaworld.package2; import com.javaworld.package1.Name; public class Hello {public static void main (String [] args) {Name name = new Name (); System.out.println ("Hello" + name.getIt ()); }}
V seznamu 4 začneme definováním balíčku a poté importem com.javawolrd.package1.Name
třída. Vezměte na vědomí, že tyto prvky fungují stejně jako vždy. Moduly změnily způsob zpřístupňování balíčků na úrovni struktury souborů, nikoli na úrovni kódu.
Podobně by vám měl být známý samotný kód. Jednoduše vytvoří třídu a zavolá na ni metodu k vytvoření klasického příkladu „hello world“.
Spuštění modulárního příkladu Java
Prvním krokem je vytvoření adresářů pro příjem výstupu kompilátoru. Vytvořte adresář s názvem /cílová
v kořenovém adresáři projektu. Uvnitř vytvořte adresář pro každý modul: /target/com.javaworld.mod1
a /target/com.javaworld.mod2
.
Krok 2 je kompilace modulu závislostí a jeho výstup do /cílová
adresář. V kořenovém adresáři projektu zadejte příkaz do Výpisu 5. (Předpokládá se instalace JDK.)
Výpis 5: Building Module 1
javac -d target / com.javaworld.mod1 com.javaworld.mod1 / module-info.java com.javaworld.mod1 / com / javaworld / package1 / Name.java
To způsobí vytvoření zdroje spolu s informacemi o jeho modulu.
Krok 3 je vygenerování závislého modulu. Zadejte příkaz zobrazený v seznamu 6.
Výpis 6: Building Module 2
javac --module-path target -d target / com.javaworld.mod2 com.javaworld.mod2 / module-info.java com.javaworld.mod2 / com / javaworld / package2 / Hello.java
Podívejme se podrobně na Výpis 6. Zavádí cesta modulu
argument pro javac. To nám umožňuje definovat cestu modulu podobně jako přepínač --class-path. V tomto příkladu předáváme cílová
adresář, protože tam se nachází výpis 5 výstupů modulu 1.
Dále definuje Výpis 6 (přes -d
switch) výstupní adresář pro modul 2. Nakonec jsou uvedeny skutečné předměty kompilace, jako modul-info.java
soubor a třída obsažená v modulu 2.
Chcete-li spustit, použijte příkaz zobrazený v seznamu 7.
Výpis 7: Provedení hlavní třídy modulu
java --module-path target -m com.javaworld.mod2 / com.javaworld.package2.Ahoj
The --module-path
switch říká Javě, aby ji použila /cílová
adresář jako kořen modulu, tj. kde hledat moduly. The -m
switch je místo, kde řekneme Javě, jaká je naše hlavní třída. Všimněte si, že předmluvu plně kvalifikovaný název třídy s jeho modulem.
Budete uvítáni výstupem Ahoj svět Java
.
Zpětná kompatibilita
Možná vás zajímá, jak můžete ve světě Java 9 spouštět programy Java napsané v předmodulárních verzích, protože předchozí kódová základna neví nic o cestě modulu. Odpověď je, že Java 9 je navržena tak, aby byla zpětně kompatibilní. Nový systém modulů je však tak velkou změnou, že můžete narazit na problémy, zejména ve velkých databázích kódů.
Když běžíte před 9 kódovou základnu proti Javě 9, můžete narazit na dva druhy chyb: ty, které vycházejí z vaší kódové základny, a ty, které vycházejí z vašich závislostí.
U chyb, které vycházejí z vaší základny kódu, může být užitečný následující příkaz: jdeps
. Tento příkaz, když ukazuje na třídu nebo adresář, prohledá, jaké závislosti tam jsou a na jaké moduly se tyto závislosti spoléhají.
U chyb, které vycházejí z vašich závislostí, můžete doufat, že balíček, na kterém jste závislí, bude mít aktualizované sestavení kompatibilní s Java 9. Pokud ne, možná budete muset hledat alternativy.
Jedna častá chyba je tato:
Jak vyřešit java.lang.NoClassDefFoundError: javax / xml / bind / JAXBException
Toto si Java stěžuje, že třída nebyla nalezena, protože migrovala na modul bez viditelnosti pro náročné kódy. Zde je popsáno několik řešení různé složitosti a stálosti.
Znovu, pokud zjistíte takové chyby se závislostí, zkontrolujte projekt. Mohou mít sestavení Java 9, které můžete použít.
JPMS je poměrně rozsáhlá změna a její přijetí bude nějakou dobu trvat. Naštěstí neexistuje žádný naléhavý spěch, protože Java 8 je vydání dlouhodobé podpory.
Jak již bylo řečeno, z dlouhodobého hlediska bude nutné migrovat starší projekty a nové projekty budou muset inteligentně využívat moduly, doufejme, že využijí některé ze slibovaných výhod.
Tento příběh „Co je JPMS? Představujeme systém Java Platform Module System“ původně publikoval JavaWorld.