blog

25
Feb

„Java muss sich für die Ära der Microservices und des Machine Learning bereit machen“

Wie sollte sich Java weiterentwickeln? Was bedeutet die beschleunigte Release-Frequenz für die Community? Wie sind Trends wie Blockchain, Machine Learning, Serverless zu bewerten? Eine Einschätzung gibt Dr. Heinz Kabutz, Java-Performance-Experte und Trainer auf dem Extreme Java Camp, im Interview.

Wie sollte sich Java weiterentwickeln?

JAXenter: Java ist als Programmiersprache schon über 20 Jahre auf dem Markt. Dabei wurde die Sprache immer wieder erweitert und an die neuen Herausforderungen angepasst. Wo siehst du momentan aber noch Lücken? Wie sollte sich Java in den nächsten Jahren weiterentwickeln?

Durch Javas massive Rückwärtskompatibilität ist es sehr schwer, neue Features zu implementieren.

Heinz Kabutz: Die Programmiersprache Java wurde in den letzten Jahren stets langsam und sorgfältig weiterentwickelt. Ein großes Thema dabei war und ist die Rückwärtskompatibilität. In mehr als 20 Jahren habe ich über etliche komische, fragwürdige und wundervolle Java Hacks geschrieben – manche aus dem Jahr 2000 funktionieren sogar heute noch in Java 11. Auch Bugs in der Sprache haben sich völlig unbehelligt immer wieder auf die gleiche Weise eingenistet, unabhängig von der Sprachversion, und als veraltet markierte Methoden werden ohnehin praktisch nie entfernt.

Das alles ist allerdings ein zweischneidiges Schwert. Auf der einen Seite freuen sich die Unternehmen natürlich, denn sie wissen, dass ihre Anwendungen auch mit neueren Java-Versionen problemlos funktionieren – ohne neuer Kompilierung oder irgendwelchen Änderungen, die vorgenommen werden müssten. Auf der anderen Seite sind die Entwickler der Sprache durch diese massive Rückwärtskompatibilität in ihrer Entfaltung stark eingeschränkt, sodass es sehr schwer ist, neue Features zu implementieren.

Mit Projekt Valhalla werden in Java sogenannte “Value Types” verfügbar, die allerdings die Designschwäche von Java 1.0 übernehmen, durch die sämtliche Java-Objekte als synchronisierte Monitore verwendet werden können. Was soll nun passieren, wenn wir eine Synchronisierung mit “Value Type” durchführen? Das ist die große Frage. Projekt Loom ist auch ein gutes Beispiel: Hiermit sollen “Fibers” als leichtgewichtige Threads der Sprache hinzugefügt werden, doch wie soll ThreadLocal implementiert werden? Welche Kosten eine solche Form der Rückwärtskompatibilität haben kann, haben wir an den Generics gesehen. Typen-Auslöschung bedeutet, dass ein ArrayList<String> exakt der gleiche Typ ist, wie ein ArrayList<Integer>.

Hinzu kommt, dass die Entwicklerwelt immer weiter in Richtung der Cloud bewegt, viele Anwendungen, die ich für mein Geschäft benötige, sind komplett Web-basiert. Es gibt nur noch ein paar, die lokal laufen, etwa meine Videoschnittsoftware und meine Java IDE. Die meisten Apps liegen allerdings irgendwo auf einem Server. Java muss sich für die Ära der Microservices und des Machine Learning bereit machen, denn eins ist sicher: Die Tage, in denen jedes Unternehmen Server-Farmen unterhält, sind eindeutig gezählt.

Java-Releases im Jahr 2019

JAXenter: Konkret stehen in diesem Jahr Java 12 und Java 13 an. Welches neue Feature ist aus deiner Sicht ein wirkliches Highlight?

Heinz Kabutz: Java 12 hat mich komplett verwirrt. Ja, wir haben die neuen verbesserten Switches, aber dieses Programmiermodell habe ich in meinen Projekten durch die Nutzung des Strategy Design Pattern stets vermieden. Die restlichen Änderungen beziehen sich fast ausschließlich auf Verbesserungen der Garbage Collection.

Java 11 hatte allerdings ein interessantes Feature, nämlich sich dynamisch in ihrer Größe anpassende String Pools. In früheren Versionen von Java war der intern() String Pool relativ klein, lediglich 1009 Einträge waren möglich. In Java 7 fasste er schon 60013 Strings, war aber immer noch mit einer festen Größe definiert, die Performance nahm also linear ab, je größer der Pool wurde. Seit Java 11 wird der Pool dynamisch größer, je nachdem wie viele Einträge vorgenommen werden.

Um mit Sicherheit zu sagen, was Java 13 bringen wird, ist es noch etwas früh. Aber die kürzere Release-Kadenz sorgt dafür, dass es aller Wahrscheinlichkeit nach kein großes Update sein wird.

Javas neue Release-Politik

JAXenter: À propos Release-Kadenz. Der Veröffentlichungszyklus von Java-Versionen hat sich nun ja deutlich beschleunigt. Jedes Jahr gibt es zwei neue Releases. Du bist als Java-Experte viel mit Unternehmen und IT-Abteilungen in Kontakt. Was sind hier deine Erfahrungen: Wie werden diese Unternehmen mit den schnelleren Java-Updates umgehen?

Heinz Kabutz: Unternehmen müssen sich jetzt entscheiden, welche Strategie sie fahren wollen. Sollten sie beim Oracle JDK bleiben, müssen sie sich ab Version 11 eine kommerzielle Lizenz für die Nutzung von Java besorgen. Wechseln sie auf das OpenJDK, sollten sie bedenken, dass Oracle lediglich einen Support bis Java 12 bereitstellt. Ab Java 13 ist an der Stelle die Community gefragt.

Viele Unternehmen werden wohl schlicht und ergreifend einen Scheck für den kommerziellen Support an Oracle ausstellen und weiter das Oracle JDK verwenden. Für alle anderen wäre es allerdings sinnvoll, wenn sie die kürzeren Release-Zyklen verinnerlichen und alle sechs Monate auf die nächste Version umsteigen würden.

Der neue Release-Zyklus von Java macht alles viel schwieriger.

JAXenter: Was ist deine persönliche Meinung dazu? Ist der neue Release-Zyklus ein Vorteil oder Nachteil?

Heinz Kabutz: Es macht alles viel schwieriger. In der Vergangenheit vergingen mehrere Jahre zwischen den Releases. Dadurch war es einfacher, sich zu erinnern, welches Feature in welchem Release vorkam. Ich konnte ein Jahr darauf verwenden, einen Kurs für Java 8 zu erstellen, weil ich wusste, dass ich ihn lange als Lehrmaterial würde nutzen können. Ende 2017 habe ich einen Kurs mit dem Titel „Datenstrukturen in Java 9“ erstellt. Drei Monate später konnten wir Java 9 nicht mehr herunterladen. Daher benannte ich den Kurs kurzerhand in „Datenstrukturen in Java“ um, damit die Leute ihn weiter buchen würden. Die Datenstrukturen haben sich seit Java 9 schließlich kaum verändert, und daher ist der Kurs weiterhin sehr relevant.

Eine weitere große Herausforderung liegt darin, dass Unternehmen durch die Änderung der Oracle-Lizenzen und den schnellen Releasezyklus ganz verschreckt sind. Sie investieren große Summen in alternative Lösungen wie AngularJS, Go und Python. Java wird es noch viele Jahre geben, aber viele neue Projekte wandern zu anderen Optionen ab.

Java Concurrency Tipps

JAXenter: Im Extreme Java Camp stellst du fortgeschrittene Java-Themen vor: Lambdas, Reflection-API, VarHandles, Thread Pool Executors, MethodHandles, StampedLock, LongAdder, parallele Streams, CompletableFuture, VarHandles und vieles mehr. Kannst du einmal einen kleinen Vorgeschmack geben? Ein Tipp, den Java-Entwickler in ihre Arbeit integrieren können?

Heinz Kabutz: Dann greife ich einmal eines der erwähnten Themen heraus: den LongAdder. Die Klasse basiert auf Striped64. Sie verwendet Lock Striping, um Konflikte in einer gemeinsam genutzten Datenstruktur zu reduzieren. Ein frühes Beispiel von Lock Striping war ConcurrentHashMap. Stripes64 geht einen Schritt weiter. Es enthält ein Array von Zellen. Wenn mehrere Threads den LongAdder aktualisieren, beginnen sie damit, in eine einzelne Zelle zu schreiben. Jedesmal, wenn wir ein CAS-Fehler bekommen (Compare-and-Swap) – also wenn unser Schreibversuch in die Zelle mittels Compare and Swap nicht erfolgreich war, weil ein anderer Thread gleichzeitig schreiben wollte – verdoppelt sich die Größe des Zellen-Arrays.

Die Zelle verdoppelt sich immer weiter, bis die maximale Anzahl an Hardware Threads in unserem System erreicht ist – aufgerundet zur nächsten Zweierpotenz. Nehmen wir einmal zum Beispiel mein neues MacBookPro, das 6 Kerne und 12 Hyperthreads hat. Java behandelt das als 12-Prozessor-Maschine. Die maximale Anzahl an Zellen ist dann 16. Es ist durchaus möglich, dass zwei Threads etwas in dieselbe Zelle schreiben – aber wir verteilen die Zellen zwischen den Threads so, dass die Wahrscheinlichkeit dafür verringert wird.

Dadurch erreichen wir gut und gerne eine 10 Mal höhere Geschwindigkeit, verglichen mit einer Synchronisierung via AtomicLong. Dort wird übrigens das Feld threadLocalRandomProbe in einem Thread verwendet, um zu entscheiden, wie ein Thread einer Zelle zugewiesen wird. Da dies ein Package-private Feld in einem Thread ist, können wir es nicht direkt lesen. Reflection wäre zu langsam. In Java 8 wurde sun.misc.Unsafe genutzt – aber seit Java 9 kommt MethodHandles.privateLookupIn() zum Einsatz, das wohl speziell für Striped64 hinzugefügt wurde. Um solche Tipps und Tricks geht es im Extreme Java Camp – und weit über die erwähnten Beispiele hinaus, wie etwa der Unterschied zwischen Padding und Contention. Hoffentlich ist der eine oder andere Leser mit dabei!

Beyond Java: Blockchain, Machine Learning, Serverless & Co.

JAXenter: Wenn wir einmal das Java-Universum verlassen: In anderen Communities tut sich ja auch sehr viel momentan – Stichwort: Blockchain, Machine Learning, Serverless oder neue Sprachen wie Kotlin, Go, TypeScript, Rust, etc. Welche Entwicklung in der IT findest du hier gerade spannend?

Heinz Kabutz: Das ist alles spannend, aber ich finde, man sollte dabei das Menschliche nicht vergessen. Die Blockchain ist eine Technologie, die durch Bitcoin populär wurde, sie hat aber natürlich auch viele andere Einsatzmöglichkeiten: Wir haben z.B. bei JCrete mit einer manuellen Blockchain Geld für eine Schule gesammelt. Mehr über das Projekt kann man hier auf Twitter erfahren.

Machine Learning ist schön und gut, aber wir verlieren die menschliche Perspektive immer mehr aus den Augen.

Aber der Hype rund um Bitcoins hat schon viele Menschen um ihr schwer erspartes Geld gebracht und wird es wohl auch weiterhin tun. Die Bedrohungen können krimineller Natur in Form von Hackern sein. Aber auch ein Wertverfall der Währung (ca. 82% seit Dezember 2017) kann viel Geld kosten. Und nun hat ein CEO sein Passwort mit ins Grab genommen und damit Bitcoins von Kunden im Wert von 145 Millionen Dollar vernichtet.

Machine Learning ist auch so eine Sache. Das Ganze ist schön und gut, aber wir verlieren dabei die menschliche Perspektive immer mehr aus den Augen. In vielen Ländern darf man sein Gepäck am Flughafen selbst wiegen und anschließend die entsprechenden Etiketten anbringen. In Europa gibt es zum Glück noch oft genug Personal, das einem helfen kann, wenn etwas schiefgeht. Denn wenn mit Machine Learning etwas aus dem Ruder läuft, dann macht es das normalerweise in gewaltiger Art und Weise.

Serverless finde ich schon recht interessant, führt aber zum Teil auch zu mehr Risiken, insbesondere in Unternehmen. Zurzeit sind die Möglichkeiten außerdem noch recht proprietär, sodass man nicht so einfach zwischen Anbietern wechseln kann. Und das wirklich Kostbare sind nach wie vor die Daten.

Was Programmiersprachen angeht, finde ich Kotlin recht interessant. TypeScript ist für uns Entwickler aber auch sehr wichtig. Ich habe mir vor allem auch die Sprache Go angeschaut und meine, dass diese vor allem im Zusammenhang mit Serverless Anklang finden wird.

JAXenter: Vielen Dank für dieses Interview!

Keine Infos mehr verpassen!