Podcast

Java 21

Alles zum neuen LTS-Release

Heute ist es soweit: Java 21, das neueste LTS-Release, erscheint. Sven bespricht in dieser Folge mit unserem Java-Experten Michael, was uns im aktuellsten Long-term Support Release alles erwartet, welche Neuerungen er besonders wichtig findet und welche Features das Arbeiten erleichtern werden. Von Virtual Threads über Structured Concurrency bis zu Scoped Values kommen innovative Aspekte wie Record Patterns, namenlose Variablen, Optimierungen des Z Garbage Collectors, CRaC und String Templates hinzu. Happy Downloading Java 21!
Weitere Episoden anhören

Shownotes & Links

Transkript

Transkript ausklappen / einklappen

Sven Johann Herzlich willkommen zu einer neuen Folge des INNOQ Podcasts. Gast ist heute Michael Vitz, Java 21 ist gerade rausgekommen. Vielleicht sogar heute, je nach Release Termin. Michael ist Java Champion und daher müssen wir reden. Michael, außer dich mit Java zu beschäftigen. Was machst du sonst noch so bei INNOQ?

Michael Vitz Hi, ich bin Michael. Ich mache halt meistens Java in meinen Projekten und sonst mache ich bei INNOQ das, was wir in Projekten so anfällt. Viel Backend, viel auf der JVM. Ich verirre mich aber auch schon ins Frontend und neben Projektarbeit schreibe ich Artikel, halte Vorträge und macht das, was ein Consultant so tut.

Sven Johann Java 21 ist ein LTS - Long Term Support Release. Was bedeutet das überhaupt genau?

Michael Vitz Ich hätte jetzt noch mal nachgucken müssen, aber ich meine, kurz vor oder mit JDK 17 haben sie eben beschlossen. Nee, muss noch früher muss gewesen sein. Irgendwo 9, 10 rum haben sie festgestellt, dass früher alle 3 bis 4 Jahre so ein Java Release rauskam und dass das eben doch eine lange Zeit ist. Ich meine, zwischendurch waren noch mal fünf Jahre zwischen zweien und dann wurde eben von Oracle vorgeschlagen, sie würden ganz gerne jedes halbe Jahr einfach ein Java releasen und das dann anders machen als vorher. Vorher war es so: Wir wollen fünf Features fertig haben und es kommt dann raus, wenn die Features fertig sind und damit sind sie quasi umgeschwenkt. Jetzt kommt jedes halbe Jahr terminiert ein Release raus und was drin ist, ist drin und was nicht drin ist, kommt halt später. Und dann gab es aber natürlich einen Aufschrei durch die Community, weil wir in der Java Welt sind auch an Stabilität und an längere Zyklen gewohnt. Und dann wurde irgendwie gesagt: Naja, kommt zwar jedes Halbjahr ein Release raus, aber nicht alle Hersteller werden für jedes 5, 6, 7, 10 Jahre Support anbieten. Und dann hat man sich damals darauf geeinigt, dass alle drei Jahre, also alle sechs Releases ein so ein inoffizielles LTS Release wird, wo dann eben eigentlich alle Hersteller Support für anbieten. Alle, die ich kenne, bieten dann Support. Und kurz nach JDK 17, das war quasi dann, 11 gab es als LTS und dann 17, ist Oracle dann noch mal vorgeprescht und hat gesagt: Naja, wir würden ganz gerne das noch verkürzen und ab jetzt alle zwei Jahre ein LTS machen und dementsprechend ist jetzt 21 quasi das erste, nach zwei Jahren. Und neben Oracle bieten die gängigen anderen Hersteller auch Support an. IBM, AWS mit Corretto, Microsoft hat auch ein eigenes, wo ich die Namen nicht weiß. Also die alle werden das jetzt länger supporten.

Sven Johann Ich finde es sehr gut, dass das mal ein bisschen schneller vorwärts geht. Wie siehst du das?

Michael Vitz Ich finde es auch ganz gut. Vor allen Dingen haben sie jetzt auch noch, ich greife jetzt ein bisschen vor, ist gar nicht so schlimm. Es werden auch noch zwei verschiedene Arten von Features, dann hinzugefügt. Es gibt jetzt eben nicht nur noch diese finalen Features, sondern es gibt jetzt noch so Incubator und Preview Features. Incubator Features erlaubt super früh einen sehr frühen Stand einfach mal zu releasen mit so einem Feature und dann kann man mal ausprobieren mit so einem Release. Wie funktioniert das? Bei Incubator Features ist dann noch die Besonderheit, die können auch wieder gedroppt werden, wenn man doch merkt: Das funktioniert so gar nicht. Und Preview Features ist dann eben schon etwas weitere Phase. Dann ist man sich sicher: Das Feature wird schon so kommen und vermutlich auch in etwa in der Art, wie wir es haben. Aber dann kann man eben auch da testen und für beide muss man dann aber noch so einen Flag angeben, sowohl beim Kompilieren als auch zur Ausführung, damit sichergestellt ist, dass nicht jemand sich auf ein Feature verlässt, dann fällt es weg oder wird vollkommen geändert und meckert dann. Ich baue meinen ganzen Produktions-Code darauf. Das kann man von 17 zu 21 auch schon sehen. Gerade diese Zwischen-Releases 18, 19, 20 enthalten unwahrscheinlich viele Preview und Incubator Features und vieles davon ist jetzt mit 21 dann final geworden. Da hat man die zwei Jahre genutzt, damit die, die eben nicht von LTS zu LTS springen, das Feature mal ausprobieren können und Rückmeldung geben können und die, die von LTS zu LTS springen haben jetzt aber die Chance, das Feature dann in der finalen Form direkt zu benutzen. Ich glaube, das funktioniert auch ganz gut.

Sven Johann In deinen Projekten, was empfiehlst du da? Sollte man von LTS zu LTS springen? Also immer nur eine LTS Version haben oder auch ständig die neueste nehmen?

Michael Vitz Ich habe im Projekt, glaube ich, beides gehabt. Ich bin persönlich ein bisschen konservativer. Und gerade dadurch, dass jetzt so viele auch immer nur Incubator und Preview Features waren, hatte ich das Gefühl, es hat sich nicht so richtig gelohnt, die ganzen Zwischen-Releases mitzunehmen. Zumal man dann auch alle sechs Monate, weil die Nicht-LTS Releases verlieren quasi sofort den Support, wenn das nächste raus ist. Das heißt, man kriegt keine Sicherheitsupdates mehr. Das heißt, man muss jedes halbe Jahr zeitnah auf die nächste Version gehen. Dann muss man manchmal auch noch darauf warten, dass die Tools das unterstützen. Gerade alles, was mit Byte Code macht, müssen die Bibliotheken auch ein Update machen. Und je nach Projekt ist mir das ein bisschen zu viel Aufwand und dann warte ich lieber und gehe von LTS zu LTS. Aber in einem Projekt haben wir auch alle Zwischen-Releases mitgenommen. Das hat auch ganz gut funktioniert.

Sven Johann Ich bin tendenziell so, ich muss immer das Neueste nehmen. Das wird dann auch immer gerne gebremst.

Michael Vitz Ich bin in vielen Spring Projekten noch unterwegs, da muss man immer ein bisschen gucken, wann welche Spring Boot Releases in dem Falle meistens die Sprache auch unterstützt. Aber die sind alle schon mittlerweile ziemlich schnell. Früher hat das auch mal ein halbes Jahr lang gedauert, bis so eine Bibliothek rauskam. Sowas wie Byte Buddy oder so hat auch schon mal länger gedauert, aber mittlerweile testen die alle auch schon vorher mit den Preview Milestone Releases und dann geht es eigentlich ziemlich zügig. Auch IntelliJ, früher war es, glaube ich, eher so, dass es mal noch ein bisschen gedauert hat nach dem Release und mittlerweile kann man häufig die Sprach Features auch vorher schon schon anticken. Aber ein bisschen muss man schon koordinieren. Und von LTS zu LTS ist es gefühlt ein bisschen einfacher.

Sven Johann Wenn ich jetzt so eine neue Veränderung habe. Wie würdest du diese Änderungen kategorisieren?

Michael Vitz Die Besonderheit ist vielleicht ein bisschen. Das JDK ist mehr als nur die Sprache Java. Das heißt, je nach Feature kann es sein, dass du Sprachänderungen an der Sprache Java mit drin hast. Du hast im Vorgespräch gesagt, für dich ist ein neues Keyword immer ein guter Indikator. Dem würde ich zustimmen. Oder ein ganz neues Konstrukt, aber primär ist das irgendwelche Keywords. Dann gibt es natürlich Bibliotheksänderungen an der Klassenbibliothek. Die ist nicht sprachspezifisch, aber es wird auch mit dem JDK ausgeliefert. Theoretisch gibt es dann noch Tooling Sachen. Das JDK bringt auch Tools mit einem Compiler und der Ausführung, sowas wie das JavaDoc Tool oder früher um irgendwelche RMI Stubs zu generieren, das gehört auch mit dazu. Dann hat die Laufzeit natürlich noch die Garbage Collectoren, wo sich noch mal was tut. Ich glaube, das sind so die groben vier. Hast du noch was?

Sven Johann Für mich hätte ich gesagt: Neue Bibliotheken, Sprache, Tools, Runtime und dann JDK Enhancement. Wobei ich nicht so genau weiß, ob Bibliothek und JDK Enhancement nicht vielleicht doch das gleiche ist.

Michael Vitz Gefühlt ist in meiner Praxis das auch gar nicht so sehr relevant häufig, was das ist. Es ist ganz nett, um einen Artikel oder einen Talk zu strukturieren. Aber in der täglichen Arbeit ist das nicht so viel. Für IDEs ist das wahrscheinlich auch ein Unterschied. Sprach Features werden die wohl komplizierter einbauen müssen als eine neue Klasse mit Methoden. Das ist immer dasselbe eigentlich.

Sven Johann Und Runtime muss man vermutlich überhaupt nichts machen.

Michael Vitz Höchstens auf Regressions testen, oder wer weiß.

Sven Johann Okay, dann starten wir doch mal mit so ein paar Neuerungen. Für mich war vielleicht die interessanteste Neuerung, vielleicht noch nicht mal vom Gebrauch, aber einfach so die interessanteste Neuerung, die Virtual Threads. Was sind Virtual Threads? Warum brauche ich die?

Michael Vitz Das ist eigentlich lustig, weil wenn man sich mit Kollegen und Kolleginnen unterhält, die mehr Erfahrung und noch länger in dieser Industrie sind als ich, die erinnern sich immer daran, dass Java ganz am Anfang auch schon mal so Green Threads, virtuelle Threads hatte und wir da jetzt wieder hingekommen sind. Der Unterschied ist, die Threads, wie wir sie bisher kannten, im JDK haben quasi eine 1:1 Abbildung auf einen Thread im Betriebssystem. Das heißt, das wird in Betriebssystemen ein eigener Thread gespawnt und da wird quasi dann der Java Code daraus ausgeführt, den ich in meinem Thread ausführe. Und was sie jetzt mit den virtuellen Threads gebaut haben, ist, dass quasi die JVM, die Runtime selber, die jetzt die Threads ausführt und auch scheduled, das heißt die JVM spawned eine gewisse Anzahl an Betriebssystem Threads und macht dann quasi intern so ein Work Sharing Thread Scheduling. Und das hat den Vorteil, für diese nativen Threads muss man immer ein eigenes Deck aufbauen für die Threads. Und ein Teil davon entfällt. Das heißt der Overhead von diesen virtuellen Threads ist viel geringer. Und der JEP. JEP sind immer das, wo man diese größeren Erweiterungen im JDK drüber spezifiziert. Der fertige ist der JEP 444. Der spricht sogar davon, dass es möglich sein müsste, auf normaler Hardware auch eher Richtung Million von diesen virtuellen Threads zu erzeugen, wo man, wenn man das mal mit den nativen Threads versucht hat, viel früher in irgendwelche Wände reinläuft. Und weil die so leichtgewichtig sind, braucht man die zum Beispiel dann auch nicht poolen. Ganz typisch in Java ist: Früher hat man sogar normale Objekte gepoolt, weil die Runtime nicht so schnell war. Mittlerweile sind Threads das letzte, was man eigentlich fast immer poolt. Threads und Datenbankverbindungen. Und die virtuellen Threads muss man aber nicht poolen, weil die so wenig Overhead haben, sondern da erzeugt man wirklich dauerhaft neue.

Sven Johann Wenn ich so an Thread Pools denke, denke ich immer so automatisch an Infrastruktur Software, die sie nutzen. Keine Ahnung, Elasticsearch, Tomcat und so weiter. Vielleicht auch Spring unter der Haube. Kriegen wir davon viel mit oder ist eher so, ich sage mal die typischen Frameworks, die wir nutzen, nutzen jetzt Virtual Threads und wir sind noch mal eine Ebene höher.

Michael Vitz Ich glaube, es kommt, wie so oft, ein bisschen darauf an. Zum einen werden wohl alle Frameworks, die die Möglichkeit bieten zu sagen: Ich nutze ab jetzt virtuelle Threads und dann machen sie es unten drunter. Das hat zum Beispiel den Vorteil, dass man vielleicht in Anwendungen, die gerade sagen würden: Wir brauchen Reactive, um Non-Blocking zu haben. Da könnte man jetzt sagen: Mir reicht der Performance Schub durch virtuelles Threads, weil dadurch, dass die JVM das scheduled, hat die plötzlich auch den Vorteil zu erkennen: ich warte hier auf Netzwerk und dann pausiert sie quasi wirklich den Code und auf dem nativen Thread führt sie dann einen anderen virtuellen Thread auf. Das heißt, ich kriege dieses Non-Blocking zum Teil „geschenkt“. Da könnte man es sehen, dass es sich vielleicht bei einigen Apps nicht lohnt, dann reactive zu machen. Und dieser JEP 444, da sind nur die virtuellen Threads. Der kommt aber noch mit zwei JEPs, die ich in die Nähe zählen würde, nämlich die Scoped Values, das ist 446, das ist eine Preview und die 453, das ist Structured Concurrency. Das ist auch eine Preview. Das ergänzt das Programmiermodell um Dinge, die es einfacher und wieder angenehmer machen, viel mit Threads zu arbeiten. Das heißt, es könnte durchaus sein, dass man jetzt doch eher mal hingeht und auch selbst kurz threadet, wenn das Sinn macht. Structured Concurrency kann grob gesagt, jetzt schaue ich schnell in den Chat rein, bevor ich Mist erzähle. Da ist schon die Idee, man hat quasi so eine Art Barriere, an denen kann man dann eben virtuelle Threads. Man startet die über die Barriere und die Barriere, auf der kann man irgendwann „Join“ sagen und die wartet dann, bis alle fertig sind oder bis einer fertig ist. Das ist ein bisschen wie die Barriere gemacht. Das ist was, was aktuell super schwierig ist. Du spawnst zwei Threads und möchtest quasi auf den ersten warten und der zweite kann dann auch abgebrochen werden. Der, der zuerst zurückkommt und nicht der, den ich als erstes starte. Und das geht mit diesem Structured Concurrency. Ich glaube, die Idee ist, dass man so ein bisschen in so eine Art Async/await Leseart kommt. Das sieht noch ein bisschen komisch aus, finde ich, aber es funktioniert halt.

Sven Johann Jetzt bin ich kein Go-Programmierer. Ich mache auch sehr wenig Kotlin, aber zum Beispiel bei Kotlin gibt es auch Co-Routinen, wo man einfach relativ einfach Concurrency zu machen, ohne dass du großartig Frameworks brauchst. Und es hört sich jetzt für mich so an, als würde das in Java auch in die Richtung laufen.

Michael Vitz Ja genau, es geht ein bisschen in die Richtung. Ich weiß nicht. Es kommt glaube ich extrem drauf an, was für Anwendungen man schreibt. Wir bauen viele so langweilige CRUD Webanwendungen, die aber auch ihre Existenzberechtigungen haben. Da muss man häufig nicht so viel unbedingt parallelisieren. Da sieht man das wahrscheinlich seltener. Aber es gibt bestimmt Anwendungen, wo das auch super Sinn macht.

Sven Johann Ich bin jetzt kein App-Entwickler, ich verirre mich nur selten da rein, aber bei Apps, wenn du deine Remote Calls machst, dann versuchst du es auch asynchron zu machen.

Michael Vitz Genau. Und was ich noch sagen wollte, diese Scoped Values, die sind auch daraus entstanden, weil was ein bisschen problematisch war ist, wenn man in Java mit Threads gearbeitet hat und man hat so Werte, die man in dem Thread und all seinen Callern und so braucht, dann hat man häufig diese ThreadLocals, die man dafür benutzt, wo man quasi einen Wert an einen Thread bindet. Dass es mit den virtuellen Threads dann ein bisschen kollidiert. Es ist jetzt so, dass man die mit Virtual Threads benutzen kann, aber diese Scoped Values soll das mittelfristig ersetzen. Und da sagt man, das ist ein bisschen wie, ich weiß nicht genau, wie dieses Clojure Feature heißt. Aber in Clojure hat man das auch. Da kann man quasi in einer Funktion eine Variable binden und diese globale Variable können alle im Call Tree unten drunter, können oben darauf zugreifen, können die aber nicht ändern. Und genau das machen diese Scoped Values auch. Das heißt, du kannst, eben wie in so einem Art Catch Block einfach eine statische Variable setzen und alle unten drunter können auf diese statische Variable zugreifen und sehen den Wert, aber eben nicht die, die in einem anderen Thread laufen. Das heißt, das ist ein bisschen besser als ThreadLocals und ist vor allen Dingen deutlich Ressourcen sparender und es ist sichergestellt, dass die auch wieder weggeräumt werden, weil das kann einem bei ThreadLocals ganz schnell passieren, dass man irgendwo das clear vergisst. Und da haben sie jetzt auch noch was, was sie dran bauen.

Sven Johann Nur damit ich das mit den Scoped Values richtig verstehe. Ich starte jetzt 10.000 virtuelle Threads, meinetwegen in so einer Schleife. Wo würde ich praktisch diesen local Wert in der Schleife initialisieren?

Michael Vitz Es kommt darauf an. Die Werte können sich auch an Unter-Thread sozusagen. Auch virtuelle Threads bauen wie so ein Baum auf. Und dann kommt es darauf an, wenn man im Moment die virtuellen Threads nur so startet, dann vererben sich diese Scoped Values zum Beispiel nicht. Wenn du aber diese Structured Concurrency benutzst, was wir eben hatten, dann vererben die sich auch auf Sub-Threads. Es kommt darauf an, wie du das startest.

Sven Johann Du hast gesagt, die können auf die die Werte können gelesen werden, aber die kann man auch schreiben.

Michael Vitz Genau das kannst du nicht. Aber es gibt Locals, die kannst du von überall verändern. Und diese Scoped Values werden quasi einmal oben gesetzt und dann genau kannst du unten nur noch lesen. Bzw du kannst den Scoped Value natürlich noch mal neu setzen so ungefähr. Dann sehen den wieder alle untendrunter, aber alle obendrüber sehen noch den anderen Wert. Dann kommt man in so ein Misch-Modell. Da muss man immer schauen, wo das passiert.

Sven Johann Ich muss sagen ThreadLocal schreiben habe ich eigentlich nur früher. Bei Spring Security habe ich das öfter mal gemacht, aber ansonsten eigentlich nie.

Michael Vitz Wo man es häufig implizit benutzt in so Map Diagnostic Kontext vom Logging Framework. Dann macht man es nicht selbst, aber die benutzen diesen Mechanismus meistens auch. Das ist etwas, an jeder Log-Nachricht wird dann dieser Wert angehangen. Die benutzen das eigentlich auch fast immer.

Sven Johann Bei dem Beispiel, wenn ich jetzt MDC, Map Diagnostic Context. Es wird eigentlich nur einmal geschrieben und dann wird ständig gelesen.

Michael Vitz Ja, ja, genau, das ließe sich dann auch so ganz gut abbilden.

Sven Johann Von meiner Seite aus wäre das schon zu Virtual Threads mit meinen Fragen. Hättest du noch irgendwas, wo du denkst, das müssen wir alle noch wissen zu dem Thema?

Michael Vitz Nö, ich kann noch mal rausholen. Ich habe einen sehr guten YouTube Vortrag von einem, der das implementiert hat, irgendwo gesehen. Wenn ich den nochmal finde, können wir ihn in die Shownotes packen.

Sven Johann Nächste Neuerung wären Record Patterns. Was ist das und warum brauchen wir die?

Michael Vitz Record Patterns müssten mit Java 17 schon gekommen sein. Kotlin hatte das leicht vorher, da heißt das Data Classes. Andere Sprachen haben das auch. Das heißt, man definiert für so eine Sprache nur die Properties und man kriegt dann hashCode, equals(), toString() automatisch. Und die Besonderheit bei Java Records ist jetzt noch, dass die Werte dann unveränderlich sind. Das heißt, ich habe quasi nur Getter, aber keine Setter, um sie zu ändern. Außer ich habe Listen, die kann ich mit add und so immer noch manipulieren. Aber das ist das übliche Problem von Java. Und zusätzlich hat Java angefangen Pattern Matching zu implementieren, angefangen mit dem Pattern Matching in instanceof. Das heißt, ich kann jetzt sowas schreiben wie: “if x instanceof String s ”. Und wenn x vorher als Objekt deklariert war, aber es ist ein String, dann habe ich quasi in dem IF Block automatisch an dieses S, was hinten dran kommt, den String gebunden und kann dann da auch alle String Methoden drauf aufrufen. Und die Record Patterns kann ich jetzt genauso auch benutzen. Ich kann dann sagen, wenn x instanceof my record ist und dann ist noch die Besonderheit ich kann die Properties jetzt auch direkt an Variablen binden. Angenommen wir hätten einen Record Point mit den Properties in X und y für die Koordinate, dann kann ich jetzt sagen if x instanceof point x, y und kann jetzt in dem Block von dem If quasi direkt auf x und y zugreifen, weil ich quasi die Properties direkt mit gebunden habe. In Clojure und vielen anderen Sprachen würde man das als Destructuring bezeichnen. Und in die Richtung geht es. Wobei, wo ich es gerade sehe. Man muss sagen: “if x instanceof Point int x int y”. Du musst den Datentypen dann noch mal angeben, aber genau, du kannst danach direkt quasi auf die Properties of Records zugreifen und das funktioniert dann auch noch tiefer geschachtelt. Wenn ich jetzt auch noch einen Caller Point hätte, der wiederum den Point beinhaltet, dann kann ich auch auf zwei Ebenen runtergehen und kann das alles direkt binden.

Sven Johann Und es geht im If. Kann ich auch so ein Switch machen?

Michael Vitz Wenn du nur auf Record Pattern gehst, nicht. Aber das ist so ein größeres Konglomerat von Features. Und mit 21 gibt es nämlich jetzt genau auch Pattern Matching for Switch. Das heißt, ich kann jetzt quasi genau dieses instanceof, was ich im If machen konnte. Ich kann jetzt auch Switch sagen, ich kann sagen: Switch Object und dann kann ich sagen: Case Point inklusive De-Strukturierung. Das geht jetzt auch für Records. Zusätzlich gibt es jetzt auch noch Switch mit einem Null Case. Vorher musste man den Null Check quasi immer vor dem Switch machen. Jetzt kannst du aber auch sagen Case Null, dann hast du den Null Teil ausgedingst und das ist jetzt vielleicht sogar das größte Sprach-Feature, wo ein neues Keyboard dazukommt. Es gibt auch Guard Clauses für das Pattern Matching im Switch. Da kann man jetzt den When benutzen. Du kannst es schreiben: “case String s” und dann, “when s.length >6”, dann würdest du in dieses Case wirklich nur reingehen, wenn es ein String ist und wenn er länger als sechs Zeichen ist. Wo man dann eben darauf aufpassen muss. Es gibt ein paar Dinger, wo der Compiler sich dann weigert, nämlich das Beispiel aus dem JEP ist CharSequence und String. Ein String ist eine CharSequence. Das heißt, wenn du erst einen Case hast “case CharSequence c” und danach noch mal ein „String s“, dann würde der Compiler sich weigern, das zu kompilieren, weil er sagt: Du kommst in dieses “case String s” nie rein, weil ein String immer eine CharSequence ist und es deswegen vorher schon findet. Damit haben sie angefangen. Ich glaube, Ihr Ziel war von Anfang an genau auch das jetzt im Switch machen zu können. Und sie haben dann das so schrittweise rausgezogen und das erste war, das im If zu machen und jetzt ist der Switch nachgekommen. Und was da auch noch ein bisschen zukommt und auch in das Feature gehört, sind dann noch der JEP 443 Unnamed Patterns and Variables. Und zwar haben sie mit irgendeinem JDK damals den Unterstrich verboten als Variablennamen, weil das ging früher in Java und den haben sie jetzt wieder eingeführt und der hat jetzt die Besonderheit, dass der eine semantische Bedeutung hat. Nämlich, der zeigt an, die Variable wird nicht mehr verwendet. Das heißt, man kann danach nicht auf die Variable zugreifen. Und du kannst jetzt auch mehrere Variablen im gleichen Scope haben, die quasi alle Unterstrich heißen deswegen. Und wenn du nämlich was hast, wie du hast einen Coloured Point, der besteht aus einer Colour und einem Point mit XY und du willst nur das Y haben, dann kannst du jetzt in so einem Switch tatsächlich einfach für alle Bestandteile, die du nicht brauchst, einen Unterstrich hinschreiben und musst dir nicht irgendwelche Namen ausdenken. Da kannst du die Unterstriche benutzen, wo die noch häufig sind, machen es in so einem try finally. Zum Beispiel dieser MDC, den wir hatten in Logback bzw SLF4J. Da gibt es ein Closeable, den du bei try-finally benutzen kannst und da musstest du dir bisher immer einen Namen ausdenken. IntelliJ hätte den gerne ignored genannt, damit er weiß, du tust damit nichts im Block und auch da kann man jetzt den Unterstrich benutzen. Bzw es ist nur ein Preview Feature. Es kommt noch, aber die drei Sachen spielen so ein bisschen miteinander zusammen.

Sven Johann Ja, interessant. Ich denke, wenn jetzt Scala Developer zuhören, die denken sich wahrscheinlich. Ich hoffe, ich sage nichts Falsches. "Das hatten wir schon vor 15 Jahren oder so. Als ich angefangen habe, 2009 oder 2008, als ich mich mit Scala beschäftigt habe, dass es gerade rauskam und dann habe ich die ersten Frameworks, die es so gibt, gelesen. Und da habe ich gedacht: Huch, die machen aber ganz schön viel Pattern Matching. Jetzt weiß ich nicht, ob es einfach nur ob Switch Case war. Es ist schon zu lange her.

Michael Vitz Auf jeden Fall. Das können wir auch noch in die Shownotes packen. Es gibt einen InfoQ Artikel von Brian Götz, der Java Language Architect bei Oracle ist, aus dem Sommer letzten Jahres, wo er sagt: Data Oriented Programming in Java. Und genau das sind alles so Features, die es ermöglichen. Dazu kommen noch dieses Sealed Interfaces, die mit 17 glaube ich auch gekommen sind. Wo du sagen kannst: Dieses Interface A darf nur von den Klassen A, B, C implementiert werden. Und dadurch kannst du zum Beispiel, wenn du darauf jetzt ein Pattern Matching machst, weiß der Compiler auch, wenn du alle Fälle behandelt hast, weil der weiß, wenn es vorher ein Interface X war, es gibt nur A, B, C und du behandelst alle drei in Case, dann braucht kein Default mehr, weil dann gibt es alle. Und er sagt, gerade für kleine Programme kann es durchaus Sinn machen, jetzt auch in Java, Data-oriented zu arbeiten. Das heißt, du modelliert deine Daten in Records und packst dann die Logik, die draufbaut woanders hin und benutzt dann eben diese ganzen Fälle wie Pattern Matching, im Switch, im If. Und so weiter und so fort. Das ist ganz spannend, weil das tatsächlich, ich habe mit meinem Kollegen darüber diskutiert. Es ist schon ein größerer Paradigmenwechsel, weil bisher war Java immer so als OP verschrien und du musst Klassen machen. Ganz viele haben noch mit Vererbung gearbeitet und dieses Data-oriented geht jetzt weg. Das ist genau das, was zum Beispiel Clojure sogar macht, nur noch generischer, weil du zum Beispiel nur Maps durch die Gegend reichst und hier hast du typisierte Records wenigstens. Das finde ich ganz spannend. Mal gucken, wo das hingeht.

Sven Johann Okay, dann. Ich würde mal weiterziehen.

Michael Vitz Ja, gerne.

Sven Johann Und zwar nächster Punkt. Du hast am Anfang schon erwähnt, die Runtime Garbage Collection. Da gibt es auch was Neues.

Michael Vitz Genau. Wenn ich es richtig überblicke, gibt es genau dafür eine Änderung. Das JEP 439. Und das ist der ZGC. Jetzt muss ich noch mal nachgucken. Es steht für Zero Garbage Collector. Ich merke mir immer Zero. Nein, einfach nur Z Garbage Collector. Der kriegt jetzt quasi auch diese Generations. Es gibt eigentlich das Feature, was man immer so kannte, wenn man Garbage Collector in Java erklärt hat. Es gibt so eine Junk Generation, wo die Objekte zuerst reinkommen und dann wird die häufiger Garbage collected. Und wenn ein Objekt die irgendwie x mal übersteht, dann wird es in so einer Old Generation kopiert. Das haben sie jetzt für den auch nachgeführt. Der hatte das vorher noch nicht, der kriegt es jetzt auch. Und das führt dazu, dass du hier und da Objekte dir nicht angucken musst bzw. dass Objekte jetzt früher weggeschmissen werden können als vorher.

Sven Johann Ich hatte tatsächlich gedacht, es gibt zwei neue Änderungen. Wir hatten es eben nochmal mit Shenandoa. Vielleicht habe ich das irgendwie auch noch fälschlicherweise in meiner Erinnerung.

Michael Vitz Ich schaue noch mal schnell durch, aber ich sehe tatsächlich nichts. Wenn ich was vergessen habe, müssen uns die Hörer und Hörerinnen verbessern. Nein, ich sehe tatsächlich eigentlich nichts sonst.

Sven Johann Aber wenn du sagst, der ZGC kann das jetzt auch mit den Generationen wird, hat er vorher anders gemacht. Was war der Unterschied?

Michael Vitz Ich bin kein Garbage Collector Experte. Ich meine, der hat tatsächlich vorher einfach nur alle Objekte immer zusammen sich angeguckt. Und Ziel von dem ist, weil ich den JEP gerade auf habe, generell eigentlich, der will, dass die Garbage Collections möglichst konstant und möglichst kurz sind.

Sven Johann Wer will das nicht? Die Wahl eines Garbage Collectors. Wie ist da so dein Vorgehen? Den Default nehmen, oder?

Michael Vitz Ja, ich versuche eigentlich immer so lange wie es geht keine Werte zu setzen, weil dann muss ich mich auch nicht kümmern. Und klar, die Aktion muss dazu passen. Gerade im letzten Projekt hatten wir das. Da haben wir von AWS hier Elastic Container Service benutzt und dann auch immer sehr kleine Instanzen. Da habe ich dann irgendwann ein Artikel gefunden, der schon empfahl, einen anderen Garbage Collector zu benutzen, weil gerade mit nur einer CPU oder so vielleicht der Default nicht immer so perfekt ist. Aber ich versuche eigentlich immer Defaults zu benutzen, bis sich herausstellt, das passt in meinem Setup nicht und dann fange ich an zu optimieren, weil wenn man direkt alle Flags setzt, dann musst du auch bei jedem JDK Update schauen: Funktioniert das noch so? Muss ich doch einen Flag ändern. Ich versuche da irgendwie faul zu sein.

Sven Johann Ich kann mich noch erinnern, im Projekt, der Attila, unser ehemaliger Kollege, also auch Java Champion, lange bei Twitter gewesen und da hatten wir auch bei einem Kunden. Da gab es Performance Probleme und er hat dann einfach seine Garbage Collector Magic spielen lassen. Welche Version? Machen wir das? Machen wir das? Machen wir das? Und irgendwann kam er mit so einer Liste von Parametern raus und da war das Problem gelöst. Und dann habe ich gedacht: Da gibt es noch ein bisschen was für mich zu lernen.

Michael Vitz Ja, ich kann das auch nicht. Ich habe schon x-mal auch Artikel gelesen, wie das alles intern funktioniert und wo man darauf achten kann. Und irgendwie verlässt es mein Kopf dann aber auch schnell mal wieder.

Sven Johann Aber ich frage mich noch, wie ich da tatsächlich auf diese zwei Garbage Kollektoren gekommen bin, aber gut.

Michael Vitz Das ist nicht schlimm.

Sven Johann Bevor ich zu Preview Features komme. Wobei wir eigentlich die, die ich mir notiert habe, schon fast alle hatten. Gibt es noch Änderungen, wo du sagst: Über die sollten wir Bescheid wissen?

Michael Vitz Final ist auf jeden Fall noch die Sequence Collections. Die ist mit 21 nämlich auch final geworden, mit JEP 431. Im Grunde haben sie festgestellt, wir haben eine Java Collection als Ober-Interface, dann List Set und Map. Wobei Map ist keine Collection, aber gehört mit ins Collection Framework. Und es ist aber so, dass eben all diese Möglichkeiten nicht ausdrücken können, wenn man eine Reihenfolge in Listen hat. Eine Liste hat als Reihenfolge, auch wenn man dann darüber iteriert, die Einfüge-Reihenfolge. Ein Set aber nicht, außer es ist ein Sorted Set. Und es gibt auch eine Sorted Liste. Oder es gibt auch noch so was wie Deque. Auf jeden Fall hat das auch wie so eine Stack Semantik und zusätzlich ist es dann bei Sets zum Beispiel auch noch, selbst in so einem sortierten Set total schwierig, rückwärts darüber zu iterieren. Da verknotet man sich regelmäßig. Deswegen haben sie jetzt quasi noch diese Sequence Collections eingeführt, die einfach eine Zwischenschicht sind. Es gibt jetzt Collection, da ist dann Set und Queue drunter und Sequence Collection. Und dann gibt es noch ein Sequence Set, das ist dazwischen und die Liste ist jetzt auch eine Sequence Collection und ähnlich haben sie das dann bei der Map gelöst. Und prinzipiell bedeutet das jetzt, dass ganz viele Methoden, die vorher in diesem Deck Interface waren, nämlich nach oben gewandert sind. Das ist vor allen Dingen at first, at last, get first, get last, remove first, remove last. Und was sie alle neu bekommen haben, ist jetzt noch mal eine Reversed Methode, mit der du dann reversen kannst und was dann wieder ein bisschen blöd ist wegen Unveränderlichkeit. Je nachdem welche Methode du benutzt, kann es wieder Fälle geben, wo das dann irgendwie unsupported Operation Exception oder sowas geworfen wird, weil zum Beispiel in einem normalen Set kannst du jetzt doch nicht at first aufrufen, weil ein normales Set hat keine Einfüge-Reihenfolge und deswegen geht es mit dem ersten nicht. Das ist ein bisschen blöd, aber sie konnten wahrscheinlich auch nicht die komplette Collection Framework einmal umwerfen. Das ist eine Mischung aus rückwärts kompatibel und hilft noch.

Sven Johann Na, da hätte ich jetzt gesagt: Uncle Bob schimpft.

Michael Vitz Irgendwer schimpft bestimmt.

Sven Johann Weil ich würde mich ja darauf verlassen, dass wenn ich dieses Interface benutze, keine UnsupportedOperationException bekomme.

Michael Vitz Ja, allerdings wenn du jetzt schon eine unmodifiable Collection hast, dann wirft add das auch. Und da würde man sich irgendwie auch darauf verlassen, dass add was tut. Wir könnten uns vielleicht darauf einigen, dass es komisch ist und vielleicht auch kaputt, aber es ist konsistent kaputt. Nein, keine Ahnung, aber so in etwa. Ob das jetzt große Auswirkungen hat, weiß ich nicht. Aber es gibt vielleicht ein paar Stellen wo einem das hilft.

Sven Johann Ja, ich habe es tatsächlich in meiner Liste notiert, aber habe es irgendwie überlesen. Aber was mich irgendwie nervt, ist tatsächlich dieses ArrayList.iterator.next um den ersten Item zu bekommen.

Michael Vitz Stimmt, das fällt jetzt.

Sven Johann Und dieses array.get(array.size()-1), um irgendwie an das Letzte zu kommen. Dieser ganze komische Boilerplate fällt weg. Das finde ich eigentlich ganz schön.

Michael Vitz Es ist lustig. Ich habe da überhaupt nicht darüber nachgedacht. Ich habe mir immer gedacht, so viel Anwendungsfälle habe ich dafür nicht. Aber get first benutzt man dann doch häufig. Aber es ist schon so im Muscle Memory mit iterator.next oder get(0) oder so.

Sven Johann Wobei ich sagen muss, mein Hauptfall für get first, da nutze ich tatsächlich eine Queue und da hätte ich es ja, aber nicht immer.

Michael Vitz Und sonst an finalen Features, die du vielleicht nicht auf dem Zettel hast. Es gibt nach JEP 451: Prepare to disallow the dynamic logging of agent. Der ist vielleicht noch relevant, weil man kann in Java so Agents reinhängen. Die werden dann vor allen Dingen ausgeführt, bevor Klassen geladen werden und können Klassen manipulieren. Und dieses Dynamic Loading heißt, ich gebe den beim Starten nicht an, sondern die Bibliothek registriert ihn quasi während der Ausführung. Und das machen zum Beispiel die Mocking Bibliotheken ganz oft und sie wollten das erst mal entfernen. Und dann kam wieder so ein Aufschrei und jetzt haben sie es erst einmal prepared. Ich meine, das heißt, man kriegt dafür dann jetzt eine Warning und dann im nächsten Schritt. Lass mich kurz gucken: Goals prepare. Ich meine, man kriegt jetzt irgendwann eine Warning und dann im nächsten Schritt wollen sie quasi den Default auf ‚nicht erlaubt‘ stellen. Man kann es aber noch umkonfigurieren und in einem dritten Schritt wollen sie es dann wirklich wegwerfen. Das hängt dann glaube ich darauf an, ob die ganzen Mocking Bibliotheken es schaffen einen Ersatz zu finden und bis wann. Wenn man das bricht, wäre es ein bisschen blöd.

Sven Johann Ich hätte zusätzlich noch an die Agents gedacht bei Observerability Tools.

Michael Vitz Aber die gibst du beim Starten eigentlich alle separat an, das geht immer noch. Das Dynamic Loading heißt quasi nur: Irgendwer macht das während das Programm startet und registriert die nach. Das wollen sie nur ausstellen.

Sven Johann Ich frage mich gerade: Will man das unbedingt?

Michael Vitz Ich weiß halt nicht. Ich meine, das macht gerade diese Flags und vielleicht auch ein Bild Tool für Tests. Das ist ein bisschen blöd, aber eigentlich will man das nicht. Ich weiß aber zum Beispiel auch nicht, wenn man jetzt sowas hat wie Proxies für Transaktionen oder sowas. Die machen häufig auch, dass sie irgendwie Byte Code manipulieren. Und da weiß ich auch nicht, ob sich Byte Buddy, da wird eigentlich auch nie explizit beim Starten über ein Flag registriert, sondern ich glaube, die machen das auch dynamisch zur Laufzeit.

Sven Johann Genau, das stimmt.

Michael Vitz Da muss man einen Weg drum rum finden. Wenn man sich diese ganze LTS zu LTS anguckt, dann gibt es in JDK 18 noch ein paar finale Features, nämlich zum Beispiel UTF 8 by Default. Das ist der JEP 400, weil vorher hat das JDK sehr viel sich auf die Zeichen Codierung des Betriebssystems verlassen und da benutzt man überall UTF 8 standardmäßig, außer für Console, also System.in und System.out. Das ist weiter Betriebssystem-abhängig, aber das muss es glaube ich auch sein. Aber bei all diesen Konstruktoren von InputStream, wenn man da jetzt weglässt, dann ist das immer UTF 8 und vorher wäre es unter Windows dann ISO 55891 oder so gewesen. Es könnte Änderungen geben. Dann ist so ein simpler Webserver mit reingekommen in 18, das ist auch final. Das ist das Äquivalent zu python-msimpelhttp Server, wer das schon benutzt hat. Das ist so zum serven von statischen Dateien während Entwicklung ganz brauchbar, aber nicht für Prod geeignet. JEP 413 ist auch noch in 18 gewesen. 18 hatte wirklich viel. Da kann man jetzt Code Snippets in der Java Doku benutzen. Anstatt das man so mit Pre und Code im Java Doc einfach den Code schreibt, kannst du sagen: Hier soll die Region X aus der Datei Y erscheinen. Und wenn man dann noch zum Beispiel dann auf einen Test verweist und der Test irgendwie anders ausgeführt wird, dann weißt du auch, dass dein Code Snippet immer kompiliert und richtig ist. Sonst ist Java nicht kompiliert oder so. Das ist ganz praktisch. Das können wir auch noch in die Shownotes packen. Da gibt es von dem Nikolai Parlog, der ist auch Java Champion, einen ganz guten Artikel, wie man das jetzt auch schon einbauen kann, dass dann diese Sachen getestet werden. Und in 18, aber das sollte nicht relevant sein, da gibt es auch noch Finalization ist jetzt for removal depricated. Schöner deutscher Satz. Finalizer machen glaube ich in Java schon länger eigentlich nichts. Und immer sagen alle: Sollte man nicht benutzen, kann man sich nicht darauf verlassen, dass sie laufen. Und die wollen sie jetzt wirklich entfernen. Und sollte man das jetzt trotzdem benutzt haben, muss man was tun.

Sven Johann Sollte man. Mir völlig unbekannt. Da denke ich immer noch so: Das ist vor über zehn Jahren mit den Finalizern, aber…

Michael Vitz Ich habe mit Java. Ich habe noch ein bisschen was in der Schule mit 1.4 gemacht, aber beruflich ab 1.5 und da war eigentlich immer schon klar: Benutzt keine Finalizer, macht damit nichts. Und ich habe, glaube ich, auch noch nie eingeschrieben. Und das sind jetzt schon eher 15 Jahre sogar.

Sven Johann Wenn sonst nichts mehr aus 18 ist, dann würde ich noch mal auf ein paar Preview Features kommen.

Michael Vitz Soll ich einfach losreden oder möchtest du etwas fragen?

Sven Johann Die meisten Sachen hast du schon erwähnt, wie Unnamed everything, Structured Concurrency, Scoped Values. Ich hätte noch StringTemplates, aber bevor wir zum StringTemplate kommen, vielleicht nochmal ein paar Worte allgemein zu Preview Features sagen. So nach dem Motto: Was ist das und wie sollte man die nutzen?

Michael Vitz Ich hatte am Anfang schon ein bisschen darauf hingewiesen, aber wir sind jetzt auch schon ein bisschen dran. Preview Features sind Features, die sich noch mal verändern können. Wie gesagt, bei Preview Feature ist immer das Versprechen, die sollten sich nur noch ganz leicht ändern. Vielleicht verändert sich dann minimal die Syntax oder es kommt noch eine Kleinigkeit dazu. Die sind aber schon so stabil, dass man sie zumindest ausprobieren kann. Man muss aber sowohl beim Kompilieren als auch beim Ausführen “–enablePreview” angeben. Und bei einem der beiden muss man auch immer noch die Version angeben. Da muss man auch sagen: Ich möchte das mit Java Version 20 starten oder 21 oder so. Er nimmt auch nicht die vom JDK selbst, sondern du musst das noch mal angeben, damit der irgendwas weiß. Das ist einfach die Sicherheit, damit man nicht ausversehen so ein Feature benutzt und sich dann irgendwann beschwert, wenn sich es doch noch mal leicht ändert: Das ist doch ein stabiles Feature. Das ist einfach nur für: Wir haben es euch gesagt. Selbst Schuld. Genau, das ist JEP 11 oder 12. Einer als Incubator, einer als Preview. Weil man das irgendwie alles so aktivieren muss und es nicht so ganz sicher ist und wie ich schon gesagt habe, bei den LTS ich eher auf der konservativen Seite häufig unterwegs bin, benutze ich die eigentlich nur zum Ausprobieren für so Artikel, Vorträge oder sowas und jetzt in meinen Projekten haben wir sowas noch nie benutzt. Aber ich meine, wenn ich mir so angucke, welche dann wie final reingekommen sind, kann man das sicherlich tun, ohne dass man riesige Wartungsaufwände hat. Wenn man denn unbedingt damit jetzt schon anfangen möchte, dann kann man das glaube ich schon tun.

Sven Johann Okay, aus meiner Sicht gäbe es das StringTemplate. Was macht es?

Michael Vitz Lang erwartet. Lustigerweise nicht das, was die meisten denken. Die meisten denken dann erst mal daran. Ich kann jetzt quasi direkt auf eine Variable in meinem String zugreifen, die ich außen deklariert habe. In andere Sprachen geht das auch. Da kann ich dann einfach In meinem String: Dollar x hin und dann wird an der Stelle der Wert von der Variable x ersetzt. Das hatten viele schon bei den Multi-Line-Strings damals gedacht. Die hießen auch immer anders, da haben sie es dann rausgenommen. Aber StringTemplates sind ein bisschen anders und zwar: Man schreibt so ein Prefix hin. Ener der Präfixe, die zum Beispiel mitkommen, ist der str-Präfix. Dann schreibe ich: str. und dann kommen die, lass mich mal gucken, ob der Punkt sein muss. str. und dann kann ich in Quotes einfach meinen String hinschreiben. Und wenn ich diesen str-Präfix benutze, dann kann ich jetzt innerhalb von dem String mit “{Variablenname}” tatsächlich auf die Variable x name - Die wird dann da rein ersetzt. Jetzt ist die Besonderheit aber eben, dass man auch andere Präfixe benutzen kann bzw sie nennen das Template Prozessoren und ich auch meine eigenen schreiben kann. Und was man dann zum Beispiel auch machen kann ist, man kann einen SQL Template Processor schreiben und der würde dann zum Beispiel automatisch diese Variablen, die ich in dem String benutze, auch noch escapen. Das heißt, es ist schon eine Ecke weiter gedacht als nur: Da kann man jetzt eine Variable in einen String schreiben. Das, was den meisten einfällt, ist ein JSON Template Processor, ein SQL Processor, aber theoretisch könnte man sich da wahrscheinlich auch noch andere Dinge für ausdenken, die sinnvoll sind. Wahrscheinlich auch nicht sinnvolle Dinge.

Sven Johann Würdest du das mit dem SQL empfehlen? Ich denke automatisch jetzt an SQL Injection. Ich würde immer PreparedStatements nehmen.

Michael Vitz Aber die könnte dieser, je nachdem wie der Template Processor geschrieben ist, würde der genau das machen. Der würde dann dafür sorgen, dass das irgendwie. Ich habe ihn mir noch nicht 100% angeguckt, wie er intern funktioniert, aber die Idee ist, dass du das machen könntest und der Template Processor wird dann sicherstellen, dass es ein PreparedStatement wird und dann intern irgendwie diese Werte ersetzen. Ich weiß nicht, ob das geht, aber wenn das geht, könnte man das glaube ich machen. Aber gerade für Strings oder auch für JSON oder so ist es. Ich meine, JSON kann man jetzt mit diesem Multi-Line und dem Format auf dem String aufrufen auch schon einigermaßen hinbekommen. Aber mal schauen, was da sonst noch raus kommt. Es kommt noch der FMT Template Processor mit. Der erlaubt einem dann diese String printf Template Dinger.

Sven Johann Gerade wenn du JSON sagst, da kommt es mir jetzt auch so vor, das sieht auf jeden Fall deutlich angenehmer aus als die alte Variante, JSON Dokumente in Java, also jetzt gerade für Testfälle oder so, denke ich mir, ist deutlich angenehmer.

Michael Vitz Sonst an Previews gibt es glaube ich noch drei, die ich relevant finde, die jetzt noch durchkommen, über die wir noch nicht gesprochen haben. Das eine ist Unnamed classes and instant Main Methods. Das ist so ein bisschen wieder für Einsteigerfreundlichkeit, ähnlich wie auch dass man jetzt Java Sourcen direkt ausführen kann. Single files, ohne dass man es kompilieren muss. Das kam irgendwie mit irgendwas vor 17 und zwar kann man jetzt quasi die Klasse weglassen. In dem Einstiegs-File und dann generiert er quasi eine künstliche Klasse, wo er dann die Main Methode rein packt und die main Methode muss man nicht mehr statisch machen und in dem Falle kann man dann sogar die args weglassen, wenn man sie nicht braucht. Und das erlaubt es. Und Menschen, die mit Java anfangen, denen muss man nicht erst mal erklären: Oh, du musst eine Klasse haben und oh, was ist denn static besonderes, sondern im Grunde kannst du jetzt einfach hinschreiben: void main und dann da drin den Code und der Compiler füllt sozusagen den Rest automatisch. Ob das jetzt für Business Anwendungen größere Relevanz findet, weiß ich nicht, aber zum Einstieg ist es super.

Sven Johann Ja, das denke ich auch.

Michael Vitz Und sonst haben wir noch zwei Themen, wo ich mich aber wieder wenig auskenne. Das eine ist die Vector API. Die ist jetzt in seinem sechsten Incubator. Da sieht man, das dauert manchmal ein bisschen. Da geht es darum, dass man Berechnungen direkt auf der GPU machen kann für Vektorenrechnungen. Es ist ein Spezial Feature. Das brauchen wir in unserem CRUD Anwendungen seltenst. Aber da gibt es Anwendungsfälle für. Und dann gibt es noch in der dritten Preview und ich meine, da hätte es auch schon Inkubatoren vor gegeben noch das Foreign Function und Memory API. Da versuchen sie eigentlich hier nicht JDI, sondern.

Sven Johann Java Native Interfaces.

Michael Vitz Ja, JNI, genau. Da versuchen sie durch etwas Benutzerinnen-freundlicheres abzulösen. Vorher musste man ja auch immer noch aus den C-Headern Klassen Stubs generieren. Da tun sie was dafür, dass es besser geht und auch schneller als vorher.

Sven Johann Okay. Ich denke Vector API, das habe ich auch gesehen, da habe ich gesagt: Das machen wir eh nicht. So ungefähr. Aber foreign Interface. Ich weiß jetzt gar nicht mehr so genau, ob mich das jetzt so tangieren würde, aber vor zehn Jahren oder 15 Jahren hätte ich mir einen deutlich leichteren Umgang gewünscht. Das hat mich immer schwer genervt, muss ich sagen.

Michael Vitz Ja, es gibt Sprachen wie Ruby oder so, wo das total üblich ist, dann plötzlich auf C-Bibliotheken auszuweichen. In Go macht man das, glaube ich, hier und da auch. Und ich glaube es gibt Spezialanforderungen. Ich habe es jetzt in meinem täglichen Projektgeschäft auch eher selten, dass ich so denke: Ach, jetzt könntes du eine C-Bibliothek aufrufen. Oh nee, ich muss einen Java Port finden. Das gibt es manchmal, aber wobei vielleicht hätte man dann kein JGit gebraucht um Git irgendwie nach zu implementieren in Java, sondern hätte direkt das Git-C oder was auch immer benutzen können.

Sven Johann Ja, ich hatte früher mal so Client Anwendungen gemacht, so Software Telefone die praktisch auf normalen Rechner laufen. Und da muss man natürlich schon irgendwie mit der Umgebung interagieren. Und da war es voll nervig, aber ich denke Server-Anwendungen würde ich jetzt auch denken.

Michael Vitz Vor allen Dingen, dann kommst du eben genau in das, wo Ruby so verschrieen ist. Wenn du da LibXML oder so brauchst oder Nokogiri und dann musst du kompilieren und den passenden Compiler haben. Und ich glaube es gibt wenig Ruby Themen, für die du mehr Google Treffer findest als dafür, weil du eben plötzlich noch eine ganze Klasse von Fehlern auch mit dazu bekommst. Jetzt haben wir hier M2s im Apple, ARM-Prozessoren, Intel noch irgendwo rumjuckeln. Du machst ganze Fehlerklassen auf. Aber es ist jeden Fall gut zu wissen, dass sie daran noch was dran machen und das da auch weitergeht.

Sven Johann Ich hätte nur noch einen Ausblick. Gibt es irgendwann am Horizont, was wir noch nicht erwähnt haben, wo du mit Spannung darauf wartest?

Michael Vitz Ich habe tatsächlich aktuell nichts. Ich habe auch gerade schon mal die Seite für JDK 22. Wir haben jetzt Anfang September. 21 ist, wenn wir aufnehmen, noch nicht ganz raus, aber bald. Für 22 ist auch noch nichts vorgeschlagen. Was definitiv kommen wird, sind diese ganzen Preview und Incubator Features werden sich weiterentwickeln.

Sven Johann Die hatten wir. Ich hatte jetzt eher gedacht an Sachen, die ganz neu sind.

Michael Vitz Ich habe, glaube ich, nichts groß mitbekommen. Vielleicht habe ich mal irgendwas gelesen, wo ich gedacht habe, das könnte noch mal irgendwann cool werden. Aber ich meine, da wäre vieles auch jetzt schon dabei. Ich sehe es eigentlich eher als positives Zeichen, dass es sich noch so viel tut an der Sprache und man schon noch das Gefühl hat, da wird sehr aktiv weiter entwickelt und keine tote Sprache. Viele machen sich lustig über Java, alte Sprache und so. Und wenn man dann sieht, wie viel sich da in der Sprache noch tut, ist es schon ein Zeichen, dass es eben nicht ganz so tot sein kann.

Sven Johann Ich war auch mal längere Zeit in diesem Camp. Camp Java ist, ich würde nicht mal sagen tot, aber bewegt sich zu langsam, zu viel, Leute sind müde. Vielleicht ist es auch super, aber man ist irgendwie nach x Jahren müde das zu machen. Und ich finde es auch erfrischend, dass einfach jetzt wieder irgendwas kommt. Schon länger, dass da ein bisschen Bewegung drin ist.

Michael Vitz Aber was mir noch eingefallen ist, aber ich bin ehrlich gesagt unsicher, wie da der Gesamtzustand ist. Heißt das jetzt CRaC? Diese Checkpoints. Die Idee ist, man kann die JVM quasi hochfahren, dann so eine Art Checkpoint machen und kann dann beim Starten das nächste Mal wieder aus diesem Checkpoint starten und spart sich irgendwelche Klassenladen, Klasseninitialisierung um eben die Startgeschwindigkeit noch mal zu beschleunigen. Ich glaube, das wird noch irgendwann kommen. Und dann ist auch immer ein bisschen die Frage, ob vielleicht irgendwann das eine oder andere Graal Feature vielleicht ist, ins OpenJDK zurück schafft. Was Ahead of Time und so was angeht. Mal schauen, wie sie das aufteilen, weil das ist ab und zu immer noch so ein bisschen frickelig und man läuft in einen Fehler rein, den man nicht hat, wenn man nicht nativ Ahead of Time kompiliert. Aber gerade der geringere Randverbrauch und die schnellere Startzeit sind schon nette Eigenschaften, die man gerne mitnehmen würde.

Sven Johann Ich habe mich Anfang des Jahres ziemlich intensiv mit Spring Native auseinandergesetzt. Ich sage C-R-A-C. Da war so mein Eindruck, der ist noch ein bisschen wacklig. Aber die Idee ist natürlich. Ich sag mal, so eine Serverless Anwendung mit Java ist eigentlich ein absurder Gedanke, würde ich mal so sagen. Aber mit CRaC, vielleicht sogar in Verbindung mit GraalVM. Es ist auf jeden Fall super interessant. Da bin ich auch mal gespannt.

Michael Vitz Ja, genau. Und ich weiß gar nicht. Sonst fehlt vielleicht auch noch irgendwas für Pattern Matching, was ich jetzt nicht auf dem Schirm habe, weil ich nicht so der Scala Mensch bin oder damit lange mit gearbeitet habe. Das nehme ich mal an, kommt dann auch noch, weil den Weg haben sie jetzt angefangen und gehen sie sehr konsequent Und da sie irgendwann jetzt auch angefangen haben, mal Dinge zu entfernen, könnte es durchaus sein, dass man vielleicht doch noch mal ein neues Collection Framework bekäme oder so. Das halte ich für eher unwahrscheinlich, weil das zu weitreichend ist. Aber jetzt, wo sie auch mal Dinge entfernen, können sie auch ein bisschen aufräumen. Das wird mit Sicherheit noch spannend.

Sven Johann Michael. Vielen, vielen Dank und auch danke an die Zuhörer. Wir sehen uns beim nächsten Mal. Auf jeden Fall: Happy Java 21 Downloading!

Michael Vitz Bis dann. Tschüss.

TAGS

Senior Consultant

Sven Johann ist Senior Consultant bei INNOQ und beschäftigt sich seit vielen Jahren mit der Modernisierung von mittleren und großen Java-Anwendungen. Er ist aktiver Teilnehmer verschiedener Workshops des Software Engineering Institutes (Managing Technical Debt) und des Leibnitz Zentrums für Informatik (Dagstuhl Seminar “Managing Technical Debt”). Zudem ist er Program Chair der GOTO Amsterdam und Show Host von Software Engineering Radio.

Senior Consultant

Michael verfügt über mehr als fünfzehn Jahre Erfahrung in der Entwicklung, Wartung und im Betrieb von Anwendungen auf der JVM. Als Senior Consultant bei INNOQ hilft er Kunden, wartbare und wertschaffende Software zu entwickeln und zu betreiben. Daneben bringt er sich in Open-Source-Projekten ein, schreibt Fachartikel, hält Vorträge und ist seit 2021 Java Champion.