Diese Woche durfte ich eine Schulung zu Java-9 mitmachen. Dabei habe ich die für mich interessantesten Highlights notiert, die ich hier kurz wiedergeben möchte. Da meines Erachtens das Modulsystem „Jigsaw“ das hightlight darstellt, hat es einen eigenen Abschnitt – danach kommt nur noch „Kleinkram“. (Man möge mich belehren, wenn ich da etwas übersehe.)
Modularisierung „Jigsaw“ in Java-9
- Explizite Definition von Modulen (quasi Gruppen von Java-Packages).
- Explizit Abhängigkeiten in einer „module-info.java“ definieren. Zwingt zu mehr Disziplin und Struktur.
- Fehlende Module (im Module-Path) werden zur Laufzeit direkt erkannt – und nicht erst, wenn fehlende Klassen geladen werden sollen
- Es gibt drei Modul-Typen:
- Unnamed Modules (=alles, was im Classpath liegt)
- exportiert alles (kann aber nicht adressiert/benannt werden, daher „unnamed“)
- Automatic Modules (= Jars, die im Module-Path liegen, aber keine module-info haben)
- exportieren autom. alles
- dürfen auf das Unnamed Module zugreifen
- Explicit Modules (= „echte“ Module – da will man hin)
- alle Exporte („exports“) und Importe („requires“) müssen explizit in „module-info.java“ angegeben werden)
- können nicht auf unnamed Module zugreifen
- Unnamed Modules (=alles, was im Classpath liegt)
- Unterstützung des ServiceLoaders auf Modul-Ebene („uses MyServiceInterface“ und „provides MyServiceInterface with MyServiceInterfaceImpl“ in der module-info)
- Migration
- In Containern (wie Tomcat) ist nicht möglich, solange der Container Java 9 nicht unterstützt.
- Ohne Container kann man zum Übergang wohl gut mit Automatic Modules arbeiten.
- Es gibt von Oracle eine Migrationsaleitung.
Sonstiges
- Reactive Streams: Subscriber-Publisher-Pattern mit definierter (einfacher) Flusskontrolle.
- Es werden nur Interfaces definiert (ähnlich JDBC) und man (=Oracle) hofft darauf, dass die verschiedenen Implementierungen zukünftig darauf aufsetzen. RxJava tut das bereits.
- Hintergrund ist wohl, dass reactive Patterns zunehmend Verbreitung finden und man möchte „Wildwuchs“ vermeiden und Interoperabilität fördern. Daher ist damit zu rechnen, dass in zukünftigen Versionen diese (momentan noch recht einfache) Interface erweitert werden wird bzw. weitere Interfaces dazu eingeführt werden.
- Kleinkram, der neu ist:
- private Methoden in Interfaces.
- neue Operationen auf den Streams (aus Java 8) z.B.
- dropWhile, takeWhile, iterate (erzeugt Stream, wenn ich Operatoren habe, die aus einem Startelement immer das nächste erzeugen)
- neue Kollektoren filtering, flatMapping
- Spin Wait Hints:
- Bei „Busy Waits“, die auf „volatile“ Variablen basieren, kann einem nun die VM „helfen“ (d.h. CPU-Zeit sparen), in dem man in der Loop
Thread.onSpinWait()
aufruft. Ob das allerdings überhaupt eine Methode ist, die anzustreben ist, wage ich zu bezweifeln…
- Bei „Busy Waits“, die auf „volatile“ Variablen basieren, kann einem nun die VM „helfen“ (d.h. CPU-Zeit sparen), in dem man in der Loop
- Interaktive Java-Shell (JSHell) (s.a. https://docs.oracle.com/javase/9/tools/language-shell.htm)
- starten mit
jshell
. - Shell-Kommandos u.a.:
- /imports (zeigt aktive imports)
- /list (zeigt alle in der Shell lokal definierten „Dinge“)
- /hist (History)
- kann via API aus laufender Anwendung heraus gestartet werden, um z.B. in der Anwendung zu „debuggen“. (Über die Debugger Schnittstelle geht das aber (noch?) nicht.)
- starten mit