Kæmpe omlægning i Java 9: Sådan bliver koden skåret i bidder

28. marts 2017 kl. 05:121
Kæmpe omlægning i Java 9: Sådan bliver koden skåret i bidder
Illustration: mkabakov/Bigstock.
Den næste udgave af Java er på vej ud af samlebåndet og rammer udviklerne om seks måneder. Den helt store nyhed er modularisering af koden, som giver hurtigere opstart, mindre kørselsmiljø, skjult kode og bedre håndtering af biblioteker.
Artiklen er ældre end 30 dage
Manglende links i teksten kan sandsynligvis findes i bunden af artiklen.

Populære programmeringssprog går ikke bort sådan uden videre, og efter 21 år ligger Java i toppen på popularitetsindekser som Tiobe og Pypl.

De seneste år har Android-styresystemet givet Java et spark bagi på popularitetskurven, så der er stadig bud efter sproget, der i de seneste opdateringer har fået tilført funktionelle træk og 'dataflow'-programmering, som tiden kræver det. Java er stadig i vælten - på telefoner og tablets, endda i spil som Minecraft, og indenfor undervisning, enterprise samt big data er Java stadig dominerende.

I den kommende version 9 handler den store nyhed om at skære koden i bidder, eller rettere sagt i moduler, som er et begreb, der ligger et trin højere en Javas medfødte modularisering ved hjælp af pakker.

Fakta om Java

Java består af mange dele. Den, der behandles i denne artikel er Java SE. Hele familien ser sådan ud:

  • Java Card - Java til smartcards. Sidder i mange SIM-kort og betalingskort.
  • Java ME - Mobile edition. Til gammeldags mobiltelefoner og indlejrede enheder.
  • Android - Ikke officielt en del af Java. Klassebibliotek består af dele af Java SE samt egne Android-klasser.
  • Java SE - Standard edition eller desktop-udgaven af Java.
  • Java EE - Enterprise edition - Java til serverprogrammering.

Modularisering på højere niveau giver fordele

Modularisering på højere niveau end pakker giver en række fordele. Det kan gøre kørselsmiljøet mindre, ved kun at kræve de klassebiblioteker som rent faktisk benyttes i koden.

Artiklen fortsætter efter annoncen

Det gør det også muligt at 'skjule kode' på et højere plan, end hvad Javas adgangsmodifikatorer (private, public mv.) tillader, en facilitet, JDK-udviklerne kalder for 'stærk indkapsling'.

Programmer får også hurtigere opstart, når en mindre kodebase skal kigges igennem, og endelig giver det nemmere håndtering af binære arkiver, så problemerne med modstridende afhængigheder løses. Der findes allerede en standard for moduler i Java i form af OSGI, men den har et bredere sigte end den, der tilbydes i Java 9.

Ny syntaks for moduler

Moduler defineres i Java 9 ved en modul-definition, som gives i en kildefil med navnet module-info.java. Den placeres i en mappe, som navngives ud fra pakkerne i modulet.

Hvis pakkerne f.eks. hedder tania.hej, så skal mappen med module-info.java også hedde tania.hej, hvilket har givet anledning til en del forvirring, og derfor er denne måde at løse sagen på stadig under overvejelse. Sidst i denne artikel kan de fulde eksempler downloades.

Artiklen fortsætter efter annoncen

Et helt simpelt eksempel på en modul-definition er:

  1. module tania.hejverden { }

Det erklærer blot at klasserne i pakken tania.hejverden udgør et modul. Grundmodulet java.base, som indeholder de mest basale klassebiblioteker, er allerede implicit tilføjet. Skal andre moduler benyttes, skal de erklæres. Så kan module-info.java se sådan ud:

  1. module tania.hejverden {
  2. requires java.logging;
  3. }

Her importeres java.logging-modulet, så dets klasser kan anvendes i tania.hejverden.

Som udgangspunkt stiller et modul ingen klasser til rådighed for andre moduler. Det betyder, at moduler giver en ny og skrappere måde at 'skjule kode' på. Hvis der skal gives adgang til en eller flere pakker, kræver det en 'export'-sætning, og det kan se sådan ud:

  1. module tania.hejverden {
  2. requires java.logging;
  3. exports tania.hejverden;
  4. }

Mere generelt så kan kode i klassen S læse kode i klassen T, hvis S’s modul 'læser' (dvs. 'requires') T’s modul, og T’s modul eksporterer T’s pakke.

Artiklen fortsætter efter annoncen

Det betyder dog ikke, at et modul kan læse de klasser, som et underliggende model kan læse. For eksempel læser modulet 'java.sql' modulet 'java.logging', men for at de moduler, som anvender java.sql, kan bruge logging-metoder, skal der videregives adgang til java.logging ved at tilføje 'transitive' i 'require'-erklæringen, som herunder:

  1. module java.sql {
  2. requires transitive java.logging;
  3. requires transitive java.xml;
  4. exports java.sql;
  5. exports javax.sql;
  6. exports javax.transaction.xa;
  7. }

(I parentes bemærket blev 'transitive'-modifikatoren tidligere kaldt 'public' i Java 9.)

Modul-definitioner har en række faciliteter ud over de her nævnte. Det gælder blandt andet 'provides'-erklæringen, som gør det muligt for et modul at erklære, at det stiller en tjeneste til rådighed, som for eksempel en databasedriver. Det kan se sådan ud:

  1. module com.mysql.jdbc {
  2. requires java.sql;
  3. requires org.slf4j;
  4. exports com.mysql.jdbc;
  5. provides java.sql.Driver with com.mysql.jdbc.Driver;
  6. }

Her er java.sql.Driver et interface og com.mysql.jdbc.Driver den konkrete driver, som modulet stiller til rådighed.

En anden facilitet, der er værd at nævne, er 'open module', som er indført for at hjælpe værktøjer, som benytter refleksion. Det gælder for eksempel database-broer som Hibernate, der har brug for at læse klasser, man normalt ikke ville eksportere i et modul.

Her kan man så erklære sit modul som 'open module', som ved kompilering kun giver adgang til de eksporterede pakker, men fuld adgang under kørslen, ved hjælp af refleksion.

Mindre kørselsmiljø med modularisering

Java-arkiver, JARs, har været måden at indkapsle binære java-klasser på, og ikke underligt giver Java 9 en facilitet til at bringe kodebibliotekerne ind i modul-verdenen. Men på den længere bane er JAR-arkiver på vej ud, og det skyldes, at formatet er for gammeldags i forhold til at finde og indlæse koden.

I stedet byder Java 9 på JMOD-arkiver, som samler Java- og system-kildekode og resurser i ét arkiv. Jlink er et værktøj, som blev introduceret i Java 8, og det fremstiller kørselstidsmiljøer, så man eksempelvis kan fremstille et miljø, der kun indeholder de moduler, som anvendes i programmet, med mindre størrelse til følge. I den avancerede ende er begrebet layers, som gør det muligt at operere med flere forskellige udgaver af samme moduler.

Java 9 byder på mange andre nyheder, men ikke nogen i samme klasse som modularisering. Her er blandt andet nemmere initialisering af lister, sets, og maps. En 'shell' gør det muligt at evaluere sætninger i et terminalvindue, som det kendes fra mange andre sprog. En ny HTTP-klient bliver ikke til noget i denne omgang, men må pænt vente på næste ombæring.

Java 9 er fastsat til at udkomme den 27 juli i år, men køreplanen er skredet mange gange før, så man skal nok ikke være helt sikker på, at det holder. Der er meget mere information om Java 9 på projektets hjemmeside.

Download artiklens kodeeksempler

1 kommentar.  Hop til debatten
Denne artikel er gratis...

...men det er dyrt at lave god journalistik. Derfor beder vi dig overveje at tegne abonnement på Version2.

Digitaliseringen buldrer derudaf, og it-folkene tegner fremtidens Danmark. Derfor er det vigtigere end nogensinde med et kvalificeret bud på, hvordan it bedst kan være med til at udvikle det danske samfund og erhvervsliv.

Og der har aldrig været mere akut brug for en kritisk vagthund, der råber op, når der tages forkerte it-beslutninger.

Den rolle har Version2 indtaget siden 2006 - og det bliver vi ved med.

Debatten
Log ind eller opret en bruger for at deltage i debatten.
settingsDebatindstillinger
1
28. marts 2017 kl. 12:32

Moduler med indbygget dependency kontrol. Nice :)

Så meget som jeg holder af at kode med Java, har det ofte været et problem at overbevise slutbrugere af software'en, at de først skal installere den store runtime. Så denne nye modularitet er yderst velkommen.