Java feiert 25. Jubiläum

Feierlichkeiten

Für den 25. Geburtstag von Java hat sich Nicolai Parlog, Java-Guru und Autor von The Java Module System, etwas ganz besonderes ausgedacht:

25 Hours of Java

Ein 25-stündiger Livestram, mit namhaften Gästen wie Brian Goetz (Java Language Architect), der IntelliJ-Evangelistin Trisha Gee u.v.m.. Das Event startet am 23. Mai 2020 um 8:00 Uhr deutscher Zeit, und endet am 24. Mai um 9:00 Uhr. Falls ihr noch nichts anderes vorhabt, schaut mal rein… (zumindest hier in Süddeutschland soll es ja regnen ;-)

Die Anfänge

Ursprünglich wurde Java von einem Team unter James Gosling für Sun Microsystems entwickelt. Am 25. Mai 1995 wurde Java erstmals der Öffentlichkeit vorgestellt. Damals war es noch eine Alpha-Version. Bis zur Veröffentlichung von Release 1.0 sollte es dann noch bis Januar 1996 dauern. Den Durchbruch schaffte Java mit der Integration in den Netscape Navigator. Mit der Zeit etablierte sich die Sprache jedoch auf dem Gebiet der Serveranwendungen für Unternehmen. Desktop-Anwendungen spielten stets eine untergeordnete Rolle, da zur Ausführung eine Runtime-Engine (JRE) nötig ist. Dieser Aspekt erschwert die Auslieferung der Anwendungen für die Entwicklerseite, sowie die Ausführung beim Anwender – sofern keine JRE mitgeliefert wird.

Besonderheiten von Java waren und sind der Garbage Collector, der den Entwicklern das Speichermanagement abnimmt, sowie das Versprechen „write once, run anywhere“. Das bedeutet, dass ein kompiliertes Java-Programm auf unterschiedlichen Plattformen wie Windows, Unix, Linux etc. läuft, wenn eine entsprechende JRE vorhanden ist. Das Maskottchen von Java ist der „Duke“ (siehe links).

Der Name rührt daher, dass die Indonesische Insel Java ein Anbaugebiet für Kaffee ist, weshalb Kaffee in den USA umgangssprachlich auch „Java“ genannt wird. Ein passender Name, da Kaffee unter Entwicklern ja ein recht beliebtes Getränk sein soll… ;-)

Java im Lauf der Zeit

In den ersten Versionen gab es keine großen Änderungen an der Sprache selbst. Jedoch wurde kontinuierlich „unter der Haube geschraubt“, beispielsweise mit Fokus auf Performance, bei der Java seit jeher einen – im übrigen ungerechtfertigt – nicht allzu guten Ruf genoss. Auch die Standardbibliothek wurde nach und nach erweitert und so immer umfangreicher.

Dann kam im September 2004 mit Java 5 das erste Release mit vielen neuen Features wie Generics, Autoboxing, Enums und Annotations, für das die Entwickler sich etliche neue Sprachkonstrukte aneignen mussten.

Lagen die Zyklen für Major-Releases bis dahin bei 1-2 Jahren, vergingen zwischen Java 6 (Dezember 2006) und Java 7, welches im Juli 2011 erschien, sage und schreibe 4 1/2 Jahre! Das lag womöglich mitunter daran, dass mit dem Release auch Lambdas und die Modularisierung („Jigsaw“) kommen sollten, welche dann auf Java 8 respektive Java 9 verschoben wurden. In der Zwischenzeit, nämlich im Jahr 2010, wurde Sun von Oracle aufgekauft, womit Java in den Besitz des Datenbankriesen gelangte.

Sowohl Java 8 (März 2014) als auch Java 9 (September 2017) erschienen mit erheblichen Verspätungen, begründet durch die zu den ursprünglich geplanten Erscheinungsteminen noch nicht fertig gestellten Hauptfeatures. Aus diesem Grund entschied man sich, mit Java 9 auch einen neuen Releasezyklus einzuführen. Seitdem erscheinen neue Java-Versionen zu festen Terminen im Halbjahresabstand. Enthalten sind alle Features, die bis zum Releasedatum fertig gestellt sind. So müssen Entwickler nun nicht mehr lange auf neue Sprachfeatures warten, nur weil ein großes Feature sich verspätet. Da der Releasezyklus nun zu kurz ist für Vorabversionen, in denen die Community neue Features testen und Feedback dazu geben kann, wurden zudem die „Preview Features“ eingeführt. Diese sind in den Major-Versionen enthalten, müssen aber extra per Kommandozeilenparameter hinzugeschaltet werden. Preview Features sind noch nicht für den produktiven Gebrauch gedacht, weil sie sich bis zu ihrer finalen Version noch ändern oder wieder entfernt werden können.

Java 10 (März 2018) ist bekannt für var, das in Methoden statt der Typdeklaration verwendet werden kann, um den Code kürzer und somit lesbarer zu machen.

Java 11 (September 2018) ist eine LTS-Version mit verlängertem Support. Bezeichnend für diese Version ist, dass erstmals eine größere Anzahl von Features aus Java entfernt wurden (z.B. JavaFX, CORBA und die JavaEE-Module). Die zuvor in Java 9 eingeführte Modularisierung ermöglichte dies. Bisher war man es gewohnt, dass die Java-Macher großen Wert auf Rückwärtskompatibilität gelegt, und so gut wie nichts aus der Sprache entfernt hatten; es wurde lediglich die eine oder andere Methode bzw. Klasse als deprecated markiert. Mit Java 11 kam aber auch Neues hinzu, z.B. die Möglichkeit, java-Dateien direkt auf der Kommandozeile auszuführen, ohne diese erst kompilieren zu müssen.

Mit Java 12 (März 2019) kam die Feature-Preview für switch-Expressions, in Java 13 (September 2019) eine leicht angepasste Version der switch-Expressions-Preview, sowie eine Preview für Text Blocks.

Java 14 (März 2020), die derzeit aktuelle Version, beinhaltet u.a. die switch-Expressions im Standardumfang sowie Previews für Pattern matching für instanceof und aussagekräftigere NullPointerExceptions.

Die Sache mit der Lizenz

Auch hinsichtlich der Lizenzierung änderte sich so Einiges. Das Oracle JDK darf seit 2019 nicht mehr kostenlos für kommerzielle Zwecke in Produktionsumgebungen verwendet werden. Für das Oracle OpenJDK gilt das nicht, jedoch erscheinen Versionen mit Bug- und Securityfixes nur für die jeweils neuste Major-Version. Will man die jeweils aktuellen Fixes haben, ist man also gezwungen, entweder dafür zu bezahlen, oder halbjährlich auf ein neues Release zu migrieren. Dieser Umstand löste erhebliche Unsicherheiten in den Reihen der Java-Anwender aus. Doch die Community sprang ein, so dass in der Zwischenzeit einige kostenfreie Alternativen entstanden, wie z.B. AdoptOpenJDK, Amazon Corretto, oder das Redhat OpenJDK für CentOS.

Ausblick

So schnell dürfte mit Java noch nicht Schluss sein. Das riesige Ökosystem an Bibliotheken, Tools und Applikationsserver ist eine der größten Stärken der Sprache, die sich nach wie vor großer Beliebtheit erfreut. Und trotz einiger Kompromisse zugunsten der Abwärtskompatibilität haben die Macher von Java gezeigt, dass sie in der Lage sind, die Sprache an die Anforderungen moderner Softwareentwicklung anzupassen. So wurde beispielsweise die Flow-API als Grundlage für reaktive Anwendungen in Java 9 aufgenommen. Projekt Valhalla verspricht Value Objects und Generics für primitive Datentypen.  Mit GraalVM ist wird eine VM für polyglotte Anwendungen entwickelt, die zudem das Bauen nativer Images für die Ausführung in Container- bzw. Cloudumgebungen unterstützt. Und Project Loom soll leichtgewichtige „Virtual Threads“ (früher auch als „Fibers“ gehandelt) bringen.

Ich bin gespannt, wohin uns die Reise mit Java in den nächsten 25 Jahren noch so führt… ;-)

Spring oder Spring Boot – das ist hier die Frage!

Die Tatsache dass die Begriffe „Spring“, „Spring Framework“ und „Spring Boot“ gerne synonym verwendet werden, macht die Unterscheidung nicht einfacher. Daher möchte ich differenzieren zwischen dem „Spring Framework“ und „Spring Boot“. Der Begriff „Spring“ dagegen schließt beides ein und beinhaltet alles, was die Spring-Welt insgesamt zu bieten hat.

Das Spring-Framework

Spring FrameworkLaut offizieller Dokumentation handelt es sich beim Spring Framework um „ein umfassendes Programmier- und Konfigurationsmodell für moderne Java-basierte Unternehmensanwendungen – auf allen möglichen Deployment-Plattformen. […] Spring fokussiert sich auf das ‚Verdrahten‘ von Unternehmensanwendungen, ohne unnötige Bindungen an spezifische Deployment-Umgebungen“
(Quelle: https://spring.io/projects/spring-framework)

Das Spring Framework ist also eine Sammlung von Tools für die Entwicklung von Geschäftsanwendungen. Zu seinen Kernfunktionalitäten gehören Dependency Injection, Events, Ressourcen, Internationalisierung, Datenzugriff mit Transaktionen, Integration und etliches mehr.

Spring Boot

Spring Boot setzt auf dem Spring Framework auf und soll eine sehr einfache Entwicklung von lauffähigen und produktionsreifen Spring-Anwendungen ermöglichen. Dies wird durch einen Autokonfigurations-Mechanismus erreicht, der die Tools aus dem Spring Framework, sowie eine Reihe weiterer Tools, auf sinnvolle Art und Weise vorkonfiguriert. Mit „Konfiguration“ ist an dieser Stelle übrigens die Konfiguration der Spring-Beans gemeint die bestimmt, welche Beans für Dependency Injection zur Verfügung stehen und wie diese miteinander „verdrahtet“ werden – und nicht die Konfigurations-Properties, die man etwa in der application.properties pflegt.

Beispielsweise bringt Spring Boot Web standardmäßig einen eingebetteten Tomcat-Container mit, der auf Port 8080 läuft – und das ohne dass man irgendetwas selbst konfigurieren muss. Den Port kann man ändern, in dem man in der application.properties unter server.port einfach einen anderen Wert einträgt. Statt Tomcat kann man auch einen anderen Servlet-Container verwenden. Dafür muss man lediglich den Tomcat in der Maven- oder Gradle-Konfiguration exkludieren und die Dependency für einen anderen Container, wie etwa Jetty, hinzunehmen.

Auch andere Aspekte wie z.B. Spring Data, Spring Security u.ä. können einer Anwendung hinzugefügt werden, indem man einfach nur Dependencies in die Build-Konfiguration mit aufnimmt. Spring Boot erkennt dann allein durch das Vorhandensein bestimmter Klassen oder Konfigurations-Properties, dass eine Funktionalität aktiviert werden soll, und erzeugt automatisch die dafür notwendigen Spring-Beans. Ist z.B. HikariCP im Klassenpfad vorhanden, wird automatisch eine HikariDataSource-Bean erzeugt. Ist stattdessen DBCP2 im Klassenpfad (und Hikari exkludiert), wird statt Hikari der DBCP2-Connection-Pool für die Data Source verwendet. Für Spring Data JPA werden automatisch Hibernate und Transaktionen aktiviert.

Des weiteren registriert Spring Boot eine ganze Reihe von @PropertySources, so dass Anwendungs-Properties automatisch aus sage und schreibe 17 verschiedenen Quellen gelesen werden – u.a. der application.properties, application.yaml, Kommandozeilenparametern, OS-Systemvariablen, Java System Properties u.v.m. Die komplette Liste ist hier zu finden:
https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config.

Das spring-boot-maven-plugin packt die Anwendung zusammen mit allen benötigten Bibliotheken in eine „Fat Jar“, die mit java -jar my-app.jar gestartet werden kann.

Zu guter letzt bringt Spring Boot ein sehr umfangreiches Dependency Management mit, in der die Versionen für die Spring-Bibliotheken, aber auch für viele 3rd-Party-Libs (z.B. Apache Commons, Hibernate, JUnit, Mockito u.v.m.) aufeinander abgestimmt und gepflegt sind. So kann man sich diese Bibliotheken ins Projekt holen, ohne deren Versionen selbst pflegen zu müssen.

Mit dem Spring Initializr kann man sich übrigens in Windeseile ein neues Spring-Boot-Projekt erstellen lassen, mit dem man direkt und ohne Initialaufwand die Entwicklung starten kann. Der Initializr ist verfügbar als Web-UI, Kommandozeilentool, für HTTP-Clients wie cURL, oder sogar direkt aus IDEs  (z.B. IntelliJ IDEA) heraus.

Fazit

Das Spring Framework ist ein Toolset zur Entwicklung von Unternehmensanwendungen für alle möglichen Deployment-Plattformen. Spring Boot setzt darauf auf und bietet viele Komfortfunktionen, die einen schnellen Projektstart ermöglichen und vernünftig vorkonfiguriert sind, aber dennoch sehr flexibel per Konfiguration an die jeweiligen Bedürfnisse angepasst werden können.

Wer mehr über Spring Boot und die Details des Autokonfigurations-Mecanismus wissen möchte, findet hier eine ausführliche Erläuterung:
https://www.marcobehler.com/guides/spring-boot.

How to deploy a (native) Quarkus Application on Heroku

Quarkus is a „container first“ framework for microservice development in Java (or alternatively Kotlin or Scala). With help of GraalVM Native Image, Quarkus applications can be compiled to native executables that run directly on the target OS, without JVM, with low memory footprint and blazing fast startup time.

Heroku is a Cloud Application Platform for building and hosting applications, while various languages can be used for development. It also allows to deploy and run self-built docker images.

Following the instructions from this blog post, we’ll create a native Quarkus application and deploy it in a docker container to the Heroku Runtime.

Mehr

7 Tipps zum Schreiben von lesbarem Java-Code

Webcast-Online CommunitiesBekanntlich wird Code viel öfter gelesen als geschrieben. Häufig wird er auch von anderen Personen gelesen als von derjenigen, die ihn verfasst hat. Und hast du nicht selbst schon erlebt, dass dein eigener Code nur wenige Monate später völlich unverständlich für dich war…? ;-) Umso wichtiger ist es, dass du dir darüber Gedanken machst, wie du deinen Code so lesbar und verständlich wie möglich gestalten kannst.

Doch was macht lesbaren, verständlichen Code aus? Er ist ausdrucksstark, das heißt er drückt aus was er tut. Und zwar genau das, und nur das.

Allerdings ist das Schreiben von lesbarem Code nicht wirklich leicht. Robert C. Martin („Uncle Bob“) zieht in seinem Buch über Clean Code1 den Vergleich zur Malerei: Es ist einfach zu erkennen ob ein Bild gut oder schlecht gemalt ist. Aber selbst ein gutes Bild zu malen, dafür braucht es viel Übung.

Daher möchte dir die folgenden 7 Tipps an die Hand geben, die dir dabei helfen können, lesbaren Code zu schreiben.Mehr

Java die 13’te

Alle halbe Jahre wieder – erscheint ein neues Java-Release. Am morgigen Dienstag, 17.09.2019, ist es wieder soweit: Java 13 wird veröffentlicht.

Folgende Funktionalitäten wurden im Rahmen der Entwicklung des Releases fertig gestellt, und halten Einzug in Java 13:

Mehr

Die Verantwortung der Entwickler

(Eins vorweg: der hier aus pragmatischen Gründen verwendete Begriff „Entwickler“ ist geschlechtsneutral gemeint und soll niemanden ausschließen; vielmehr seien damit alle Personen angesprochen die Software entwickeln, unabhängig von der Geschlechtsbezeichnung (m/w/*), der sie sich zugehörig fühlen.)

Software ist allgegenwärtig und spielt in vielen Lebensbereichen eine Rolle. So schlägt sie z.B. im Onlineshop Artikel vor, die einem auch gefallen könnten, oder im Streamingdienst Filme und Serien, die aufgrund bereits geschauter Titel wahrscheinlich ebenfalls den Geschmack des Zuschauers treffen. Doch auch in vielen sicherheitskritischen Bereichen, in denen es um Menschenleben geht, ist Software involviert. Sind wir Entwickler uns der daraus erwachsenden Verantwortung auch immer bewusst?
Mehr

Welches Logging-Framework für Java nutzen?

Einer der größten Vorteile von Java ist das reichhaltige Ökosystem, in dem viele Bibliotheken und Frameworks für die Programmiersprache existieren. Auch der Bereich Logging hat gleich mehrere Frameworks zu bieten, was die Frage aufwirft, welches davon man nutzen soll. Dieser Artikel stellt die Frameworks kurz vor und soll als Entscheidungshilfe bei der Auswahl des passenden Frameworks dienen.Mehr

April April! (Entfernung der Time API ;-)

In Zeiten der „Fake News“ sollte man stets den Wahrheitsgehalt von dem hinterfragen was man liest – insbesondere an einem bestimmten Tag im Jahr, wie gestern einer war. :-)

Der JEP-472 und die Entfernung der neuen Date & Time API aus meinem gestrigen Beitrag waren natürlich frei erfunden. Spätestens beim Anklicken der Quellen-Links wäre dies klar geworden.

Tatsächlich ist die java.time-API ein Beispiel für sehr gutes Code Design. Unter anderem werden die folgenden Prinzipien darin konsequent eingehalten:Mehr