Programmering

Hva er JPMS? Vi presenterer Java Platform Module System

Inntil Java 9 hadde Java sitt toppnivå kodeorganiseringselement vært pakken. Starter med Java 9 som endret seg: over pakken er det nå modulen. Modulen samler relaterte pakker sammen.

Java Platform Module System (JPMS) er en kodenivåstruktur, så det endrer ikke det faktum at vi pakker Java i JAR-filer. Til slutt er alt fortsatt samlet i JAR-filer. Modulesystemet legger til en ny deskriptor på høyere nivå som JAR kan bruke, ved å inkludere module-info.java fil.

Store apper og organisasjoner vil dra nytte av moduler for å bedre organisere koden. Men alle vil konsumere moduler, ettersom JDK og klassene nå er modulære.

Hvorfor Java trenger moduler

JPMS er resultatet av prosjektet Jigsaw, som ble gjennomført med følgende uttalte mål:

  • Gjør det lettere for utviklere å organisere store apper og biblioteker
  • Forbedre strukturen og sikkerheten til plattformen og JDK selv
  • Forbedre appytelsen
  • Bedre nedbrytning av plattformen for mindre enheter

Det er verdt å merke seg at JPMS er en SE (Standard Edition) -funksjon, og derfor påvirker alle aspekter av Java fra grunnen av. Når det er sagt, er endringen designet for å tillate det mest kode for å fungere uten endring når du flytter fra Java 8 til Java 9. Det er noen unntak fra dette, og vi vil merke dem senere i denne oversikten.

Hovedideen bak en modul er å tillate samling av relaterte pakker som er synlige for modulen, mens du skjuler elementer fra eksterne forbrukere av modulen. Med andre ord, en modul tillater et annet nivå av innkapsling.

Klassebane vs. modulbane

I Java har hittil klassestien vært bunnlinjen for hva som er tilgjengelig for et applikasjon som kjører. Selv om klassebanen tjener dette formålet og er godt forstått, ender det med å bli en stor, udifferensiert bøtte som alle avhengigheter er plassert i.

Modulbanen legger til et nivå over klassebanen. Den fungerer som en container for pakker og bestemmer hvilke pakker som er tilgjengelige for applikasjonen.

Moduler i JDK

JDK selv består av moduler nå. La oss begynne med å se på muttere og bolter til JPMS der.

Hvis du har en JDK på systemet ditt, har du også kilden. Hvis du ikke er kjent med JDK og hvordan du får tak i den, ta en titt på denne artikkelen.

Inne i JDKs installasjonskatalog er en / lib katalog. Inne i katalogen er en src.zip fil. Pakk det ut i en / src katalog.

Se inne i / src og naviger til /java.base katalog. Der finner du module-info.java fil. Åpne den.

Etter Javadoc-kommentarene i spissen finner du en seksjon som hetermodul java.base etterfulgt av en serie med eksport linjer. Vi vil ikke dvele ved formatet her, da det blir ganske esoterisk. Detaljene finner du her.

Du kan se at mange av de kjente pakkene fra Java, som java.io, eksporteres fra java.base modul. Dette er essensen av en modul som samler pakkene.

Baksiden aveksport er den krever instruksjon. Dette gjør at en modul kreves av modulen som defineres.

Når du kjører Java-kompilatoren mot moduler, spesifiserer du modulbanen på samme måte som klassebanen. Dette gjør at avhengighetene kan løses.

Opprette et modulært Java-prosjekt

La oss ta en titt på hvordan et modulert Java-prosjekt er strukturert.

Vi skal lage et lite program som har to moduler, en som leverer en avhengighet og den andre som bruker den avhengigheten og eksporterer en kjørbar hovedklasse.

Lag en ny katalog et sted som er praktisk på filsystemet. Kall det /com.javaworld.mod1. Som konvensjon lever Java-moduler i en katalog som har samme navn som modulen.

Nå, i denne katalogen, oppretter du en module-info.java fil. Innvendig, legg til innholdet fra oppføring 1.

Oppføring 1: com.javaworld.mod1 / module-info.java

modul com.javaworld.mod1 {eksporterer com.javaworld.package1; }

Legg merke til at modulen og pakken den eksporterer er forskjellige navn. Vi definerer en modul som eksporterer en pakke.

Opprett nå en fil på denne banen i katalogen som inneholder module-info.java fil: /com.javaworld.mod1/com/javaworld/package1. Gi filen et navnNavn. Java. Sett innholdet i Listing 2 i den.

Oppføring 2: Name.java

 pakke com.javaworld.package1; public class Name {public String getIt () {return "Java World"; }} 

Oppføring 2 blir en klasse, pakke og modul som vi er avhengige av.

La oss nå opprette en annen katalog parallelt med /com.javaworld.mod1 og kaller det /com.javaworld.mod2. La oss lage en i denne katalogen module-info.java moduldefinisjon som importerer modulen vi allerede opprettet, som i Listing 3.

Listing 3: com.javaworld.mod2 / module-info.java

 module com.javaworld.mod2 {krever com.javaworld.mod1; } 

Listing 3 er ganske selvforklarende. Den definerer com.javaworld.mod2 modul og krever com.javaworld.mod1.

Inne i /com.javaworld.mod2 katalog, opprett en klassebane slik: /com.javaworld.mod2/com/javaworld/package2.

Legg nå til en fil som heter Hei.java, med koden gitt i oppføring 4.

Oppføring 4: Hello.java

 pakke com.javaworld.package2; importere com.javaworld.package1.Name; offentlig klasse Hei {public static void main (String [] args) {Name name = new Name (); System.out.println ("Hello" + name.getIt ()); }} 

I oppføring 4 begynner vi med å definere pakken, og deretter importere com.javawolrd.package1.Name klasse. Vær oppmerksom på at disse elementene fungerer akkurat som de alltid har gjort. Modulene har endret hvordan pakkene blir gjort tilgjengelige på filstrukturenivå, ikke kodenivå.

På samme måte bør selve koden være kjent for deg. Det oppretter ganske enkelt en klasse og kaller en metode for å skape et klassisk "hallo verden" -eksempel.

Kjører det modulære Java-eksemplet

Det første trinnet er å opprette kataloger for å motta utdata fra kompilatoren. Lag en katalog som heter /mål ved roten til prosjektet. Opprett en katalog for hver modul inne: /target/com.javaworld.mod1 og /target/com.javaworld.mod2.

Trinn 2 er å kompilere avhengighetsmodulen og legge den ut til /mål katalog. Ved roten til prosjektet, skriv inn kommandoen i Listing 5. (Dette forutsetter at JDK er installert.)

Oppføring 5: Bygningsmodul 1

 javac -d target / com.javaworld.mod1 com.javaworld.mod1 / module-info.java com.javaworld.mod1 / com / javaworld / package1 / Name.java 

Dette vil føre til at kilden bygges sammen med modulinformasjonen.

Trinn 3 er å generere den avhengige modulen. Skriv inn kommandoen som vises i Oppføring 6.

Listing 6: Bygningsmodul 2

 javac --module-path target -d target / com.javaworld.mod2 com.javaworld.mod2 / module-info.java com.javaworld.mod2 / com / javaworld / package2 / Hello.java 

La oss se nærmere på Listing 6. Det introduserer modul-bane argument til javac. Dette lar oss definere modulbanen på samme måte som --class-path-bryteren. I dette eksemplet passerer vi i mål katalog, fordi det er her Listing 5 sender ut modul 1.

Deretter definerer Listing 6 (via -d switch) utgangskatalogen for modul 2. Til slutt blir de faktiske kompilasjonsemnene gitt, som modul-info.java fil og klasse som finnes i modul 2.

For å kjøre, bruk kommandoen vist i oppføring 7.

Listing 7: Gjennomføring av hovedklassen i modulen

 java --module-path target -m com.javaworld.mod2 / com.javaworld.package2.Hello 

De --modul-sti switch forteller Java å bruke /mål katalog som modulrot, dvs. hvor du skal søke etter modulene. De -m switch er der vi forteller Java hva hovedklassen vår er. Legg merke til at vi forordner det fullt kvalifiserte klassenavnet med modulen.

Du vil bli møtt med utdataene Hei Java World.

Bakoverkompatibilitet

Du kan godt lure på hvordan du kan kjøre Java-programmer skrevet i pre-modulversjoner i innlegget Java 9-verden, gitt at den forrige kodebasen ikke vet noe om modulbanen. Svaret er at Java 9 er designet for å være bakoverkompatibel. Imidlertid er det nye modulesystemet en så stor endring at du kan støte på problemer, spesielt i store kodebaser.

Når du kjører en pre-9-kodebase mot Java 9, kan du støte på to typer feil: de som stammer fra kodebasen din, og de som stammer fra dine avhengigheter.

For feil som stammer fra kodebasen din, kan følgende kommando være nyttig: jdeps. Denne kommandoen når den pekes på en klasse eller katalog, vil skanne etter hvilke avhengigheter som er der, og hvilke moduler disse avhengighetene er avhengige av.

For feil som stammer fra avhengighetene dine, kan du håpe at pakken du er avhengig av vil ha en oppdatert Java 9-kompatibel versjon. Hvis ikke, må du kanskje søke etter alternativer.

En vanlig feil er denne:

Hvordan løse java.lang.NoClassDefFoundError: javax / xml / bind / JAXBException

Dette er Java som klager over at en klasse ikke blir funnet, fordi den har migrert til en modul uten synlighet til forbrukskoden. Det er et par løsninger av varierende kompleksitet og varighet, beskrevet her.

Igjen, hvis du oppdager slike feil med avhengighet, sjekk med prosjektet. De kan ha en Java 9-build som du kan bruke.

JPMS er en ganske omfattende endring, og det vil ta tid å adoptere. Heldigvis er det ikke noe hastverk, siden Java 8 er en langsiktig støtteutgivelse.

Når det er sagt, vil eldre prosjekter på sikt måtte migrere, og nye må bruke moduler intelligent, forhåpentligvis å utnytte noen av de lovede fordelene.

Denne historien, "Hva er JPMS? Introduksjon av Java Platform Module System" ble opprinnelig utgitt av JavaWorld.

$config[zx-auto] not found$config[zx-overlay] not found