Happy Birthday, Java!

25 Jahre Java: Eine Programmiersprache zelebriert ihr Jubiläum

Wolfgang Weigend

© Software & Support Media GmbH / Bianca Röder

Java wird 25, ein Vierteljahrhundert Java. Für Wolfgang Weigend, Master Principal Solution Engineer bei der Oracle Global Services Germany GmbH, ein guter Grund, die heute tief in allen IT-Systemen verwurzelte Programmiersprache zu feiern und einen Blick auf ihre vergangene, zukünftige und gegenwärtige Entwicklung zu werfen.

Es war der 23. Mai 1995, ein Dienstag, als Sun Microsystems, Inc. das erste Java Release unter dem Namen „Java Development Kit 1.0“ (oder auch JDK 1.0) veröffentlichte. Die Programmiersprache Java umfasste schon damals die Software-Entwicklungsumgebung (JDK) zur Erstellung von Java-Anwendungen und eine Java Virtual Machine (JVM) zur Ausführung von Java-Programmen auf beliebigen Geräten und Betriebssystemen. Damit war der Slogan „Write once, run anywhere“ geboren. Die Java Standard Edition (Java SE) besteht bis heute aus der Kombination von JDK und JVM und wird allgemein als “Java” bezeichnet.

Plattformunabhängigkeit und Abwärtskompatibilität

Was mit den bekannten Fähigkeiten einer objektorientierten Programmiersprache begann, wurde durch sukzessives Hinzufügen von neuen Merkmalen zu den Java APIs mit ihren Klassenbibliotheken kontinuierlich erweitert. Java läuft nach dem Ansatz einer interpretierten Sprache: Der Java Compiler erzeugt den Bytecode für die JVM, der Java Interpreter führt den kompilierten Bytecode einer Java-Anwendung aus. Durch die Plattformunabhängigkeit vom Java-Bytecode lassen sich die entsprechenden Anwendungen auf jedem unterstützten Betriebssystem ausführen, für das eine JVM existiert.

Förderlich für die Verbreitung der verteilten Programmiersprache Java war die damalige heterogene Systemlandschaft und die aufkommende Vernetzung. Um tatsächlich portable Anwendungen zu schreiben, wurden sämtliche API-Plattformabhängigkeiten vermieden, indem 100 Prozent reine Java-Programme entwickelt wurden. Diese bekamen durch die „Pure Java“-Programmzertifizierung durch Sun ihre Portabilität dann auch offiziell bescheinigt. Die ständige Erneuerung der Java APIs mit gleichzeitig gewährleisteter Abwärtskompatibilität ermöglichte Java die direkte Ausführung von älteren, nicht kompilierten Programmen auf einer aktuellen Java-Version. Erst unter Verwendung neuer Sprach-Features wurde der Compiler angeworfen und existierende Programme schrittweise modernisiert.

Happy 25th Birthday, Java! Unsere Artikel- und Interviewreihe zum Jubiläum

Java wird 25, ein Vierteljahrhundert Java. Das ist definitiv ein Grund zu feiern! Aus diesem Grund haben wir mit einer Reihe von Java-Expertinnen und -Experten gesprochen, Interviews geführt und natürlich Glückwünsche zum Jubiläum gesammelt. In unserer Interviewreihe plaudern unsere Java-Champions über ihre Lieblingsfeatures und erzählen Geschichten über die Programmiersprache, die sie geprägt haben. Zudem blicken einige Java-Profis in Artikeln zum Thema auf ihre gemeinsame Zeit mit Java zurück.

Feiern Sie mit uns den 25. Geburtstag von Java!

Java feiert 25 Jahre – Unsere Interview-Reihe zum Geburtstag

 

>> Noch nicht genug Java? Dann schleunigst für die JAX 2020 anmelden! <<

Auf zu neuen Ufern

Die 25-jährige Reise in eine moderne Java-Anwendungslandschaft war geprägt von intensiven Code-Reviews mit einer gründlichen Evaluierung neuer Features für die jeweiligen Hauptversionen. Einige Meilensteine sind mir dabei in besonderer Erinnerung geblieben.

Funktionale Programmierung mit Lambdas

Mit der Einführung von Lambda-Ausdrücken und dem Stream API im März 2014 erfuhr die Java SE in Version 8 die größte Sprachänderung seit der Einführung von Generics in Java SE 1.5. Damit wurde die funktionale Programmierung auch für Java ermöglicht und dabei maximale Abwärtskompatibilität sichergestellt. Die Lambda-Ausdrücke wurden in die Sprachsyntax aufgenommen und mittels invokedynamic-Bytecode implementiert. Lambdas veränderten die Art und Weise, wie Java-Programme geschrieben werden und es flossen so ab Java SE 8 endlich funktionale Konzepte in die Sprache ein.

Aufbau von Lambdas

Im Grunde repräsentiert ein Lambda eine Funktion. Ein Lambda-Ausdruck ist eine Instanz eines funktionalen Interfaces. Der Lambda-Ausdruck enthält jedoch keine Informationen darüber, welches funktionale Interface er implementiert. Diese Informationen werden aus dem verwendeten Kontext abgeleitet. Im Unterschied zu einer Methode gleicht eine Funktion einer Berechnung, die eine Anzahl von Parametern zugeführt bekommt und dann einen Wert zurückliefert. Damit ist es eher ein mathematisches Konzept.

Wichtig ist zu wissen, dass Funktionen auch Nebeneffekte haben können, deshalb war es bei der Implementierung von Lambda-Ausdrücken in Java 8 besonders wichtig, diese zu vermeiden. Dabei geht es hauptsächlich darum, die Eingangsparameter zu berechnen und dann ein Ergebnis zurückzugeben.

Vor der Veröffentlichung von Java 8, musste jede Berechnung in einer Methode enthalten sein, die wiederum in einer Klasse enthalten war. Der Programmcode war Bestandteil einer Methode. Diese Methode hat einen Namen, der Methodenaufruf erfolgte über die Namensreferenz und möglicherweise auch über die Klasse mit der enthaltenen Methode oder eine Instanz, die mit der Klasse und der darin enthaltenen Methode verbunden war. Somit konnte man Funktionen bisher nur mittels Methoden in Java implementieren.

Durch die Lambdas bekommt man seit Java 8 nun Funktionen, die nicht notwendigerweise fest mit einem Methodennamen innerhalb einer benannten Klasse verbunden sind. Wird die Funktion aus dem strikten Korsett von Methodenname und Klasse herausgelöst, kann man eine Lambda-Funktion benutzen und sie als Parameter weiterreichen, als Rückgabewert zurückgeben oder in eine Datenstruktur einbinden. Damit besteht jetzt auch in Java die Möglichkeit, Funktionen zu benutzen, wie es bereits in anderen Programmiersprachen der Fall ist. Funktionen können ineinander verschachtelt sein und Funktionen zurückliefern.

Lambda Tour

Zur Einführung des Features bot die „Java Magazin Lambda Tour“ die Gelegenheit, die Lambda-Ausdrücke in der Praxis kennenzulernen und das Programmieren damit zu vertiefen. Die Lambda Tour, inklusive Hackathons, fand in den Städten Duisburg, Hamburg, Frankfurt und München im Herbst 2013 statt. Die Teilnehmer lösten mit den neuen Mitteln kleinere Programmieraufgaben und gewannen dabei erste Erfahrungen mit Lambdas und dem Stream API.

Projekt Jigsaw modularisiert Java

Das im September 2017 erschienene JDK 9 enthielt den modularen Aufbau der Java SE mit dem Java-Plattform-Modulsystem (JPMS). Damit wurde es möglich, die technische Paketierung von ausgewählter Java-Funktionalität selbst zu bestimmen. Das Projekt Jigsaw hatte die primäre Aufgabe, das Design und die Implementierung eines Standardmodulsystems für die Java-Plattform und für das JDK 9 bereitzustellen. Es sollte einfach nutzbar sein, damit die Entwickler das Modulsystem zum Aufbau und zur Wartung von Bibliotheken sowie für große skalierbare Java-SE-Anwendungen verwenden können.

Das Einsatzgebiet von Java SE 9 umfasst die Zielplattformen von Embedded-Geräten, Laptops, Desktops und Servern. Mit dem Werkzeug jdeps, wird die Modulabhängigkeitsanalyse im JDK durchgeführt und es können jeweils die Module aufgelistet werden, die eine besondere Abhängigkeit zum Klassenpfad besitzen. Das Werkzeug jlink erzeugt eine individuelle Java Runtime, die inklusive der erstellten Java-Anwendung wesentlich kleiner ist als eine vollständige Java-Laufzeitumgebung (JRE) oder ein komplettes JDK. Die Modularisierung der Java-SE-Plattform im JDK 9 bringt viele Vorteile, wohlgemerkt waren auch einige größere Änderungen damit verbunden: Existierender Anwendungs-Code, der nur offizielle Java-SE-Plattform-APIs mit den unterstützten JDK-spezifischen APIs verwendet, sollte dabei auch weiterhin ohne Änderungen ablauffähig sein. Nach wie vor war und ist die Abwärtskompatibilität für vorangegangene Hauptversionen mit Java SE gegeben – das gilt auch für die künftigen JDK Releases mit JPMS. Jigsaw trennt die APIs und die Implementierung von Java-Komponenten und bietet mit diesem Modularisierungsmodel eine bessere Unterstützung für große Projekte an. Die Aufgabe der Java-Anwendungsmodularisierung ist für eine Dekade konzipiert und der Classpath kann weiterhin benutzt werden.

GraalVM der Grenzüberschreiter im Java-Ökosystem

Durch die GraalVM und ihre Vielsprachigkeit, den JIT Compiler und das Native Image erfuhr das Java-Ökosystem im Jahr 2019 einen Innovationsschub. Die GraalVM bietet für Entwickler und Anwender eine große Chance mit dem Potential, die Java-Landschaft grundlegend zu verändern. Bei der GraalVM handelt es sich um eine universelle virtuelle Maschine (VM) für Anwendungen, die in JavaScript, Python, Ruby, R oder mit den JVM-basierten Programmiersprachen Java, Scala, Kotlin, Clojure sowie LLVM-basierten Sprachen C/C++ geschrieben wurden. Neben den jeweiligen Performance-Verbesserungen hebt die polyglotte GraalVM die Grenzen zwischen den Programmiersprachen auf und ermöglicht die Interoperabilität in einer gemeinsam genutzten Laufzeitumgebung.

Mit dem GraalVM Native Image Tool wird Java-Code via Ahead-of-Time-Kompilierung (AoT) in Maschinencode konvertiert, der als eigenständige Binärdatei ausführbar ist. Das Native Image ermöglicht niedrige Startup-Zeiten bei geringem Memory-Bedarf, was für die Ausführung von Microservices-Frameworks wie Helidon, Micronaut und Quarkus vorteilhaft ist. Die GraalVM gibt es in zwei Ausführungen. Es gibt einerseits die frei einsetzbare und quelloffene GraalVM Community Edition (CE) mit „GPLv2 + Classpath Exception“-Lizenzierung, andererseits die optimierte GraalVM Enterprise Edition (EE) für den produktiven Einsatz mit der kostenpflichtigen OTN-Lizenz. Die GraalVM CE basiert auf dem auf GitHub verfügbaren GraalVM Sourcecode und kann kostenfrei im Produktivbetrieb eingesetzt werden. Die GraalVM EE ist für Entwicklung, Test, Prototyping und Demozwecke kostenlos nutzbar.

JDK Lieblings-Features

Seit der Einführung vom Oracle JDK 11 im September 2018 und der damit verbundenen Gleichstellung von Oracle JDK 11 und dem Oracle OpenJDK 11 wurden die technischen Unterschiede zwischen den Versionen entfernt. Bei diesem Technologietransfer sind alle Bestandteile vom Oracle JDK als Open-Source-Implementierungen in das Oracle OpenJDK geflossen, sodass das Oracle JDK mit dem Oracle OpenJDK frei getauscht werden kann. Passend zum Oracle JDK 11 und Oracle OpenJDK 11 wurde der JDK Flight Recorder und die JDK Mission Control frei verfügbar angeboten.

JDK Flight Recorder

Die Werkzeuge zum unternehmensweiten Java-Management, die mit JDK 7 im Juli 2011 eingeführt wurden, beinhalten Diagnose- und Monitoring-Tools für Java-Laufzeitumgebungen. JDK Mission Control ist ein etabliertes Werkzeug für das Monitoring, Profiling und die Diagnose von Java-Anwendungen. Der JDK Flight Recorder ist hingegen mit einem echten Flugdatenschreiber vergleichbar: Die auf ihm gespeicherten Informationen werden wichtig, wenn etwas schiefgelaufen ist. So ist es auch beim JDK Flight Recorder. Hier finden sich kontinuierlich aufgezeichnete Informationen darüber, was auf der Java Virtual Machine passierte, als ein Fehler auftrat. Das Werkzeug kann mit beliebigen Java-Anwendungen und Applikationsservern, von der Entwicklung bis zum produktiven Betrieb, verwendet werden. Die einheitliche Datenbasis des Java Flight Recorders ermöglicht Administratoren und Entwicklern, gemeinsam an Problemlösungen zu arbeiten und Konflikte besser und schneller zu bewältigen.

In development: Fehlende JDK Features

Mit dem definierten Oracle-Prozess der JDK Enhancement Proposals (JEPs), gelangen die technischen Verbesserungsvorschläge in das OpenJDK und in das JDK. Die JEP-Struktur dient zur Gestaltung einer langfristigen Java-Feature-Pipeline und der Roadmap für die JDK-Release-Projekte sowie den damit verbundenen Aufwendungen.

NullPointerExceptions

JEP 358 „Helpful NullPointerExceptions“ steht beispielhaft für die stete Verbesserung der Java SE und gehört als lang ersehntes Merkmal zum JDK 14. Bei der Fehlersuche entfällt das lästige Rätselraten, welche Variable null war. Mittels Programm-Bytecode-Command-Analyse erkennt die JVM, welche Variable den Wert null ergibt. Die JVM löst eine NullPointerException (NPE) an einer Programmstelle aus, an der der Code versucht, eine Nullreferenz wieder zu dereferenzieren. Durch die Analyse der Programm-Bytecode Anweisungen ermittelt die JVM dann, welche Variable null war und beschreibt die Variable in Bezug auf den Quellcode mit einer Null-Detail-Nachricht in der NPE. Diese Information gelangt dann, zusammen mit der Methode, dem Dateinamen und der Zeilennummer, zur JVM.

Records

Mit der Einführung von Record-Typen (JEP 359) im Jahr 2020 gelangte ein brauchbares Feature als Preview in das JDK 14. Die Records wurden im Rahmen des Projektes Valhalla entwickelt. Ähnlich wie Enums lassen sich Records mit einer eingeschränkten Form von Klassen vergleichen und erlauben das Ersetzen einer einfachen Datenklasse durch Records mit Datenkapselung. Records deklarieren ihre Repräsentierung und sie bestätigen diese Darstellung an das zugehörige API. Dabei werden Freiheiten einer Klasse, also etwa die Fähigkeit das API von seiner Repräsentierung zu entkoppeln, bewusst aufgegeben. Im Gegenzug dazu erhält man mit Records einen signifikanten Grad an Präzision: Was zusammengehört, bleibt zusammen.

JavaFX & Swing

Der Status von Java Swing, das über die Java Foundation Classes im Jahr 1997 eingeführt wurde, ist unverändert und bedeutet, dass Java Swing ein Bestandteil von Java SE 8 ist und der Support gemäß Java SE Support Roadmap bis zum März 2030 läuft. Beim JDK 11 steckt Java Swing im Modul java.desktop.jmod, hierfür erstreckt sich der Support bis zum September 2026.

Seit der Vorstellung von JavaFX 2.0 auf der JavaOne 2011 hat die UI-Technologie für Java-Client-Anwendungen eine konstante Anzahl von Entwicklern begeistern können. Im Herbst 2012 wurden erste namhafte JavaFX-Anwendungsbeispiele vorgestellt, dicht gefolgt von weiteren Geschäftsanwendungen, die später mit JavaFX 8 realisiert wurden. Im Jahr 2013 ging die bislang proprietäre UI-Technologie vollständig in Open Source auf und fand ihr Zuhause für die Entwicklung im OpenJDK-Projekt OpenJFX.

Mit der Bündelung von JavaFX 8 und Java SE 8 (JRE/JDK) im März 2014 wurde die Versionierung von JavaFX/OpenJFX und Java SE vereinheitlicht. Aufgrund der JavaFX 8 Roadmap bekommt die Zusammenarbeit mit der JavaFX Developer Community und ihren signifikanten Entwicklungsbeiträgen einen hohen Stellenwert für den Fortbestand von JavaFX / OpenJFX.

Durch die Java-Modularisierung wurde JavaFX 11 aus dem JDK 11 herausgelöst und fortan von Oracles JavaFX-Engineering-Team und von Gluon gemeinsam gepflegt. JavaFX wird seitdem separat zum Oracle JDK hinzugefügt und OpenJFX passt mit dem OpenJDK zusammen.

Der Download von JavaFX 11 (LTS) und höheren Versionen erfolgt über eine separate Webseite. JavaFX 14 wird als eigenständiges Release über den Entwicklungspartner Gluon angeboten und kann als Open-Source-Software mit dem Oracle OpenJDK oder wahlweise mit dem Oracle JDK 14 und dem Java SE Subscription Support betrieben werden. Über Gluon wird ein dezidierter Support für JavaFX angeboten. Die JavaFX-Module können mit dem javafx-sdk-14 (SDK) über den Java Module Path integriert werden oder über die JavaFX 14 JMODs, die mit dem Werkzeug jlink in eigene Anwendungen eingebunden werden.

Beeindruckend sind der Aufwärtstrend der JavaFX-UI-Technologie mit den ansteigenden Downloads bei Maven Central im Jahr 2019 und die konkreten Projektdiskussionen beim JavaFX Anwendertreffen 2018 in München sowie auf den JFX Days 2019 in Zürich.

Dank der GraalVM und der darin enthaltenen Native-Image-Funktionalität können jetzt auch kleinere und vor allem leistungsfähigere JavaFX-Anwendungen mit der aktuellen JDK-Version und der korrespondierenden JavaFX-Version erstellt werden. Damit ist ein Cross-Plattform-Deployment möglich, die Plattformen iOS und Android werden mit Java durch Gluon Mobile abgedeckt.

Von Konferenzen und Verwaltungssystemen

Die JavaOne-Konferenz wurde im Jahr 1996 erstmals von Sun Microsystems veranstaltet, um alle relevanten Java-Themen zu diskutieren. Die weltweite Entwicklerkonferenz, die immer in San Francisco stattfand, gab über viele Jahre den Takt zur Weiterentwicklung der Programmiersprache Java vor. Die Begeisterung der Entwickler erreichte ihren Höhepunkt im Jahr 2001 mit 25.000 Teilnehmern im Moscone Center. Die Obergrenze hatte der Feuerwehrchef von San Francisco aus Brandschutzgründen ausgegeben und tatsächlich waren exakt 25.000 Teilnehmer im Gebäude versammelt, sodass der Feuerwehrchef das Gebäude nicht räumen lassen musste.

Die Oracle Code One, hat die frühere JavaOne im Jahr 2018 als Nachfolgekonferenz abgelöst. Sie ist auf verschiedene Programmiersprachen, Technologien und Entwickler-Communitys ausgerichtet. Bei ihrer Premiere lag der Fokus auf den Code-Contributions durch Entwickler via GitHub, natürlich Java selbst und der weltweiten Zusammenarbeit der Java Community im OpenJDK.

Das Projekt Skara wurde vor Ort von GitHub vorgestellt. Die Community arbeitet dabei an der Umsetzung eines alternativen Source-Code-Management-Systems mit Code-Review-Optionen für den JDK-Quellcode, das anstelle von Mercurial das beliebtere Git nutzt. In der GitHub-Skara-Demo wurde ein Code-Update mit einem JDK 10 Feature in einem älteren Java Programm durchgeführt, dann der Pull Request erzeugt und die Änderung analysiert. Die Demo verdeutlichte so die einzelnen Verbesserungen mit GitHub bei der Java-Entwicklung und unterstützt damit einen unkomplizierten Zugang zu den Java-Repositorys.

In Übereinstimmung mit JEP 357 (Migration von Mercurial zu Git) hat JEP 369 die Aufgabe, alle OpenJDK-Projekte mit einem Repository zu GitHub zu migrieren. Letzteres gilt einschließlich der JDK Feature Releases sowie der JDK Update Releases für Version 11 und höher. Diese beiden JDK-Verbesserungsvorschläge sind als Bestandteil für das JDK 16 vorgeschlagen.

Fazit und Ausblick

Mit dem sechsmonatigen Java-Release-Zyklus wird angestrebt, dass neue Features schneller bereitgestellt werden können und die Java Feature Releases zueinander passen. Außerdem soll sichergestellt werden, dass nicht-LTS-Releases den Ruf „experimenteller“ Versionen verlieren und und die als „deprecated“ markierten Features nicht einfach aus Zwischen-Releases verschwinden.

Die Erfahrungen beim Umstieg von JDK 8 auf JDK 11 haben gezeigt, dass die Variante „just run“ praktisch nutzbar ist. Das heißt, existierende Java-Anwendungen sind dank Abwärtskompatibilität ohne Modifikation mit dem höheren Java-Release ablauffähig. Dennoch muss man in seltenen Fällen die Möglichkeit einer Unverträglichkeit in Betracht ziehen, wenn auch nur in Randbereichen. Mit der Variante „Neukompilieren und Quell-Code anpassen“ wird der alte Java-Code immer auf dem aktuellen Stand der Technik gehalten und durch die gängigen Entwicklungsumgebungen bestmöglich unterstützt.

Der Oracle JDK Migration Guide bietet praktische Hilfen bei der Migration von JDK 8 auf JDK 11 oder JDK 17 (LTS). Die künftige Feature-Pipeline für Java ist gut gefüllt! Die Inhalte der Projekte Amber (Right-sizing Language Ceremony), Valhalla (Value Types und Spezialized Generics), Panama (Foreign Function/Data Interface), Loom (Continuations in der JVM und Fibers im JDK) und Project Leyden (Static Images für das JDK) stellen dies unter Beweis. Unabhängig davon, ob Java on-premises oder in der Cloud eingesetzt wird, liegt es in der Hand der Community, wie wir die nächsten 25 Jahre gestalten möchten und wohin Java steuert.

Verwandte Themen:

Geschrieben von
Wolfgang Weigend
Wolfgang Weigend
Wolfgang Weigend arbeitet als Master Principal Solution Engineer bei der Oracle Global Services Germany GmbH im weltweiten Java Team. Er beschäftigt sich mit Java-Technologie, GraalVM und Architektur für unternehmensweite Anwendungsentwicklung.
Kommentare

Hinterlasse einen Kommentar

avatar
4000
  Subscribe  
Benachrichtige mich zu: