Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Die Zukunft von Java - was steck für uns drin? ...

Die Zukunft von Java - was steck für uns drin? (Seacon 2022)

Seit dem Release von Java 9 im September 2017 bekommen wir alle 6 Monate eine neue Java Version. Das bedeutet, dass wir schneller von neuen Features in unseren Anwendungen profitieren können. Aber welche spannenden Features sind langfristig eigentlich geplant oder schon in Entwicklung? Wir schauen uns gemeinsam die derzeit wichtigsten OpenJDK-Projekte an, die sowohl die Programmiersprache Java als auch die JVM nachhaltig verbessern werden oder bereits verbessert haben.

Zusammen gehen wir darauf ein, wie und warum uns die Projekte Amber, Loom, Valhalla und Panama helfen werden
* die Entwicklerproduktivität zu steigern
* die Performance und Skalierbarkeit unserer Anwendungen zu verbessern und
* Ressourcen (CPU, Speicher) zu sparen.

In der Summe führen sie dazu, dass Java und die JVM für viele Projekte auch in Zukunft eine wichtige und relevante Technologie bleibt, die uns bei der Lösung unserer technischen und fachlichen Herausforderungen unterstützt.

Avatar for Johannes Jank

Johannes Jank

May 19, 2022

More Decks by Johannes Jank

Other Decks in Technology

Transcript

  1. Die Zukunft von Java Was steckt für uns drin? Johannes

    Wengert, 19.05.2022 - SEACON digital 2022
  2. 3 Über mich Johannes Wengert Software-Entwickler | bbv Software Services

    GmbH | München • Java-Entwickler und OpenJDK-Enthusiast • Leiter bbv-interne Java-Community
  3. • Java heute und die Design-Ziele der Evolution • Die

    großen vier Gamechanger Projekte: • Amber - Mehr Ausdruck, weniger Zeremonie • Loom – Moderene und hochgradig skalierbare Concurrency • Valhalla - Performance-Boost durch Value- und Primitive Classes • Panama – Neue Tore in die Welt nativer Libraries öffnen • Timeline & Zusammenfassung 5 Java Die Zukunft ist lebendig und spannend
  4. Seit JDK 9 gibt es Java-Releases alle 6 Monate •

    Java 17 Release im September 2021 – von vielen Distributoren mit Long-Term Support • Wird vermutlich in vielen Umgebungen die neue default-Version werden • Viele kleine und große Verbesserungen sind bereits im JDK und bringen Mehrwert • Neue und verbesserte APIs (HTTP-Client, Stream::toList, java.util.HexFormat,...) • JFR (Java Flight Recorder) seit JDK11 Open Source • Zahllose mikro- und makro-Optimierungen in der Runtime und den Core-Libraries (Compact Strings (JEP 254), String::format ist 3x schneller…) • Neuer ZGC Garbage-Collector mit Pausen-Zeiten im Sub-Millisekunden Bereich 6 Heute Java 18
  5. Alle Entscheidungen über die Entwicklung der Java-Plattform sind von zwei

    wesentlichen Zielen motiviert: 1. Langzeit-Ziele in den Vordergrund stellen – dabei sehr genau die Balance zwischen Innovation und Erhaltung von Altem berücksichtigen 2. Kompatibilität und Lesbarkeit dabei erhalten Per Definition ist Java ein „late Adopter“ 7 Reminder Design Goals für die Evolution von Java
  6. • Projektstart 2017, angeführt von Brian Goetz • Kleine, oft

    voneinander unabhängige Verbesserungen der Java-Syntax • Mehr Ausdrucksstärke • Weniger Zeremonie • Mehr Typsicherheit und präzisere Modellierung der Domäne • Viele dieser Features sind schon fertig und können verwendet werden 9 Amber Background & Ziele
  7. JEP 361: Switch Expressions – Keine breaks, kein fall-through |

    Java 14, März 2020 enum ExternalResult { OK, WARN, ERROR } enum InternalStatus { DONE, RETRY } 11 Amber in Action: Switch Expressions
  8. InternalStatus mapToStatus(ExternalResult result) { switch (result) { case OK: return

    InternalStatus.DONE; case WARN: // Fallthrough L case ERROR: return InternalStatus.RETRY; default: throw new IllegalArgumentException("unexpected: " + result); } } 12 Amber in Action: Switch Expressions InternalStatus mapToStatus(ExternalResult result) { return switch (result) { case OK -> InternalStatus.DONE; case WARN, ERROR -> InternalStatus.RETRY; }; } InternalStatus mapToStatus(ExternalResult result) { return switch (result) { case OK -> InternalStatus.DONE; case WARN, ERROR -> InternalStatus.RETRY; // Kein default - der Compiler kennt alle Enum-Werte }; } InternalStatus mapToStatus(ExternalResult result) { return switch (result) { case OK -> InternalStatus.DONE; case WARN, ERROR -> InternalStatus.RETRY; }; } InternalStatus mapToStatus(ExternalResult result) { return switch (result) { case OK -> InternalStatus.DONE; case WARN, ERROR -> InternalStatus.RETRY; // Kein default - der Compiler kennt alle Enum-Werte }; }
  9. JEP 378: Text Blocks – Schmerzfreie Multiline-Strings | Java 15,

    September 2020 String json = "{\n" + " \"foo\": 42,\n" + " \"bar\": \"baz\"\n" + "}\n"; String json = """ { "foo": 42, "bar": "baz" } """; 13 Amber in Action: Text Blocks
  10. JEP 394: Pattern Matching for instanceof – Einstieg in Pattern-Matching

    | Java 16, März 2021 if (obj instanceof String) { String s = (String) obj; // ¯\_(ツ)_/¯ return s.toLowerCase(); } if (obj instanceof String s) { return s.toLowerCase(); } 14 Amber in Action: Instanceof Patterns
  11. JEP 395: Records – Transparenter Träger für unveränderliche Daten |

    Java 16, März 2021 // Immutable Objects heute final class StorageObject { private final String bucket; private final String key; StorageObject(String bucket, String key) { this.bucket = bucket; this.key = key; } // accessors // equals // toString // hashcode } 15 Amber in Action: Records
  12. // implizit final, alle Felder sind final record StorageObject(String bucket,

    String key) { // Compiler generiert: // * Konstruktor // * equals/hashCode/toString (via invokedynamic) // * Accessors bucket(), key() } void useRecords() { var so = new StorageObject("bucket", "key"); var bucket = so.bucket(); // Accessors – Records sind keine JavaBeans var key = so.key(); System.out.println(so); // StorageObject[bucket=bucket, key=key] } 16 Amber in Action: Records
  13. record StorageObject(String bucket, String key) {} 17 Amber in Action:

    Records record StorageObject(String bucket, String key) { // "compact constructor" mit automatischen Bindings der Fields // Security-Plus: Serialization umgeht bei Records nie den Konstruktor StorageObject { Objects.requireNonNull(bucket, "bucket"); Objects.requireNonNull(key, "key"); } } record StorageObject(String bucket, String key) implements Comparable<StorageObject> { // "compact constructor" mit automatischen Bindings der Fields // Security-Plus: Serialization umgeht bei Records nie den Konstruktor StorageObject { Objects.requireNonNull(bucket, "bucket"); Objects.requireNonNull(key, "key"); } @Override public int compareTo(StorageObject other) { // ... } }
  14. JEP 409: Sealed Types – geschlossene Typhierarchien | Java 17,

    September 2021 // `sealed` und `permits` sagen: // * wir erlauben exakt 2 hier genannte Implementierungen des Interfaces // * Diese müssen zur Compile-Zeit existieren sealed interface AvResource permits AudioResource, VideoResource { Duration duration(); } // Implementierungen müssen final sein - records sind hier ideal record AudioResource(Duration duration, SampleRate sampleRate) implements AvResource {} record VideoResource(Duration duration, Dimensions dimensions) implements AvResource {} 18 Amber in Action: Sealed Types
  15. JEP 427: Pattern Matching for switch (3rd Preview) – Preview

    in Java 19, September 2022 19 Amber in Action: Pattern Matching für switch boolean validate(AvResource resource) { return switch (resource) { case AudioResource a -> a.duration().isPositive() && a.sampleRate().isProAudio(); case VideoResource v -> v.duration().isPositive() && v.dimensions().isHd(); // kein default nötig, weil `sealed` type }; } 3. Preview-Runde, weil durch Feedback aus der Community Syntax und Semantik immer weiter verbessert wurden boolean validate(AvResource resource) { return switch (resource) { case AudioResource a -> a.duration().isPositive() && a.sampleRate().isProAudio(); case VideoResource v -> v.duration().isPositive() && v.dimensions().isHd(); // kein default nötig, weil `sealed` type }; } boolean validate(AvResource resource) { return switch (resource) { case AudioResource a -> a.duration().isPositive() && a.sampleRate().isProAudio(); case VideoResource v -> v.duration().isPositive() && v.dimensions().isHd(); // kein default nötig, weil `sealed` type }; } boolean validate(AvResource resource) { return switch (resource) { case AudioResource a -> a.duration().isPositive() && a.sampleRate().isProAudio(); case VideoResource v -> v.duration().isPositive() && v.dimensions().isHd(); // kein default nötig, weil AvResource ein `sealed` Type ist }; }
  16. • Project Amber bringt für unsere tägliche Produktivität schon jetzt

    wichtige Verbesserungen mit • Mehr Ausdrucksstärke, weniger Raum für Bugs und Sicherheitslücken • Schnellere Java-Releases begünstigen schnelleres Feedback und kürzere Iterationen bei neuen Features • Pattern Matching passt auch gut zu Java • Es sind noch mehrere spannende Ideen in der Entwicklung (z.b. ein Draft für Templated Strings) 22 Amber Zusammenfassung
  17. • Projektstart 2018, angeführt von Ron Pressler • Neue, leichtgewichtige

    Implementierung von Threads in der JVM • Neues Concurrency-Programmiermodell „Codes like sync – performs like async“ 24 Loom Background & Ziele
  18. Heute haben wir die „Wahl“ zwischen synchronen und asynchronen/reactive APIs

    26 Loom Concurrency in Java heute Threads Requests App Synchron • Einfach, verständlich • nicht gut skalierbar Threads Requests App Asynchron oder Reactive • Gut skalierbar • Komplex • Profiling & Debugging ist schwer
  19. • Eine Implementierung – dünner Wrapper um Platform-Threads • Platform-Threads

    brauchen viele Resourcen, insbesondere Speicher • Task-Switching und Scheduling passieren im Kernel bzw. im OS • Der Scheduler des OS muss generisch sein und kann nichts optimieren • Die “Lösung” Thread-Pools 27 Loom java.lang.Thread JVM j.l.Thread j.l.Thread j.l.Thread j.l.Thread OS Platform- Thread Platform- Thread Platform- Thread Platform- Thread
  20. • Virtual Threads sind einfach nur Threads – Implementiert in

    der Java Runtime • Blockieren eines virtual Threads ist nicht mehr teuer: • Synchronization und I/O ist “virtual friendly” • Blockt ein vThread (weil er z.B. auf I/O wartet), wird er vom Carrier-Thread unmounted • Verbraucht in dieser Zeit keine CPU-Resourcen • Scheduler ist in Java implementiert und bei Bedarf sogar austauschbar 28 Loom virtual Threads to the rescue JVM OS Platform- oder “Carrier”-Thread … vThread vThread vThread vThread vThread vThread vThread vThread vThread vThread vThread vThread vThread vThread vThread vThread vThread vThread vThread vThread …
  21. • Virtual Threads sind für Java der richtige Ansatz, um

    das Skalierungs-Problem zu lösen • Threads sind ein zentraler Baustein in Java, nahezu alles dreht sich um Threads: • Exceptions • Debugger • Profiler • Thread Locals • Virtual Threads sind ein mächtiges Konzept, das sich in Sprachen wir Go oder Erlang schon bewährt hat 29 Loom Threads sind überall
  22. Idee: Der Kontrollfluss von Threads und Concurrent-Tasks spiegelt sich in

    der Blockstruktur des Codes wieder. Der Begriff Structured Concurrency wurde geprägt von Martin Sústrik und Nathaniel J. Smith Die Api wird in etwa so aussehen: 30 Loom Structured Concurrency try(// Ein Exectutor, der virtuelle Threads erstellt) { } // Erst wenn alle Tasks beendet sind, wird der Block verlassen try(// Ein Exectutor, der virtuelle Threads erstellt) { // * Executor verwenden, um Tasks zu submitten // * Handler für Fehler spezifizieren // * Auf das Ergebnis der Tasks warten, z.b. mit Future::get } // Erst wenn alle Tasks beendet sind, wird der Block verlassen try(// Ein Exectutor, der virtuelle Threads erstellt) { }
  23. • Project Loom wird für viele Use-Cases den Einsatz von

    asynchronen oder reactive Libraries in Zukunft überflüssig machen • Weniger Komplexität im Code • Hohe Skalierbarkeit mit wenig Resourcen • Keine Abhängigkeit zu Libraries • Virtual Threads (JEP 425) werden in Java 19 Preview-Feature J • Structured Concurrency (JEP 428) kommt in das incubator Modul in Java 19 Call to Action: Probiert Virtual Threads aus, gebt Feedback und macht sie für uns alle noch besser! 33 Loom Zusammenfassung
  24. • Projektstart 2014, angeführt von Brian Goetz • Sichtbares bzw.

    vordergründiges Ziel: • Einführung eines neuen Typs, Value Types – „Codes like a class, works like an int“ • Performance-Verbesserungen: • Indirektionen über Referenzen bzw. Pointer werden vermieden • Kompaktere Speicher-Layouts sind möglich • Besseres Inlining von Werten durch die JVM, wenn sie frei kopierbar sind • Subtileres Ziel: Reference-Types und Primitives zusammenbringen • Komplexes und ambitioniertes Projekt, denn es betrifft den ganzen Stack: • vom Classfile-Format… • …bis hin zum Programmiermodell • “…six Ph.D theses, knotted together.” ~James Gosling 35 Valhalla Background & Ziele
  25. • Die lange und intensive Phase von Prototypen und Feedback

    hat ergeben, dass es sinnvoll ist zwei neue Typen einzuführen: • Value Classes (keine Identität, aber noch Objekt-Referenz) • Primitive Classes (keine Identität, keine Referenz) • Warum überhaupt einen Reference-Type? - Kompatibilität und Migration wird sonst ein fast unlösbares Problem 37 Valhalla Value Classes und Primitive Classes
  26. • Reference-Types (nullable, default Wert ist null), ohne Object-Identity •

    Immer noch Klassen und haben die meisten Eigenschaften normaler Klassen mit wenigen Einschränkungen (z.B. keine synchronized Methoden, keine Vererbung von State) • Weil sie Values sind, werden sie mit == verglichen • Genau wie primitives sind sie frei kopierbar durch die JVM – Sie können zerlegt und ihre Felder frei in andere Objekte kopiert werden • Kandidaten im JDK: java.util.Optional oder java.time.LocalDateTime value class CustomerId implements Comparable<CustomerId> { private String id; // implizit final // …Konstruktor @Override public int compareTo(CustomerId other) { … } } 38 Valhalla Value Classes
  27. • Keine Referenz mehr (nicht nullable, haben einen default-Wert) •

    Gleiche Performance wie die eingebauten Primitives • Können Interfaces implementieren und von abstrakten Klassen erben • Obwohl sie „rohe Daten“ sind, funktioniert Polymorphismus primitive class Complex implements Serializable { private double re; // beide implizit final private double im; // Konstruktor Complex scale(double s) { return new Complex(s * re, s * im); } } 39 Valhalla Primitive Classes
  28. • Project Valhalla wird signifikante Performance-Optimierungen für Java und die

    JVM mit sich bringen • Java kann dadurch auch für Domänen interessanter werden, in denen es bisher keine besonders wichtige Rolle gespielt hat, z.b. Machine-Learning, numerische Libraries, … • Einige Draft JEPs existieren bereits: Value Objects, Primitive Classes (1), Primitive Classes (2), Universal Generics • Der Weg dorthin ist noch etwas weiter – Das Dokument The Road to Valhalla vom Dezember 2021 gibt einen guten Überblick über den derzeitigen Stand • Vorsichtige Schätzungen sehen Value Classes als Preview in Java 20 (03/2022) 40 Valhalla Zusammenfassung
  29. • Projektstart 2014, angeführt von Maurizio Cimadamore • Ziele: •

    Moderner Ersatz für JNI (Java Native Interface) • Sichere und schnelle APIs um mit nativem (nicht-Java) Code und Speicher (off-Heap) zu interagieren • API für zuverlässige Nutzung von CPU Vektor-Instruktionen • Das einfachere Interagieren mit nicht-Java Libraries soll – ähnlich wie bei Project Valhalla – Java für Domänen wie Machine-Learning attraktiver machen. • Viele relevante Libraries wie z.B. Tensorflow haben z.B. oft keine aktuellen Java Bindings, weil das bisherige Tooling zu umständlich ist und die Bindings mühsam zu warten sind • Aber auch weniger exotische Anwendungsfälle wie Kryptografie oder Kompression möchten native Libraries wie OpenSSL oder Brotli ansprechen 42 Panama Background & Ziele
  30. • Das Projekt ist teilweise schon recht weit: • Foreign

    Function & Memory API (JEP 424) wird in Java 19 Preview Feature • Die Vector- und Forgein Linker APIs sind incubating (JEP 417, JEP 389) • Wegen der engen Interaktion mit Panama wird das Programmiermodell aber vermutlich noch einmal angepasst werden, sobald Value- und Primtive Classes fertig sind • jextract (JNI-Ersatz) wird vermutlich als separates Tool veröffentlicht werden, um schnellere Iterationen zu ermöglichen 43 Panama Status & Zusammenfassung
  31. Die nachfolgende Timeline ist eine reine Schätzung und hat absolut

    keine Verbindlichkeit! 45 Timeline Disclaimer
  32. JDK 21 09/2023 Primitve Classes & Universal generics Vector API

    Virtual Threads JDK 19 09/2022 Record Patterns (Preview),… Foreign Memory-API (Preview) Virtual Threads (Preview) 46 Timeline Schätzung JDK 20 03/2023 Deconstruction Patterns, Template Strings Virtual Threads… & Structurred Concurrency (Preview) Value Classes JDK 22/23 2024 Structurred Concurrency Mehr zu Pattern Matching JDK 24/25 2025 Specialized Generics Amber Loom Valhalla Panama
  33. Java wird aktiv weiterentwickelt, um die technischen und fachlichen Probleme,

    die wir heute in unseren Projekten finden effizienter zu lösen Effizienz hat mehrere Dimensionen: • Entwickler-Produktivität durch moderne Sprachfeatures und besseres Tooling • Ressourcen-Effizienz durch bessere Nutzung der vorhandenen Hardware Effizienz = Einsparung von Kosten Feedback und Diskussion zu neuen Features ist explizit erwünscht und wird berücksichtigt 47 Zurück zur Frage Was ist für uns drin?
  34. Wer mehr wissen oder auf dem Laufenden bleiben will: https://inside.java/

    ist der beste Einstiegspunkt 48 Zum Schluss Quellen und Feedback Ich würde mich freuen, wenn ihr euch kurz Zeit nehmt und meinen Vortrag bewertet J
  35. bbv Software Services GmbH Elsenheimerstr. 9 80687 München www.bbv.eu [email protected]

    Telefon +49 89 452 4383 43 LinkedIn Johannes Wengert | Professional Technical Consultant