Suche
Einfacher und einheitlicher

Java EE 8 ist da! Das sind die wichtigsten Änderungen und Features

Sebastian Daschner

© Shutterstock / TippaPatt

Gemeinsam mit dem gestrigen Release von Java 9 wurde auch Java EE 8 veröffentlicht. Die neue Version hat einen längeren und schwierigen Weg hinter sich, doch wie heißt es so schön: was lange währt wird endlich gut. Im Zuge des Versionsupdates wurden wieder einige Spezifikationen aktualisiert, um die Plattform produktiv und modern zu halten: Hier sind die wichtigsten Änderungen der einzelnen Java Specification Requests (JSRs) im Überblick.

Der so genannte Umbrella JSR der Plattform umfasst die Spezifikationen, die in der Enterprise Edition enthalten sind, und ist für die Zusammenarbeit der einzelnen Spezifikationen zuständig. In Java EE 8 werden als neue Technologien Java API for JSON Binding (JSON-B, JSR 367) und Security API (JSR 375) hinzukommen, beide in Version 1.0. Ein Update erhalten haben CDI 2.0 (JSR 365), JAX-RS 2.1 (JSR 370), Bean Validation 2.0 (JSR 380), Java API for JSON Processing (JSONP, JSR 374), Servlet 4.0 (JSR 369) und JSF 2.3 (JSR 372). Grundsätzlich ist das Mantra der EE-8-Neuerungen, Java EE fit für Java-SE-8-Features zu machen, wie Lambdas und wiederholbare Annotationen, zusammen mit dem noch besseren Zusammenspiel der einzelnen Standards untereinander.

CDI 2.0: Context and Dependency Injection

Context and Dependency Injection (CDI) gehört mit zu den wichtigsten Standards in Java Enterprise. Das API fungiert als Kleber zwischen Codekomponenten und anderen EE-Spezifikationen. CDI macht Enterprise-Entwicklern das Leben deutlich leichter. In Version 2.0 wurde vor allem Augenmerk auf CDI außerhalb eines EE-Containers gelegt, d. h. dass auch Java-SE-Anwendungen von einem abgespeckten Dependency-Injection-Standard Gebrauch machen können. Das soll für größere Akzeptanz von CDI auch jenseits der Java-EE-Welt sorgen. Abgesehen davon gab es vergleichsweise wenig Updates, was schon in Java EE 7 für den Reifegrad dieser Technologie sprach. Ein paar neue, hilfreiche Features gibt es aber dann doch, beispielsweise asynchrone CDI-Events.

CDI-Events sind ein hilfreiches Mittel, um Codefunktionalitäten lose zu koppeln. Bisher werden CDI-Events grundsätzlich synchron behandelt. Die Ausnahme davon waren bisher mit @Asynchronous-annotierte Event-Handler-Methoden in EJBs. In Version 2.0 werden asynchrone Events auch mit reinem CDI möglich sein. Man bestimmt die Asynchronität von Events mit der neuen Methode fireAsync() sowie der Annotation @ObservesAsync.

Noch eine Neuerung bezüglich CDI-Events: Observer-Methoden können nun per @Priority eine Reihenfolge bei der Ausführung festlegen. Damit hält sich CDI an bisherige Konventionen im Java-EE-Umfeld. Wiederverwendbare Annotationen wie @Priority sind allgegenwärtig und erleichtern den Alltag von Entwicklern.

JAX-RS 2.1: mehr REST

JAX-RS ist der Standard, um mit Java REST-Services zu entwickeln. Innerhalb der Java-Plattform ist die Entwicklerakzeptanz sehr groß. Aber auch außerhalb des Java-EE-Umfelds findet JAX-RS große Verbreitung. Mit Version 2.1 hat sich die Expert Group hauptsächlich den Themen Reactive Clients, Server-sent Events (SSE) und der noch besseren Integration von Bean Validation, JSON-B und CDI verschrieben. Zudem wurden von der Community viele kleinere Verbesserungen vorgeschlagen, denen ebenfalls versucht wird, Rechnung zu tragen.

Da das Thema reaktive Programmierung immer populärer wird, unterstützt der JAX-RS-2.1-Client neue Funktionalitäten, um HTTP-Aufrufe direkt in entsprechenden, reaktiven Typen zurückzugeben. Das erleichtert die Arbeit mit diesen Technologien und vermindert Boilerplate-Code. Der Client unterstützt nun nativ CompletionStages  und andere Typen und Frameworks per Erweiterung. Dazu wurde dem ClientBuilder eine neue rx()-Methode spendiert.

Ein weiteres, interessantes neues Feature ist die Unterstützung von Server-sent Events (SSE)  – sowohl server- als auch clientseitig. SSEs sind Plain-Text-Nachrichten, die vom Server zu den Clients geschickt werden, die einen Endpunkt auf dem entsprechenden Server abonniert haben. Gerade für webbasierte, leichtgewichtige Updatemechanismen auf Nachrichtenbasis bietet dieser Standard eine einfache Lösung.

Einer der größten Vorteile von Java Enterprise ist die nahtlose Integration der einzelnen Spezifikationen mit möglichst wenig entwicklerseitigem Extraaufwand. Das Ziel hat JAX-RS 2.1 ebenfalls wieder auf der Agenda, was die Integration von JSON-B (JSR 367), Bean Validation 2.0 (JSR 380) und JSONP 1.1 (JSR 374) nach sich zieht. Wie schon mit JAXB der Fall, können den JSON-Output annotierte Typen steuern, die von JAX-RS-Ressourcen-Methoden zurückgegeben werden. Einzelne JSON-Felder und -Strukturen lassen sich mit JSON-B deklarativ per Annotationen konfigurieren. Die Integration in JAX-RS sorgt dafür, dass der JSON-Output vom Container in entsprechendes HTTP serialisiert wird. Die gleiche nahtlose Integration in JAX-RS und somit die HTTP-Welt gilt für die neuen Features von Bean Validation 2.0 und JSONP 1.1.

In der neuen Version kommen ebenfalls viele kleinere und für den Entwickleralltag hilfreiche Neuerungen hinzu. Dazu zählt serverseitiger Support für HTTP PATCH (per @PATCH), Support von CompletionStage als neuer Rückgabetyp von asynchronen JAX-RS-Methoden und standardisierte Time-out-Spezifikationen im JAX-RS-Client. In 2.1 gibt es, wie die Version vermuten lässt, keine bahnbrechenden Neuerungen, jedoch interessante neue Features und viele kleine Verbesserungen, mit dem Ziel, dieses API für die Entwickler noch angenehmer zu gestalten.

JSON-B 1.0: Java-Objekte zu XML

Seit Langem ist JAXB ein weit verbreiteter Standard in Java EE und SE, um deklarativ Java-Objekte zu XML zu mappen. In ähnlicher Art und Weise definiert das Java API for JSON Binding 1.0 (JSON-B), wie Java-Objekte deklarativ ins JSON-Format gemappt werden. Die Annotationen, wie @JsonbProperty, und der gesamte Look and Feel werden Entwickler an JAXB erinnern, was den Einstieg erleichtert. Selbstverständlich lassen sich per Serializer und Adapter auch eigene Mapping-Logiken definieren. Einer der größten Vorteile von JSON-B ist vermutlich der Einsatz zusammen mit JAX-RS. Die Spezifikationen werden – wie auch schon mit JAXB – nahtlos zusammenspielen. Damit steht dem anbieterunabhängigen Einsatz von deklarativem JSON-Mapping per JAX-RS in Projekten nichts mehr im Weg.

Bean Validation 2.0: Support für Java SE 8

Bean Validation (BV) hat mit Version 2.0 ein paar neue Features und vor allem Support für Java SE 8 erhalten. Da in SE 8 nun mehrmals dieselben Annotationstypen an einer Stelle auftreten dürfen, macht BV davon Gebrauch und unterstützt damit mehrfache, verschieden konfigurierte Constraints pro Feld oder Typ. Zudem wird out-of-the-box Validierung der Java-8-Time-Typen unterstützt, wie in @Past LocalDate date. Als weiteres interessantes Feature können mit 2.0 auch in Containertypen enthaltene Werte validiert werden, wie Map<String, @Valid Customer> customers, List<@NotNull String> strings oder Optional<@NotNull String> getResult(). Bean Validation 2.0 enthält auch einige neue Constraints, die die Version mitliefert. Mit @Email lassen sich nun E-Mail-Adressen validieren. @Negative und @Positive verifizieren numerische Werte. @NotEmpty testet auf nicht leere Collections, Maps, Arrays oder Strings ungleich null und @NotBlank validiert Strings auf Whitespaces.

Security 1.0: mehr Sicherheit

Security 1.0 ist neben JSON-B die zweite, komplett neue Spezifikation in Java EE 8. Die Idee hinter Security ist, Authentifizierung und Autorisierung mit standardisierten, anbieterunabhängigen APIs zugänglich zu machen und moderne Technologien zu nutzen, die den Einsatz in Cloud-Umgebungen ermöglichen. Aktuell ist das den Entwicklern nur möglich, wenn sie aufwendig Mechanismen wie JASPIC implementieren oder anbieterspezifische Features nutzen. Einen Standardweg, so genannte IdentityStores zu definieren und einzubinden, gab es bisher ebenfalls nicht. JSR 375 ist in der Roadmap und Featureliste vom ursprünglichen Plan etwas abgewichen und wird nun hauptsächlich die Features HttpAuthenticationMechanism, IdentityStore und SecurityContext enthalten.

Aktuell existieren in Java mehrere Wege, User z. B. über HTTP zu authentifizieren, wie JASPIC oder JAAS. JASPIC ist ein sehr mächtiger Weg, alle möglichen Arten von Authentifizierungen einzubinden, kommt jedoch auch mit nicht trivialem Integrationsaufwand. Die Idee hinter dem HttpAuthenticationMechanism-Ansatz ist es, JASPIC auf einfachere Weise in Servlet-Containern zu nutzen. Vom Entwickler wird nur noch verlangt, ein HttpAuthenticationModule zu implementieren und die Authentifizierung in der web.xml-Datei anzugeben. Davon abgesehen werden Java-EE-Container auch schon vorgefertigte Authentifizierungsmechanismen anbieten, die sich z. B. per @BasicAuthenticationMechanismDefinition-Annotation konfigurieren lassen. Diese werden für BASIC- und formbasierte Authentifizierungen zur Verfügung stehen.

Lesen Sie auch: Java EE geht an die Eclipse Foundation

Bisher existiert auch kein Standardweg, in Java-EE-Applikationen oder -Containern IdentityStores zu definieren oder zu nutzen. IdentityStores enthalten Authentifizierungs- und Autorisierungsinformationen von Applikationsbenutzern und treten je nach Projekt und Infrastruktur meist in Form von LDAP-Servern oder Datenbankstrukturen auf. Security 1.0 enthält IdentityStores als leichtgewichtiges, portables Feature zum Verwalten dieser Informationen. Entwickler können vergleichsweise einfach eigene IdentityStores implementieren, die entweder User authentifizieren, autorisieren oder beides. Dazu ist das Interface IdentityStore gedacht. Davon abgesehen werden Java-EE-Container in Zukunft auch Standard-IdentityStores für externe LDAP- oder Datenbankanbindung anbieten. Diese können Entwickler bequem nutzen, indem sie jegliche per CDI auffindbare Klassen mit @LdapIdentityStoreDefinition oder @DataBaseIdentityStoreDefinition konfigurieren.

Businesscode muss ab und an Securityinformationen zum aktuellen Applikationsbenutzer abfragen. Aktuell lassen sich diese Informationen je nach Kontext auf verschiedene Weise abrufen. Security 1.0 enthält mit SecurityContext einen einheitlichen Weg, diese Informationen abzufragen und die bisherigen verschiedenen Aufrufe in Java-EE-Projekten abzulösen. Das Interface SecurityContext definiert dazu in erster Linie die Methoden getCallerPrincipal(), isCallerInRole und authenticate, die vom Container bereitgestellt werden müssen. JSR 375 wird das Thema Security in Java-EE-Projekten deutlich vereinheitlichen und somit die anbieterunabhängige Nutzung weiter vorantreiben.

JSONP 1.1: Erstellen und Lesen von JSON-Objekten

Java EE 7 hat mit dem Java API for JSON Processing 1.0 ein mächtiges Feature zum programmatischen Erstellen und Lesen von JSON-Objekten hinzubekommen. Version 1.1 enthält neben kleineren Updates hauptsächlich Unterstützung für Standards im JSON-Umfeld, z. B. JSON Pointer (RFC 6901), JSON Patch (RFC 6902) und JSON Merge Patch (RFC 7386). JSON Pointer ist ein IETF-Standard, der eine Syntax zu Abfragen zu JSON-Konstrukten und -werten definiert. Per Pointern wie „/0/user/address“ werden JSON-Werte referenziert, prinzipiell ähnlich zu XPath in XML-Konstrukten. JSONP 1.1 enthält dazu den neuen Typ JsonPointer, der passend zum bisherigen API per Json.createJsonPointer() erstellt wird. Dieser Pointer kann mit getValue() Werte zu JSON-Strukturen abfragen oder neue, veränderte JSON-Strukturen per add(), remove() oder replace() erzeugen. RFC 6092 definiert Methoden als JSON-Objekte, so genannte Patches, die bestehende JSON-Strukturen bearbeiten, wenn die Patches auf sie angewandt werden. In JSON 1.1 können per Json.createJsonPatch oder createJsonPatchBuilder Objekte vom neuen Typ JsonPatch erzeugt werden. Ähnliches gilt für den Support von JSON Merge Patch, in dem mehrere JSON-Konstrukte kombiniert werden, um neue resultierende Konstrukte zu erzeugen. Das wird in JSONP mit Json.createMergeDiff oder Json.createMergePatch und dem neuen JsonMergePatch-Typ realisiert.

Neben den neu unterstützten Standards enthält JSONP 1.1 ein paar Erweiterungen, um Java-EE-Entwicklern das Leben leichter zu machen. Dazu gehören Support von Java 8 Streams und vordefinierte Stream Collectors, wie .stream().collect(JsonCollectors.toJsonArray()). Ebenfalls neu ist Json.createValue, um aus Strings und numerischen Typen JSONP-Valued-Typen leichter erstellen zu können.

Servlet 4.0: HTTP2 und Server-Pushes

Servlet 4.0 betrifft hauptsächlich ein großes Thema: HTTP/2. Die neue Version von HTTP soll mit Multiplexing, Pipelining, Headerkomprimierung und Server-Push die Latenz und den Durchsatz von Client-Server-Verbindungen erhöhen. Servlet 4.0 enthält Support von HTTP/2, worauf dann andere Spezifikationen, wie JAX-RS, aufsetzen und die Servlets wie bisher schon transparent nutzen. Die meisten Änderungen in Servlet 4.0 sind hauptsächlich für Servlet-Container und weniger für die Entwickler sichtbar, bis auf die Ausnahme von Server-Push. Mit Server-Pushes schickt der Server direkt HTTP Responses an den Client, aufgrund der Annahme, dass nach der clientseitigen Anfrage einer bestimmten Ressource vermutlich weitere Ressourcen benötigt werden. Das betrifft im Web hauptsächlich Stylesheets, JavaScript-Code und andere Assets. Mit PushBuilder, den der Entwickler mit HttpServletRequest.newPushBuilder() erzeugt, werden in Servlet 4.0 diese Server-Push-Nachrichten ermöglicht.

JSF 2.3: moderne HTML-UIs

Java Server Faces ist der klassische Weg, um in Java EE serverzentrische, komponentenbasierte HTML-UIs zu erstellen. Version 2.3 enthält direkt ein paar Neuerungen. JSF 2.3 macht es mit neuen CDI-Produzenten und Qualifiern Entwicklern leichter, JSF-Komponenten wie ApplicationMap oder ExternalContext per @Inject zu injizieren. Das deckt sich mit dem Java-EE-Gedanken und vereinfacht die Entwicklung. Die Spezifikation enthält nun auch WebSocket-Support per <f:websocket>-Tag. Die XML-Attribute channel und onmessage definieren den WebSocket-Kanal und den JavaScript-Event-Handler, der beim Eintreffen einer Nachricht aufgerufen wird. Über den Typ PushContext können serverseitig von JSF aus WebSocket-Nachrichten an den Client geschickt werden. JSF 2.3 verbessert ebenso die Integration von Ajax mit serverseitigem Code. Mit dem Tag <h:commandScript> lassen sich nun serverseitige Methoden aus dem UI aufrufen. Das haben bisher die meisten Implementierungen unabhängig vom Standard schon unterstützt. Zudem ist es möglich, auf dem Client JavaScript-Code auszuführen, der vom Server definiert und nach Ajax-Anfragen zurückgeschickt wird. JSF unterstützt nun mit <f:validateWholeBean> Bean Validation auf Klassenlevel. Das ist hilfreich, wenn die Validierung nicht nur Informationen von separaten Feldern, sondern verschiedene Felder auf einmal benötigt. Wie andere Spezifikationen auch, unterstützt JSF nun Java-8-Date-Time-Typen. Der Tag <f:convertDateTime> kann nun auch entsprechende Typen in Text und zurück wandeln.

Lesen Sie auch: Die Zukunft von Java EE sieht rosig aus: Das sagen die Experten

Fazit

Java EE 8 geht in ähnlicher Richtung weiter wie schon Java EE 7, indem es Entwicklern die Arbeit einfacher macht und die Benutzung der verschiedenen APIs und Spezifikationen weiter vereinheitlicht. Vor allem die voranschreitende Integration mit CDI verbessert die Benutzung und den Code in Projekten. Was ebenfalls die Plattform vorantreibt, ist die umfassende Integration von Java-SE-8-Features. Alle Expert Groups legen viel Wert darauf, dass Entwickler die Möglichkeiten der neuesten Java-Version so weit wie möglich nutzen können.

Verwandte Themen:

Geschrieben von
Sebastian Daschner
Sebastian Daschner
Sebastian Daschner arbeitet als freiberuflicher Java Consultant, Softwareentwickler bzw. -architekt und programmiert begeistert mit Java (EE). Er nimmt am Java Community Process teil, ist in der JSR 370 Expert Group vertreten und entwickelt an diversen Open-Source-Projekten auf GitHub. Er ist ein Java Champion und arbeitet seit über 6 Jahren mit Java. Darüber hinaus benutzt Sebastian auch intensiv Linux und Containertechnologien wie Docker. Er evangelisiert Java- und Programmierthemen unter https://blog.sebastian-daschner.com und auf Twitter unter @DaschnerS.
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.