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

Efter 21 år lever Java i bedste velgående. 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.

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.

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.

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.

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

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:

module tania.hejverden {
             requires java.logging;
}

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:

module tania.hejverden {
             requires java.logging;
             exports tania.hejverden;
}

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.

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:

module java.sql {
    requires transitive java.logging;
    requires transitive java.xml;
    exports java.sql;
    exports javax.sql;
    exports javax.transaction.xa;
}

(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:

module com.mysql.jdbc {
    requires java.sql;
    requires org.slf4j;
    exports com.mysql.jdbc;
    provides java.sql.Driver with com.mysql.jdbc.Driver;
}

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

Tips og korrekturforslag til denne historie sendes til tip@version2.dk
Følg forløbet
Kommentarer (1)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
Henrik Eiriksson

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.

  • 2
  • 0
Log ind eller Opret konto for at kommentere