Shownotes & Links
- Ankündigung von schnelleren Releases
- Support und End-Of-Life Tabelle
- JDK 10
- JEP 286 zu Typinferenz
- JEP 317 zum Graal JIT Compiler
- JEP 307 zur parallelen full Garbage Collection vom G1
- JEP 310 zur Speicheroptimierung durch geteilten Klassen
- Generator für API Änderungen zwischen JDK Versionen
- JEP 313 zur Entfernung von javah
- JEP 296 zur JDK Mercurial Konsolidierung
- JEP 322 zum neuen Versionsschema des JDKs
- Projekt Amber
Transkript
Lucas Dohmen: Hallo und herzlich willkommen zu einer neuen Folge des INNOQ Podcasts. Heute werden wir über Java sprechen, und zwar über die neue Version von Java, Java 10. Dafür habe ich mir den Michael eingeladen. Hallo Michael!
Michael Vitz: Hallo Lucas!
Lucas Dohmen: Magst du dich kurz vorstellen?
Michael Vitz: Ich bin Michael, ich bin seit drei Jahren bei INNOQ. Ich bin dort Senior Consultant, was bei uns, wie die meisten wissen, heißt, ich mache die meiste Zeit Entwicklung in Projekten. Ich mache nebenbei Trainings, gebe Talks, schreibe Artikel. Das Umfeld, in dem ich mich primär bewege, ist die JVM.
Lucas Dohmen: Jetzt wo wir es gerade aufnehmen, ist Java 10 noch nicht draußen, aber wenn ihr es hört ist es wahrscheinlich gerade rausgekommen. Wir wollen erstmal über Java Releases sprechen. Wie ist es in der Vergangenheit gewesen, wann ist eine neue Java Version rausgekommen, war das alle zehn Jahre oder was waren da so die Abstände?
Michael Vitz: Wenn man manchen JVM- oder Java Kritikern zuhört, dann könnte man das Gefühl bekommen, dass es nur alle zehn Jahre sind. So schlimm oder so langsam ist es dann doch nicht gewesen. Ich habe nochmal geguckt, zwischen 7, 8 und 8 und 9 lagen einmal zweieinhalb und einmal etwa dreieinhalb Jahre. Das heißt in letzter Zeit waren es mehrere Jahre, so zwei bis drei Jahre in der Regel, dazwischen. Dafür waren das dann auch relativ große Releases, da waren teilweise sehr große Dinge drin. Und dann noch ganz viel kleine Dinge, die mit dabei waren.
Lucas Dohmen: Wie ist das in der Java-Welt mit der Versionsnummer? Ich erinnere mich noch daran, es gab irgendwie mal Java 1.5 und dann auf einmal Java 6, wie ist das abgelaufen?
Michael Vitz: Als ich mit Java angefangen habe, das war mit 1.5 oder sowas, auch da hat man eigentlich immer schon Java 5 gesagt. Sie haben einfach irgendwann mal das Naming geändert, weil dieses 1. hat ihnen glaube ich nicht gefallen. Sie haben intern – wenn man sich die Versionsnummern hat ausgeben lassen, da stand halt auch 1.6 und 1.7 und auch noch 1.8. Das haben sie jetzt mit 9 vor ein paar Monaten geändert. Das heißt es ist das erste Release, wo vorne tatsächlich die 9 steht. Das heißt wenn wir jetzt über Java 10 sprechen, dann ist es einfach 10.
Lucas Dohmen: Nicht 1.10.
Michael Vitz: Nicht 1.10, genau.
Lucas Dohmen: Ok. Und dieser Release-Zyklus wird jetzt beschleunigt, ja?
Michael Vitz: Genau, da hat Oracle – ich habe eben nochmal nachgeguckt – die haben Anfang September – am 21. September 2017 kam Java 9 raus – am 7. September gab es einen Blogpost, wo sie sagen „Wir würden gerne von einem Feature- getriebenen Modell, wo wir ganz viele Features sammeln und dann einen riesen Release bauen, auf ein zeitbasiertes Modell umsteigen“. Und haben dann gesagt, dass sie vorhaben, alle sechs Monate ein neues Java Release herauszubringen.
Lucas Dohmen: Das scheint ja in letzter Zeit moderner geworden zu sein, in der Javascript- Welt ist ja auch auf einen Jahres-Release-Zyklus umgestellt worden. Finde ich auf jeden Fall interessant, dass da mehrere Communities auf diesen Schluss gekommen sind.
Michael Vitz: Genau, also das ist auch in dem Java-Umfeld ein sehr kontroverses Thema gewesen. Weil Java hat eben diesen enterprisey Touch, sage ich mal, und da gibt es ja durchaus auch Firmen, die für Support bezahlen. Und ein Erfolg von Java ist eben auch gewesen, dass sie so lange so stabil geblieben sind. Da hat sich jetzt eben schon ein bisschen eine Angst breit gemacht: Wenn jetzt alle sechs Monate ein Release kommt, muss ich dann alle sechs Monate auch auf die neue Version gehen? Weil das diesem Stabilitätsanspruch ja ein bisschen widerspricht.
Andererseits gibt es eben manchmal so kleine Features, die hinzukommen. Das sind so Einzeiler im JDK, da musste man halt bisher dann drei Jahre drauf warten. Da begrüßt man schon, dass es dann schneller wird. Das ist ein bisschen eine zwiegespaltene Meinung, und ich bin mal gespannt, wie sich das so entwickelt. Ich habe da selber auch noch keine feste Meinung zu. Erstmal finde ich es gut, dass es schneller geworden ist. Man muss mal gucken was das für Auswirkungen auf die Industrie dann letztenendes noch hat, dass das jetzt so schnell geworden ist.
Lucas Dohmen: Ok. Also in manchen Communities, wie zum Beispiel bei Node ist es ja so, dass manche Releases als Longterm Support markiert sind und manche nicht. Ist das jetzt in Java auch so? Früher war vermutlich jede ein Longterm Support?
Michael Vitz: Genau, meines Wissens nach haben sie früher alle – also mindestens bis zum nächsten Release, was ja diese drei Jahre waren und dann häufig auch noch länger – Longterm unterstützt. Wenn man noch länger wollte, dann konnte man auch noch speziellen Support bei Oracle kaufen. Dann hatte man plötzlich, ich weiß nicht, sieben, acht oder zehn Jahre Support. Ich bin mir jetzt nicht ganz sicher wie es aktuell ist, ich weiß, dass sie nicht mehr jedes Release Longterm supporten wollen. Zum Beispiel 9 und 10 sind auf jeden Fall keine Longterm Releases. Das heißt die haben eine Lebensdauer – was den offiziellen Support angeht – im Grunde von diesen sechs Monaten. Man müsste jetzt eigentlich, wenn man Support haben möchte, jeden Versionssprung mitmachen. Meines Wissens nach ist dann geplant, etwa jedes dritte als Longterm Release auszurollen. Das heißt vermutlich wird das nächste JDK, was dann eben 11 sein wird, dann wahrscheinlich länger gepflegt werden. Aber hunderprozentig sicher bin ich mir da nicht.
Lucas Dohmen: Ok. Und wie kennst du das so aus dem Projektalltag? Ist ein Update von einer Java Version ein größeres Unterfangen? Oder ist es relativ einfach, auf eine neue Version zu kommen?
Michael Vitz: Das hängt halt – jetzt kommt die typische Consulting Antwort –
Lucas Dohmen: lacht
Michael Vitz: It depends. Das hängt sehr sehr stark davon ab, welche Größe so eine Anwendung hat und welche Features man benutzt hat. Und manchmal auch ein bisschen davon, was man noch alles mit drumherum benutzt. Also gerade so Projekte, wo man noch einen Application Server unten drunter hat, die sind dann manchmal nur für bestimmte Java Versionen zertifiziert. Die benutzen teilweise auch alle möglichen „dreckigen“ Tricks von der JVM. Da kann so ein Java Release dann schon wehtun. Man muss das ja auch alles testen. Nicht nur weil es kompiliert funktioniert ja alles. Zumindest nicht in Java und in den wenigsten anderen Sprachen ja auch.
Wenn man jetzt so ein mittelgroßes Projekt hat, dann geht so ein hochhieven noch relativ gut in der Regel, aber auch da kann es schonmal so kleinere Probleme, kleinere Hänger geben.
Lucas Dohmen: Wie funktioniert das denn in der Java Welt mit den neuen Features? Gibt es da ein Proposal-System, wie neue Features in die Sprache eingebracht werden oder wie läuft das ab?
Michael Vitz: Ich würde sagen, das ist ein bisschen gemischt. Es gibt einmal JSRs, das sind Java Specification Requests. Die sind für sehr große Dinge gedacht. Es gibt zum Beispiel für jedes JDK einfach ein JSR, der ist sehr groß. Das ist auch ein bisschen kompliziert, ein bisschen bürokratisch. Und um das nochmal ein bisschen zu trennen, gibt es dann zusätzlich noch Java Enhancement Proposals, die halt wirklich nur für sehr sprachnahe Features, für sehr JDK-nahe Features gedacht sind.
Jedes Java Release besteht aus einer Menge von diesen Java Enhancement Proposals – ich sag immer JEPs dazu, ich bin mir nicht sicher, wie man das genau abkürzt. Und zusätzlich besteht so ein JDK eben ja aus ganz vielen APIs. Es gibt dieses Collection API, es gibt zwei oder drei Date APIs, je nachdem wie man es zählen möchte, und so weiter und so fort. Und auch da werden häufig so kleine Dinge hinzugefügt. Meines Wissens nach gibt es dafür weder ein JEP noch ein JSR, sondern das wird so ein bisschen nebenbei mit hochgezählt.
Lucas Dohmen: Also das ist quasi mehr so die Standard-Bibliothek, kann man das so sagen?
Michael Vitz: Genau. Also da erwischst du mich wieder auf dem falschen Fuß, da bin ich mir auch nicht so hunderprozentig sicher. Aber das JDK bringt eben diese Standard- Bibliothek mit. Ich bin mir unsicher wo die wie genau standardisiert ist. Aber zum Beispiel das Collection API sieht halt auch in jeder Implementierung des JDKs gleich aus. Also egal von welchem Hersteller ich das nehme, das verhält sich gleich und die Klassen sehen auf jeden Fall schonmal gleich aus in der Benutzung.
Lucas Dohmen: Ok. Ja dann lass uns doch mal auf die neuen Features von Java 10 eingehen. Ich habe gehört, es wird jetzt ein bisschen Typinferenz eingeführt.
Michael Vitz: Genau, das ist vielleicht für Leute, die mit Java wirklich
entwickeln, also die primär Java Code schreiben, eigentlich das Haupt-Feature
was jetzt mit 10 kommt. Das was sich ändert zur vorherigen Version. Und zwar hat
man eben eingesehen, dass dieses String s =
– und dann kommt in
Anführungszeichen ein String hin – dass man häufig in Java die Typen auf der
linken Seite hinschreiben muss, obwohl man auf einen Blick sieht was der Typ
ist. Und obwohl der Compiler das sowieso ohne Probleme rauskriegen könnte.
Inspiriert von vielen anderen Sprachen, die es gibt, also Groovy oder Kotlin
oder Scala, sind sie jetzt eben hingegangen und erlauben an speziellen Stellen,
nämlich für lokale Variablen – das heißt Variablen, die ich innerhalb einer
Methode deklariere – da kann ich auf der linken Seite einfach var
hinschreiben
und der Compiler kann das dann für ganz viele Fälle interferieren. Es gibt ein
paar Fälle wo er das nicht kann. Dann gibt es halt nach wie vor einen compile
Fehler und dann muss ich den konkreten Typen hinschreiben. Aber für die meisten
Fälle funktioniert es halt einfach, wenn ich auf die linke Seite das richtige
hinschreibe.
Lucas Dohmen: Aber das bedeutet, für Funktionssignaturen und für die Felder einer Klasse, da ändert sich nichts, das bleibt so wie es bisher ist?
Michael Vitz: Genau, das muss so bleiben wie es ist, das geht auch nicht
anders. Ich habe die Tage mal nachgeguckt, es gibt einen Spezialfall. Dadurch,
dass sie als Keyword jetzt var
nutzen, also V A R, wie man das auch in anderen
Sprachen benutzt. var
ist zwar bisher kein Keyword gewesen, aber war schon ein
reserviertes Wort. Das heißt an den Stellen, wo man es jetzt benutzt, durfte man
es vorher sowieso nicht benutzen. Das heißt es bricht auch keinen Code. Der
einzige Spezialfall wäre, wenn man eine Klasse oder ein Interface vorher var
benannt hat, und dann aber auch mit kleinem V, was sowieso sehr unüblich ist.
Also wenn man das gemacht hat, dann kann man an einigen Stellen jetzt ein
Problem bekommen. Weil dann weiß er ja nicht mehr, ob du mit var
dieses
Keyword oder die Klasse oder dieses Interface gemeint hast. Aber da das sehr
unüblich ist, in der Kombination, sollte das eigentlich keinen Code brechen.
Auch alter Code sollte damit noch fuktionieren.
Lucas Dohmen: Kann ich die dann trotzdem irgendwie als final
oder so
deklarieren?
Michael Vitz: Gute Frage, weil dieser Ansatz, Dinge unveränderlich zu
machen, auch in Java immer mehr Einfluss nimmt. In Java 9 gab es zum Beispiel
Factory Methoden für unveränderliche Collections. Das heißt auch, das nimmt so
ein bisschen Einzug in die Java Welt. Ich meine es gab mal eine Umfrage, ob man
dafür auch extra Syntax Keywords gerne hätte. Die war wohl nicht so erfolgreich,
denn sie haben sich dagegen entschieden, sowas wie val
oder let
oder sowas
einzubinden, als Pendant zu var
. Was man aber jederzeit machen kann, man kann
final var
schreiben. val
wäre halt ein bisschen schöner gewesen, weil man
diesem Argument, Java sei so verbose und würde soviel Brimborium drumherum
schreiben, entgehen würde. Aber sonst muss man halt final var
schreiben.
Lucas Dohmen: Ok. Und was ist da so deine Warnehmung, ist das ein Change, den viele Leute gut finden, oder ist das eher was wo die Leute sagen so „Hm, das gefällt mir nicht so gut“?
Michael Vitz: Das was ich bisher wahrgenommen habe, ist, dass es durchaus
positiv aufgenommen wurde. Das sind ja nur die Stellen innerhalb von Methoden.
Das erklärt vielleicht auch, wieso dieses val
und let
nicht ganz so wichtig
ist. Weil die meisten Entwickler doch heutzutage sehr kleine Methoden schreiben,
das heißt der Scope ist sehr begrenzt, das final machen innerhalb des Scopes ist
gar nicht so super wichtig.
An den meisten Stellen kann ich auch als Entwickler, und nicht nur der Compiler, direkt sehen, was das für ein Typ ist. Das heißt da gibt mir der Typ auf der linken Seite gar keinen großen Gewinn. Wo es jetzt ein bisschen versteckter wird, ist wenn ich sage, var x ist gleich der Rückgabewert von einer Methode, die ich auf einem anderen Objekt aufgerufen habe. Weil dann kann ich tatsächlich nicht mehr sehen, was da für ein Typ zurückkommt. Das heißt da muss ich dann entweder die Variable sinnvoll benennen, um das irgendwie mit herauszufinden, oder ich kann mir durchaus vorstellen, dass IDEs einem da einfach etwas anzeigen, obwohl man es gar nicht hingeschrieben hat.
IntelliJ macht das zum Beispiel aktuell auch schon so: Wenn man eine Methode mit
mehreren Parametern aufruft, dann zeigen sie einem die Parameternamen an. Das
sieht dann ein bisschen wie diese benamten Parametern in manchen Sprachen aus,
obwohl ich das gar nicht hingeschrieben habe. Aber wenn man noch Entwickler hat,
die vielleicht lieber einen plain Texteditor benutzen würden – was glaube ich in
Java ein bisschen unüblich ist – dann haben die jetzt ein Problem, zu sehen, was
das an der Stelle für ein Typ ist. Das einzige Gegenargument ist vielleicht,
wenn man den Typen sich links einspart und immer nur drei Zeichen hat, alle
Variablennamen so aligned untereinander stehen, was das Auge so ein bisschen
führt. Und man kann den Platz dann vielleicht tatsächlich nutzen, um die
Variablen vernünftig zu benennen. Dann schreibt man halt nicht c
hin sondern
einfach connection
tatsächlich.
Lucas Dohmen: Ja. Aber ich meine man hat ja trotzdem weiterhin die Option,
den Typen hinzuschreiben, wenn man jetzt bei dem Methodenaufruf das Gefühl hat,
da geht so viel Information verloren. Da könnte man immernoch auf die linke
Seite String bla
hinschreiben.
Michael Vitz: Genau. Das kann ich machen, und wie gesagt, es gibt eben auch
noch Fälle, wo man das sowieso tun muss. Zum Beispiel wenn man eine
Methodenreferenz zuweisen möchte, das ist mit Java 8 neu dazugekommen, dann kann
ich sowas schreiben wie Objekt::Methodennamen
und dann kriege ich etwas
zurück, was diese Methode repräsentiert. Da haben sie halt auch schon so ein
bisschen Compilermagie eingebaut. Und zwar kann man das theoretisch ganz ganz
vielen Typen zuweisen, und das geht zum Beispiel mit var
nicht. Weil er dann
nicht weiß, welcher Typ denn jetzt var
sein soll. An den Stellen muss ich
sowieso nochmal den Typen links hinschreiben. Das heißt in der Realität wird man
sowieso immernoch beide Formen sehen, es wird nicht alles ersetzt werden können.
Lucas Dohmen: Zudem gibt es Änderungen, was die Root-Zertifikate angeht?
Michael Vitz: Oracle hat gleichzeitig mit diesem Umstieg auf den sechsmonatigen Release Plan auch nochmal klargemacht, dass sie jetzt und in Zukunft deutlich mehr tun möchten, um Java noch offener zu gestalten. Das heißt sie übergeben noch eine ganze Menge von dem proprietären Kram, den sie intern bei sich benutzt haben, der Öffentlichkeit. Und ein Teil, den sie jetzt davon umsetzen, ist halt, dass sie die Root-Zertifikate, die im JDK mit ausgeliefert werden, auch einfach open sourcen und dann Open Source übergeben. Ein anderer Plan, den sie zum Beispiel auch noch haben, den sie jetzt demnächst dann auch umsetzen werden dann hoffentlich, ist, dass die JDK Builds unter der GPL laufen. Bisher hatten sie eine sehr exotische Lizenz, mit so einer Classpath-Extension. Und da war zum Beispiel schon unklar, darf ich ein JDK in ein Docker-Image einbacken? Und wenn ich das verteile, dann könnte man das heute so auslegen, als würde man damit gegen die Lizenz verstoßen. Und wenn sie das mal unter einer wirklichen Open Source Lizenz wie der GPL ausliefern, dann ist das zumindest schonmal rechtlich geklärt.
Lucas Dohmen: Ok, das heißt es ist auch vielleicht ein bisschen eine Reaktion darauf, dass viele Leute Docker Container verwenden wollen?
Michael Vitz: Sie haben auch mit Java 9 schon ein bisschen was zu Docker getan, also dass man zum Beispiel erkennen kann, wieviel Memory der Docker Container einem zur Verfügung stellt. Vor 9 war das so, dass die JVM trotzdem den Speicher vom Host sah. Auch Oracle geht Richtung Containerisierung. Das ist einfach ein Trend in der IT, um den kommen wir nicht mehr drumherum. Der hat sich etabliert, denke ich.
Lucas Dohmen: Auch an der Virtual Machine hat sich dann nochmal was verändert? Es gibt einen neuen JIT, richtig? Magst du erstmal kurz erklären was ein JIT ist?
Michael Vitz: Um nochmal kurz einen Schwenk zurück zu machen: Im Grunde sind das die Hauptfeatures, die man als Entwickler so mitbekommt, und der Rest, das geht dann eher Richtung Betrieb und der virtuellen Maschine selber, wie du gerade schon gesagt hattest. JIT ist einfach ein Just in Time Compiler. Das heißt, aus meinem Java Code wird halt dieser Byte Code, aber während der läuft, erkennt die JVM anhand aller möglichen Dinge einfach, dass sie da noch etwas zum Beispiel nach C übersetzen könnte und das kompiliert sie dann während das Programm läuft, und kann dadurch halt noch schneller werden. Sie lernt dann zum Beispiel auch Dinge, und kann so ein Kompilat auch wieder verwerfen, wenn sie gemerkt hat, dass eine Annahme, auf die sie sich vorher verlassen hat, nicht mehr gilt. Das ist halt sehr magisch und ich glaube so der Königsthron des Compilerbauens. Also wenn ich das könnte, fände ich das bestimmt ganz toll, dass ich das könnte.
Lucas Dohmen: lacht Alles klar. Und da, das gabs ja schon, das haben sie jetzt nochmal verbessert?
Michael Vitz: Nicht verbessert, aber bisher ist der Just in Time Compiler in C geschrieben, und das schreckt vielleicht nochmal Leute ab, sich damit zu beschäftigen. So ein Just in Time Compiler ist mit Sicherheit nie einfach, aber den in C zu haben, ist nochmal ein bisschen schwerer. Sie arbeiten jetzt schon längere Zeit an Graal, das ist ein Just in Time Compiler, der in Java geschrieben wurde. Und der ist jetzt experimentell eingebaut. Wenn man sich dann den JEP dazu anguckt – da steht explizit drin, es ist experimentell, und es ist in diesem Schritt kein Ziel gewesen, genau so schnell oder schneller wie die vorhandenen zu werden. Das heißt man wird den mit Sicherheit im normalen Betrieb noch nicht einsetzen möchten. Aber man kann damit mal rumprobieren, gucken. Und es hilft denen halt, den irgendwann mal als default zu etablieren und vorher schon zu wissen, das funktioniert. Es ist ja eine sehr große Änderung, wenn man den einfach mal austauscht.
Lucas Dohmen: Also wenn ich jetzt den Graal benutzen möchte, dann gibt es sicherlich eine Flag, das ich das anschalten kann, wie funktioniert das?
Michael Vitz: Zur Compilezeit musst du nichts übergeben, weil der JIT, wie wir schon ein paar Mal gesagt haben, ja erst zur Laufzeit läuft. Und da gibt es einfach ein Flag, was der geneigte Hörer dann den Shownotes entnehmen kann. Wir werden natürlich alle JEPs verlinken, und da steht dann auch standardisiert drin, welches Flag man zur Laufzeit setzen muss, damit der Graal JIT aktiviert wird.
Lucas Dohmen: Ok. Cool. Und es gibt auch Changes an dem Garbage Collector?
Michael Vitz: Genau. Ich bin zwar auch kein Experte was die Garbage Collectoren angeht, aber da geht es primär auch nochmal darum, wie der Sourcecode intern strukturiert ist. Es gibt ein JEP dazu, dass sie die bisher vorhandenen Garbage Collecoren – es gibt mehrere, es gibt noch den etwas älteren Concurrent Mark Sweep und es gibt den mit Java 8 hinzugekommen und neu als default angeschalteten G1 Garbage Collector – es ist wohl so, dass da nicht so ganz getrennt wird zwischen den Garbage Collectoren. Teilweise teilen sie sich den Sourcecode noch, er liegt ein bisschen verstreut. Da geht es einfach darum, eine klare Grenze dazwischen zu ziehen, weil es auch die Entwicklung eines neuen Garbage Collectors einfacher macht, wenn der vollkommen isoliert von den vorhanden ist.
Lucas Dohmen: Und ist der auch in Java geschrieben?
Michael Vitz: Meines Wissens nach sind die Garbage Collectoren bisher auch alle in C geschrieben, weil das einfach an der Stelle dann schnell und performanter ist, als wenn man das in Java machen würde.
Lucas Dohmen: Das ist ja auch irgendwie so eine Besonderheit der JVM, dass man da seine Garbage Collectoren auswählen kann. Also, ich kann mir aussuchen, welchen von der Auswahl der Garbage Collectoren ich anschalten möchte, richtig?.
Michael Vitz: Genau, du kannst zwischen verschiedenen Garbage Collectoren wählen, und du kannst dann auch nochmal jeden tweaken. Du kannst je nachdem halt super viel machen. Du kannst sagen: Wann soll er laufen, wie soll er sich verhalten. Was zum Beispiel auch neu hinzugekommen ist: Der G1 kann jetzt, wenn eine volle Garbage Collection läuft, die auch parallel machen. In der Regel ist es so, dass die JVM, wenn sie merkt, mein Speicher wird knapp, dann schmeißt sie so eine kleine Garbage Collection an, die möglichst schnell möglichst viel Speicher einfach freigeben soll, damit man weiterarbeiten kann. Deren Ziel ist es aber nicht, optimal zu sein, sondern einfach nur möglichst schnell, damit man weiterarbeiten kann.
Irgendwann kommt ja die JVM dann trotzdem an einen Punkt, wo sie mal sauber aufräumen müsste. Dann gibt es eine full Garbage Collection, die in der Regel heißt, dass sie das Programm komplett stoppt. Zumindest für einen gewissen Zeitraum, weil sich an der Stelle für einen Moment nichts ändern darf. Bisher war das bei dem G1 so, dass er sozusagen vorher parallel sich markiert hat, was er denn jetzt wegräumen möchte. Aber zum wirklichen Wegräumen hat er gestoppt, da lief ein Prozess. Das haben sie jetzt geschafft, auch noch zu parallelisieren. Das heißt, im Idealfall läuft das schneller, weil es parallel ist, und dann ist dieses „Stop the World“-Intervall halt deutlich kürzer.
Lucas Dohmen: Das heißt also, da kann man damit rechnen, dass die Applikation nochmal ein bisschen mehr responsive ist. Auch in den Fällen, wo dann die Garbage Collection anspringt.
Michael Vitz: Das ist zumindest meine Hoffnung. Ich hab auch schon Stimmen gelesen, die gesagt haben, Java 10 wird wahrscheinlich die wenigsten Java Anwendungen deutlich beschleunigen oder deutlich schneller machen. Das hilft aber bestimmt der einen oder anderen größeren Anwendung insbesondere an der Stelle weniger diese Stopp- Zyklen zu haben.
Lucas Dohmen: Ok. Eine langzeitige Kritik an der JVM ist ja immer, dass sie relativ viel Speicher benötigt, und dass sie relativ lange braucht zum Starten. Daran haben sie wohl auch ein bisschen was verbessert?
Michael Vitz: Es gibt einen JEP, das ist der 310er, der behandelt, dass man Klassen einfach teilen kann. Das heißt eine Möglichkeit, die sie damit eröffnen – meines Wissens nach gibt es das schon länger, aber es war nie so offiziell und mit einem Standard abgesegnet – theoretisch können jetzt zwei JVM Prozesse, die auf derselben Maschine laufen, die können sich gewisse geladene Klassen teilen. Das würde halt Memory einsparen, zur Laufzeit. Der Fall ist vielleicht in so einer containerisierten Welt, wo eben in jedem Container eine eigene JVM läuft, nicht ganz so wichtig. Aber über diesen JEP ist auch standardisiert worden, dass man die Klassen in ein Archiv verschieben kann. Das kann man dann mit zur Startzeit laden, und dann kann man sozusagen dieses Archiv direkt aufs Memory mappen. Das heißt er lädt die Klassen dann gar nicht mehr, sondern lädt das direkt in den Memory durch, was eben durchaus Startzeit- Verbesserungen ermöglichen kann. Ob das jetzt eine Welt ist, das weiß ich nicht, das muss man mal ausprobieren, ich glaube nicht. Aber wenn man jetzt von 20 auf 15 oder 16, 17 Sekunden runterkommt, ist das ja nunmal auch schon ein Gewinn.
Lucas Dohmen: Ja, auf jeden Fall. Du hattest am Anfang erwähnt, dass es neben diesen JEPs dann immer auch Änderungen an dieser Standard-Bibliothek, oder wie man das auch nennen möchte, gibt. Ist da etwas besonderes dabei, was dich freut?
Michael Vitz: Ja. Von 8 auf 9 gab es deutlich spannendere Dinge, aber von 9
auf 10 sind jetzt auch nochmal ein paar Dinge dabei, die sich geändert haben. Um
das rauszufinden gibt es ein ganz cooles Tool auf Github. Von jemandem, dessen
Namen mir gerade nicht einfällt, aber das verlinken wir auch in den Shownotes.
Der erzeugt so ein HTML-Diff zwischen zwei Java Versionen, wo man dann eben sich
so das API angucken kann. Als ich eben drübergescrollt bin, waren die beiden
interessantesten Dinge, die ich gefunden habe: Einmal, wenn man so mit Java
Streams, mit Collections und Streams arbeitet, dann ist der letzte Schritt
häufig, dass man ein collect
macht. Um sozusagen den Stream wieder in eine
Collection zu überführen. Bisher hatte man dann halt so etwas wie
Collectors.toSet()
oder Collectors.toList()
, die aber dann immer
veränderliche Datenstrukturen zurückgaben. Und mit 10 haben sie jetzt
tatsächlich auch nochmal toUnmodifiableList()
und ein paar andere Datentypen
unterstützt.
Die zweite kleine Änderung, die vielleicht noch interessant ist, ist was
Optional
angeht. Optional
ist dieser Rückgabetyp, den man anstelle von
null
an manchen Stellen verwenden kann, um klarzumachen „Hier kann auch mal
nichts zurückkommen“. Da haben sie noch eine weitere Methode hinzugefügt, um im
Falle, wo man nichts zurückgegeben hat, eine Exception zu werfen. Also da ist
eine Methode einfach nochmal überladen worden. Und es gibt Stellen, wo auch das
helfen kann. Das sind so kleine Änderungen, die man dann aber wirklich im Alltag
manchmal merkt, die einem helfen können. Obwohl die nicht so groß aufgehangen
werden.
Lucas Dohmen: Ok. Haben wir damit das abgearbeitet, was in Java 10 rauskommen wird? Oder fehlt da noch irgendwas?
Michael Vitz: Im Grunde ist es das. Was vielleicht manche noch wissen müssen, ist, es gab so ein javah Tool. Damit konnte man, wenn man aus Java auf C-Code zugreifen wollte, Header Files generieren. Das haben sie jetzt mit Java 10 gestrichen. Das gibt es nicht mehr, weil sie mit Java 9 einen neuen Mechanismus eingeführt haben, der das obsolet gemacht hat. Das heißt das fehlt.
Dann haben sie noch – das JDK bestand vorher aus fünf Mercurial Repositories, die man erst zusammenklonen musste. Das haben sie jetzt in eins überführt, das merkt man als Benutzer aber auch nicht. Und dann haben sie nochmal leichte Änderungen an der Versionsnummer gemacht. Mit 9 haben sie eingeführt, dass sie Major.Minor.Patch haben. Jetzt mit 10 haben sie das nochmal ein bisschen geändert, um auf diesen sechsmonatigen Release Zyklus besser angepasst zu sein. Zwischendurch war auch mal überlegt, ob das überhaupt 10 heißt oder ob das nicht 18.4 oder 18.3 heißen sollte, weil es im März oder April 2018 erscheint. Also so ähnlich wie Ubuntu das macht. Da hat sich die Community dann sehr stark gewehrt, dann sind sie halt bei diesem 10, 11, zwölfer Modell geblieben, haben nur das Versionierungsschema nochmal minimal angepasst.
Lucas Dohmen: Ok. Wenn wir jetzt über Java 10 hinausschauen, dann wird ja jetzt alle sechs Monate ein neuer Release kommen. Was für Dinge findest du da schon cool, die jetzt in nächster Zeit rauskommen werden?
Michael Vitz: Genau, das ist ganz spannend. Wir hatten ja diese lokale
Typinferenz. Das alles ist in dem Projekt Amber – Amber mit A, nicht mit E wie
das Javascript- Framework – entwickelt worden. Die probieren halt neue Dinge
aus, und wenn die merken, es funktioniert etwas, dann wird daraus ein JEP, der
dann in ein JDK einfließt. Und woran die eben neben dieser Typinferenz
gearbeitet haben, ist vor allen Dingen so etwas wie Pattern Matching einzubauen.
Weil das alle modernen Sprachen haben, und an manchen Stellen macht es den Code
einfach besser lesbar. Da arbeiten sie dran. Das haben die sogar schon vor
eineinhalb Jahren gesagt, dass sie ausprobieren, wie das denn geht, und wie das
rückwärtskompatibel geht. Das wird mit Sicherheit kommen. Neben dem Pattern
Matching, da kann man so etwas machen wie – bisher musste man sagen if(x
instanceof String)
und dann musste man in der nächsten Zeile sagen String s =
und dann x auf den String casten – das kann einem dann zum Beispiel der
Compiler abnehmen. Der weiß dann einfach, dass x dadrunter ein String ist, und
dann kann man direkt auf dem x String- Methoden aufrufen, ohne dass man selber
casten muss.
Und was sie dann eben noch gemerkt haben, ist, man will auch so etwas machen wie
switch (x)
und dann sagen case String s
. Also wenn x ein String ist, dann
mache da etwas. Und dann haben sie gemerkt, dass man sowieso mit switch
noch
viel viel mehr Dinge tun könnte, und haben das nochmal aufgesplittet. Das heißt
meine Hoffnung ist, dass vor dem Pattern Matching dieses verbesserte switch
kommen wird.
Eine Sache, die sie erlauben wollen, ist, dass switch sozusagen einen
Rückgabewert bekommt, dass man es als Ausdruck verwenden kann. Da kann man halt
sowas sagen wie int i = switch (x)
und dann kann man in jedem case einfach i
returnen und dann hat man am Schluss den Wert zugewiesen. Sonst musste man
bisher immer int i
schreiben und dann zuweisen, und dass sah ein bisschen
hässlich aus. Die zweite Verbesserung ist, dass endlich auch switch mit null
umgehen kann. Wenn man vorher sagte switch (x)
, und x war null
, dann kriegte
man halt eine NullPointerException. Und was sie dann hoffentlich auch erlauben
wollen, weil es auch geht, ist einfach zu sagen, case null
und dann kann man
auf denn null- Fall reagieren.
Und was dann in dem Projekt Amber noch mit dabei ist, ist einmal die
Dekonstruktion. Das heißt ich kann so etwas schreiben wie if(x match ...)
und
dann kann ich einen Klassennamen schreiben, wie Point
, dann schreibe ich in
Klammern dahinter (int x, int y)
. Wenn mein x eine Instanz von Point ist, dann
habe ich direkt an x und y die beiden Felder, die man im Konstruktor an den
Stellen übergeben würde, gebunden. Das heißt nochmal so eine fancy
Dekonstruktions-Bindings-Syntax.
Was sie noch beschreiben – das ist ein sehr großes Projekt, das wird nicht in
einem JDK kommen, sondern so schubweise – sind halt Data Classes. In Scala sind
das meines Wissens nach die Case Classes. Und auch Kotlin hat dafür eine Syntax,
um das zu machen. Im Grunde schreibt man dann einfach nur noch hin DataClass
Point(int x, int y)
und der Compiler generiert einem dann unter der Haube eine
finale Klasse daraus, die die beiden Felder x und y hat. Was er dann noch tut
ist halt getX()
und getY()
zu konstruieren. Und equals()
, hashCode()
und toString()
zu überschreiben für einen, die dann halt wertbasiert die
Gleichheit garantieren. Deswegen ist es auch alles unveränderlich, weil man
damit Wertobjekte, wie sie vielleicht im Domain Driven Design definiert werden,
abbilden kann. Das heißt die sind dann unveränderlich. Dafür kann man diese sehr
kompakte Syntax schreiben.
Lucas Dohmen: Super. Das klingt ja so als würden sich doch irgendwie viele Sachen bewegen. Glaubst du das liegt vielleicht auch ein bisschen an so Projekten wie Kotlin, die ja so eine „gefixte“ Version von Java machen wollten? Weil sie Schmerzpunkte hatten, wo sie gerne etwas kürzer schreiben wollten. Meinst du das ist der Einfluss davon?
Michael Vitz: Also ich bin fest davon überzeugt, dass mit dem Beginn dieser
ganzen anderen Sprachen, die auf der JVM laufen, das eben auch Einfluss auf die
Entwicklung von Java genommen hat. Man sieht das auch schon an diesen Streams.
Und dann hat man plötzlich map()
und filter()
und reduce()
. Man kann
plötzlich Methodenreferenzen durch die Welt reichen, weil das im Funktionalen
sehr im Kommen war. Und auch diese Unveränderlichkeit.
All das hat einen klaren Einfluss auf Java, und da entwickeln sie sich auch
weiter. Ich glaube nicht mal mehr, weil sie so viel Angst haben, dass die Leute
weglaufen, sondern einfach, weil sie auch gemerkt haben „Das ist jetzt
akzeptiert, das machen wir“. Wenn man den Java Core Menschen zuhört, zum
Beispiel Brian Goetz, dann sagt der ganz klar „Ja, Java ist halt etwas
langsamer, weil wir eben auch dann erst bewährte Konzepte einsetzen“. Das heißt
sie haben manchmal auch den Vorteil, dass sie abwarten, was setzt sich denn in
anderen Sprachen durch. Und das danach erst bei sich einsetzen. Dann wirkt es
halt manchmal etwas langsamer, dafür legen sie super viel Wert auf
Rückwärtskompatibilität. Selbst wenn jetzt switch
ein Ausdruck wird, dann wird
mein alter Code, der damit noch nicht umgehen kann, immernoch funktionieren.
Es gibt auch Sprachen, die werfen an der Stelle Dinge über den Haufen. Das macht Java einfach nicht, und das ist auch einer der Erfolgsfaktoren. Man kann sich darauf verlassen und es sichert einfach das Investment von Firmen deutlich ab. Aber sie müssen eben mit den ganzen neuen Sprachen schon ein bisschen was tun, um nicht vielleicht gar nicht mehr benutzt zu werden. Diese Mischung führt einfach zu diesen ganzen Veränderungen.
Lucas Dohmen: Super. Ja, vielen Dank, dass du uns das so ausführlich erklärt hast.
Michael Vitz: Danke, dass ich da sein durfte!
Lucas Dohmen: Dann würde ich sagen, an die Hörer, bis zum nächsten Mal!