Java 9 linkelés
A Java 9 újdonságai cikksorozat előző részében a Java platform modul rendszeréről olvashattál. Ez az új feature lehetővé teszi alkalmazásaink különböző módokon való telepítését. A Java 9 linkelés új, opcionális statikus linkelési lépést épít be a programunk fordítási lépései közé. De kezdjük az elején!
Java 8 kompakt profilok
Ahhoz, hogy megértsük, milyen új képességekre teszünk szert a Java 9 kibővült eszközkészletével, előbb érdemes megnéznünk az előzményeket.
A Java 8 2014. március 18-án jelent meg, és rengeteg várva várt új nyelvi elemet tartalmazott. A legismertebb talán a funkcionális programozást egyszerűbb formában lehetővé tevő lambda kifejezések és a Stream API volt, de számos más újítás is ezzel a verzióval jelent meg. Ezek egyike volt a kompakt profilok bevezetése (compact profiles).
3 kompakt profilt definiáltak, amelyeknek mérhetetlenül izgalmas neveket adtak:
- compact1
- compact2
- compact3
Java 8 előtt
A Java 8 előtt, amikor lefordítottuk a programunkat, nem volt lehetőségünk megadni a Java fordítónak (javac), hogy ne a Java futtatókörnyezet (JRE) teljes eszközkészletére fordítson, hanem annak csak egy részhalmazára. Ez mondjuk asztali számítógépek esetén ma már nem olyan nagy gond, mert itt bőséges memória áll rendelkezésre, viszont ha a mobil eszközökre gondolunk, már más a helyzet. Itt erősen korlátozottak az erőforrásaink. Nem csak a memória, de a processzor, tárhely, hálózati kapcsolat, akkumulátor is. Ezekre az eszközökre nem lenne célszerű a folyamatosan növekvő teljes JRE-t telepíteni, főleg, ha ki sem használjuk annak képességeit.
Java 8 után
A Java 8-ban viszont már megadhattuk a programunk fordításakor valamelyik kompakt profil nevét, ami a teljes Java futtatókörnyezetnek csak valamilyen részhalmazát tartalmazta. A kompakt profilok kibővítik egymást. A legszűkebb részhalmaz a compact1. A compact2 profil tartalmaz mindent, amit a compact1 és egyéb csomagokat is. Ugyanígy a compact3 tartalmazza a teljes compact2-t és egyéb package-eket is. Hogy melyik profil pontosan mit tartalmaz, azt az alábbi táblázatban láthatod:
compact1 | compact2 | compact3 | Teljes JRE SE |
---|---|---|---|
Core (java.lang.*) | JDBC | Security (kerberos, acl, sasl) | Beans |
Security | RMI | JMX | Input Methods |
Serialization | XML JAXP | JNDI | IDL |
Networking | XML JAXP (adds crypto) | Preferences | |
Ref Objects | Management | Accessibility | |
Regular Expressions | Instrumentation | Print Service | |
Data and Time | RMI-IIOP | ||
Input / Output | CORBA | ||
Collections | Java 2D | ||
Logging | Sound | ||
Concurrency | Swing | ||
Reflection | AWT | ||
JAR | Drag and Drop | ||
ZIP | Image IO | ||
Versioning | JAX-WS | ||
Internationalization (I18N) | |||
JNI | |||
Override Mechanism | |||
Extension Mechanism | |||
Scripting |
Megtakarított tárhely
Hogy legyen egy valós képünk arról, hogy mennyi tárhelyet is takaríthatunk meg a kompakt profilokkal, íme egy rövid mérés:
- compact1 profil: ~14 MB
- compact2 profil: ~18 MB
- compact3 profil: ~21 MB
- Teljes JRE (Java SE Embedded): ~45 MB
Jól látható, hogy a compact1 profil az amúgy is tárhelyoptimalizált teljes Java SE Embedded kiadás egyharmada csupán.
A kompakt profilok már sokat segítettek a problémán, de még mindig nem jelentettek végleges megoldást.
Java 9 linkelés – linkelési idő
Néha úgy érzem kár lefordítani magyarra a fontosabb angol szakkifejezéseket. Talán most is jobban tettem volna, ha link time-nak hagyom.
Eddig fordítási időről (compile time) és futási időről (run time) beszélhettünk programjaink kapcsán, amik a szoftverünk életciklusának két különböző fázisa. E kettő közé a Java 9-ben beférkőzött a linkelési idő (link time). A Java nyelv a kezdetektől fogva egy dinamikusan linkelő nyelv volt, vagyis amikor a forráskódot lefordítottuk bájtkódra, akkor csak a külső library-kra való hivatkozások neve került a lefordított gépi kódba. A függőségek a program futtatásakor töltődtek be. Ez lehetővé tette, hogy több Java program is használja ugyanazt a külső library-t.
A dinamikus linkelés mechanizmusában semmi nem változott, ez továbbra is így működik. Amivel a Java 9-ben most már többet tud a nyelv, az az, hogy lehetőségünk van egy opcionális statikus linkelési lépést is beépíteni a programunk életciklusába. Ez a linkelési idő, ami a fordítási idő és futási idő között van, egy statikus linkelési lépés. A statikus linkelés során modulok halmazait és azok tranzitív függőségeit (transitive dependencies) tudjuk linkelni, hogy egy run-time image-et létrehozzunk.
Java 9 linkelés – jlink parancssori eszköz
Mindezt a jlink nevű új, parancssori eszközzel tehetjük meg, az alább demonstrált módon:
jlink --module-path <modulepath> --add-modules <modules> --limit-modules <modules> --output <path>
- module-path: Ezzel a kapcsolóval specifikálhatjuk a JDK moduljainak elérési útját. Ezek lehetnek JAR fájlok, jmod fájlok (a JDK 9 új fájlformátuma, ami hasonló a JAR fájlokhoz, de tud kezelni natív kódot és java konfigurációs fájlokat is) vagy exploded modulok.
- add-modules: Modulok, amikre a run-time image-et le szeretnénk generáltatni.
- limit-modules: Korlátozhatjuk a linkelést csak azokra a modulokra, amikre az alkalmazásunknak mindenképp szüksége van. Néha, amikor modulokat adunk hozzá, akkor azok tranzitív függőségeit is hozzáadjuk. Ezzel a kapcsolóval limitálhatjuk, hogy melyek ezek a modulok.
- output: A kimeneti elérési út, ahova a generált run-time image kerül.
Konklúzió
Láthatjuk, hogy a Java 9 új, jlink parancssori eszközével a modularizált Java programokat új módokon tudjuk telepíteni, ami számos helyzetben jól jöhet. Annak köszönhetően, hogy a Java 9-ben maga a core csomagok is modularizálva lettek, ha saját projektünket is modularizálva írjuk meg és modularizált külső library-kat használunk, akkor olyan run-time image elkészítése válik lehetővé, ami a korábbi verziókban nem volt kivitelezhető.
Ha többet szeretnél olvasni a jlink használatáról, akkor azt ezen a hivatalos Oracle oldalon teheted meg.