Do Jave 9 je bil Javin element najvišje ravni organizacije kode paket. Začenši z Javo 9, ki se je spremenila: nad paketom je zdaj modul. Modul zbira povezane pakete skupaj.
Sistem modula Java Platform Module (JPMS) je struktura na ravni kode, zato ne spreminja dejstva, da Javo pakiramo v datoteke JAR. Na koncu je vse še vedno povezano v datoteke JAR. Modulni sistem doda nov deskriptor na višji ravni, ki ga lahko uporabljajo JAR-ji, z vključitvijo module-info.java
mapa.
Velike aplikacije in organizacije bodo izkoristile module za boljšo organizacijo kode. Toda vsi bodo uživali module, saj so JDK in njegovi razredi zdaj modulirani.
Zakaj Java potrebuje module
JPMS je rezultat projekta Jigsaw, ki je bil izveden z naslednjimi navedenimi cilji:
- Razvijalcem olajšajte organizacijo velikih aplikacij in knjižnic
- Izboljšajte strukturo in varnost platforme in samega JDK
- Izboljšajte delovanje aplikacije
- Boljše ravnanje z razgradnjo platforme za manjše naprave
Omeniti velja, da je JPMS funkcija SE (Standard Edition) in zato od začetka vpliva na vsak vidik Jave. Ob tem je sprememba zasnovana tako, da omogoča najbolj koda, ki bo delovala brez sprememb pri prehodu z Jave 8 na Javo 9. Obstajajo nekatere izjeme in jih bomo opazili kasneje v tem pregledu.
Glavna ideja modula je omogočiti zbiranje povezanih paketov, ki so vidni modulu, hkrati pa skriti elemente pred zunanjimi porabniki modula. Z drugimi besedami, modul omogoča drugo raven kapsulacije.
Pot razreda v primerjavi s potjo modula
V Javi je bila do zdaj pot razreda do konca tistega, kar je na voljo delujoči aplikaciji. Čeprav razredna pot služi temu namenu in jo dobro razumemo, je na koncu velik, nediferenciran segment, v katerega so umeščene vse odvisnosti.
Pot modula doda nivo nad potjo razreda. Služi kot vsebnik za pakete in določa, kateri paketi so na voljo aplikaciji.
Moduli v JDK
JDK je zdaj sestavljen iz modulov. Začnimo s pogledom na matice JPMS tam.
Če imate v sistemu JDK, imate tudi vir. Če JDK ne poznate in kako ga pridobiti, si oglejte ta članek.
V vašem namestitvenem imeniku JDK je / lib
imenik. V tem imeniku je src.zip
mapa. Razpakirajte to v / src
imenik.
Poglejte v notranjost / src
in se pomaknite do /java.base
imenik. Tam boste našli module-info.java
mapa. Odpri.
Po komentarjih Javadoc na vrhu boste našli razdelek z imenommodul java.base
čemur je sledila vrsta izvoz
črte. Tu se ne bomo zadrževali na formatu, saj postane dokaj ezoteričen. Podrobnosti najdete tukaj.
Vidite lahko, da so mnogi znani paketi z Jave, kot java.io
, se izvozijo iz java.base
modul. To je bistvo modula, ki zbira pakete.
Druga stranizvoz
ali je zahteva
navodila. To omogoča, da modul zahteva modul, ki ga definiramo.
Ko izvajate prevajalnik Java proti modulom, pot modula podate na podoben način kot pot razreda. To omogoča odpravljanje napak.
Ustvarjanje modularnega Java projekta
Oglejmo si, kako je strukturiran modulirani projekt Java.
Naredili bomo majhen program, ki ima dva modula, enega, ki zagotavlja odvisnost, in drugega, ki uporablja to odvisnost in izvozi izvršljiv glavni razred.
Ustvarite nov imenik nekje priročno v vašem datotečnem sistemu. Pokliči /com.javaworld.mod1
. Po dogovoru moduli Java živijo v imeniku z istim imenom kot modul.
Zdaj v tem imeniku ustvarite module-info.java
mapa. V notranjost dodajte vsebino iz seznama 1.
Seznam 1: com.javaworld.mod1 / module-info.java
modul com.javaworld.mod1 {izvozi com.javaworld.package1; }
Upoštevajte, da sta modul in paket, ki ga izvozi, različna imena. Določamo modul, ki izvozi paket.
Zdaj na tej poti ustvarite datoteko v imeniku, ki vsebuje module-info.java
mapa: /com.javaworld.mod1/com/javaworld/package1
. Datoteko poimenujteIme.java
. Vstavite vsebino seznama 2 vanjo.
Seznam 2: Name.java
paket com.javaworld.package1; ime javnega razreda {public String getIt () {return "Java World"; }}
Seznam 2 bo postal razred, paket in modul, od katerih smo odvisni.
Zdaj pa ustvarimo še en vzporednik z /com.javaworld.mod1
in ga pokličite /com.javaworld.mod2
. V tem imeniku ustvarimo module-info.java
definicija modula, ki uvozi modul, ki smo ga že ustvarili, kot v seznamu 3.
Seznam 3: com.javaworld.mod2 / module-info.java
modul com.javaworld.mod2 {zahteva com.javaworld.mod1; }
Seznam 3 je precej samoumeven. Določa com.javaworld.mod2
modul in zahteva com.javaworld.mod1
.
Znotraj /com.javaworld.mod2
imenik, ustvarite pot do razreda tako: /com.javaworld.mod2/com/javaworld/package2
.
Zdaj dodajte datoteko znotraj imenovane Pozdravljeni.java
, s kodo iz seznama 4.
Seznam 4: Hello.java
paket com.javaworld.package2; uvoz com.javaworld.package1.Name; javni razred Pozdravljeni {public static void main (String [] args) {Name name = new Name (); System.out.println ("Pozdravljeni" + name.getIt ()); }}
V seznamu 4 začnemo z opredelitvijo paketa in nato uvozom datoteke com.javawolrd.package1.Name
razred. Upoštevajte, da ti elementi delujejo tako kot vedno. Moduli so spremenili način, kako so paketi na voljo na ravni strukture datotek in ne na ravni kode.
Podobno bi vam morala biti znana tudi sama koda. Preprosto ustvari razred in na njem pokliče metodo, da ustvari klasičen primer "hello world".
Zagon primera modularne Java
Prvi korak je ustvariti imenike za sprejem izhodnih podatkov prevajalnika. Ustvari imenik z imenom / tarča
v korenu projekta. V notranjosti ustvarite imenik za vsak modul: /target/com.javaworld.mod1
in /target/com.javaworld.mod2
.
Korak 2 je sestaviti modul odvisnosti in ga poslati v / tarča
imenik. V korenu projekta vnesite ukaz v seznam 5. (To predvideva, da je JDK nameščen.)
Seznam 5: Gradbeni modul 1
javac -d target / com.javaworld.mod1 com.javaworld.mod1 / module-info.java com.javaworld.mod1 / com / javaworld / package1 / Name.java
To bo povzročilo, da bo vir sestavljen skupaj z informacijami o modulu.
Korak 3 je ustvariti odvisni modul. Vnesite ukaz, prikazan v seznamu 6.
Seznam 6: Gradbeni modul 2
javac --module-path target -d target / com.javaworld.mod2 com.javaworld.mod2 / module-info.java com.javaworld.mod2 / com / javaworld / package2 / Hello.java
Oglejmo si podrobno seznam 6. Predstavlja pot modula
argument za javac. To nam omogoča, da pot modula definiramo na podoben način kot stikalo --class-path. V tem primeru podajamo datoteko cilj
imenik, ker je tam, kjer seznam 5 izpiše modul 1.
Nato seznam 6 opredeljuje (prek -d
preklopite) izhodni imenik za modul 2. Končno so podani dejanski predmeti prevajanja kot module-info.java
datoteka in razred v modulu 2.
Za zagon uporabite ukaz iz seznama 7.
Seznam 7: Izvajanje glavnega razreda modula
java --module-path target -m com.javaworld.mod2 / com.javaworld.package2.Hello
The --module-path
stikalo pove Javi, naj uporabi / tarča
imenik kot koren modula, tj. kje iskati module. The -m
switch je mesto, kjer Javi povemo, kaj je naš glavni razred. Upoštevajte, da smo pred modulom predstavili popolnoma kvalificirano ime razreda.
Pozdravili vas bodo z izhodom Pozdravljeni Java World
.
Združljivost nazaj
Morda se sprašujete, kako lahko zaženete programe Java, napisane v različicah pred modulom v svetu post Java 9, glede na to, da prejšnja kodna baza ne pozna ničesar o poti modula. Odgovor je, da je Java 9 zasnovan tako, da je združljiv nazaj. Vendar je novi sistem modulov tako velika sprememba, da lahko naletite na težave, zlasti v velikih zbirkah kod.
Ko zaženete kodno bazo pred 9 pred Java 9, lahko naletite na dve vrsti napak: tiste, ki izvirajo iz vaše kodne baze, in tiste, ki izhajajo iz vaših odvisnosti.
Za napake, ki izhajajo iz vaše kode, je lahko v pomoč naslednji ukaz: jdeps
. Ta ukaz, ko je usmerjen na razred ali imenik, bo pregledal, katere odvisnosti obstajajo in na katere module se te odvisnosti zanašajo.
Za napake, ki izhajajo iz vaših odvisnosti, lahko upate, da bo paket, od katerega ste odvisni, imel posodobljeno zgradbo, združljivo z Java 9. V nasprotnem primeru boste morda morali poiskati druge možnosti.
Ena najpogostejših napak je ta:
Kako rešiti java.lang.NoClassDefFoundError: javax / xml / bind / JAXBException
To je Java, ki se pritožuje, da razreda ni mogoče najti, ker se je preselil v modul, ne da bi bil viden uporabniški kodi. Tu je opisanih nekaj različno zapletenih in trajnih rešitev.
Če znova odkrijete takšne napake, se posvetujte s projektom. Morda imajo zgradbo Java 9, ki jo lahko uporabljate.
JPMS je precej obsežna sprememba in sprejetje bo trajalo nekaj časa. Na srečo ni nujnega hitenja, saj je Java 8 dolgoročna izdaja za podporo.
Glede na to bodo dolgoročno starejši projekti morali migrirati, novi pa bodo morali pametno uporabljati module, upajmo, da bodo izkoristili nekatere obljubljene koristi.
To zgodbo z naslovom "Kaj je JPMS? Predstavljanje sistema Java Platform Module" je prvotno objavil JavaWorld.