Spring Tools 4 Update

Am 22.01.2020 wurde das neue Update der beliebten Spring Tools 4 Suite veröffentlicht. Im allgemeinen sind Verbesserungen und Fehlerbeseitigung in Eclipse vorhanden. Ausnahme bildet der Hover Mechanismus, der nun auch Connection Failures anzeigen kann.

Spring Boot

  • Live hover können nun Connection Failures anzeigen

Eclipse

  • Completions werden nun asynchron durchgeführt
  • Early access builds für Eclipse 4.15 verfügbar
  • Bei der Autovervollständigung für Parameter in @Value Annotationen wurde immer ein zusätzliches NewLine eingefügt
  • Das Spring Boot Dashboard konnte Projekte die ein Leerzeichen enthalten nicht starten
  • Eine NPE in PropertiesJavaDefinitionHandler.adjustedHighlightRangeForKey wurde gefixt
  • Neueste m2e Snapshot um Probleme mit JUnit 5 Tests zu beseitigen

Spring Tool Suite

Mit dem neuen Release 4.3.0 von Spring Tool Suite, ist Pivotal wieder gut gelungen.

Neuerungen

Neben dem Update auf Eclipse 2019-06 (Release News) sind auch wieder jede Menge Bugfixes dabei (Changelog).

Änderungen in STS4

Theia ist nun in die Liste der offiziell unterstützten Editoren aufgenommen worden. Dafür wurde die Unterstützung für ATOM (ab Spring Tools 4.3.0) gestrichen und ist nun kein unterstützter Client mehr.

Spring Boot

  • Verbesserung: Die Startugeschwindigkeit wurde durch Optimierung der Classpath Meldungen verbessert
  • Verbesserung: Symbole werden neu erstellt, wenn ein abhängiger Typ sich ändert
  • Bugfix: Langsame Codevervollständigung (mehr als eine Sekunde) wurde behoben
  • Bugfix: Der Content-Assisten für Spring XML funktioniert nun auch wieder in VS Code und Theia Editoren
  • Bugfix: Ein ClassCast Exception in dem Spring Boot LanguageServer wurde behoben
  • Bugfix: Anonyme Inner Types hatten keine Boot Hints

Eclipse

  • Bugfix: Das schelle neustarten einer Anwendung im Boot Dashboard erzeugt keine Fehler mehr
  • Bugifx: Merkwürdige Exceptions beim Löschen einer CF Anwendung, wenn der SSH Tunnel noch aktiv war, wurde behoben

Sichern einer Anwendung mit Spring Security 5.0

1. Hinzufügen der Dependencies

"org.springframework.boot:spring-boot-starter-sercurity",
"org.springframework.security:spring-security-oauth2-resource-server"

Mit dem Hinzufügen der Dependency spring-boot-starter-sercurity werden automatisch alle Endpoints gesichert.

Es muss spring-security-oauth2-resource-server Libary eingebunden werden, damit die Anwendung mit JWT encoded Barear Token gesichert werden kann. Dieses muss deklariert werden, dann verwandelt sich die Anwendung in einen Resource Server. Wenn ein Authorization Header in einem Request vorhanden und in diesem Barear Schema und das Token vorhanden ist, dann wird das JWT geparst und festgestellt ob der Request authorisiert war oder nicht.

2. Anpassen der application.yaml

Die application.yaml muss angepasst werden. Es muss die URI angegeben werden wo der uaa Server läuft. Hier in diesem Beispiel läuft der Server auf dem Localhost auf Port 8090.

   security:
     oauth2:
       resourceserver:
         jwt:
           issuer-uri: http://localhost:8090/uaa/oauth/token 

Beim Starten der Anwendung werden von der standarisierten URI http://localhost:8090/uaa/oauth/token/.well-known/openid-configuration weitere Konfigrationseinstellungen geladen. In den Konfigurationseinstellungen wird u.a. auch die URI für jwks-Token angegeben.

Über die URI (http://localhost:8090/uaa/token_keys) kann der PublicKey geladen werden, um z.B. die Signierung durch den Authorisationsserver zu überprüfen und ob das Token seit der Generierung im Server modifiziert worden ist.

Damit ist die minimale Konfiguration abgeschlossen, um die Anwendung in einen Resourceserver zu verwandeln.

Exkurs: JWT

JWT (jawt ausgesprochen) steht für JSON Web Token. Auf jwt.io gibt es einen Decoder der die beide Teile Header und Payload base64 decodiert und als JSON darstellt. Im Header wird der Algorythmus und der Typ (z.B. JWT) angegeben. In der Payload können die Attribute (hier Claims genannt) übertragen werden. JWT wird als Bearer Token im HTTP Authorization Header übertragen. Der Header und die Payload wird als Singnatur mit RSASHA256 angehangen.

UAA

OAuth Authorization Code FLow

Resource Owner –> Application –> Authorization Server –> Resource Server

  1. Der Resource Owner (Hier der Anwender) fragt bei der Application an.
  2. Die Application frag den Anwender nach den Rechten. Dieser gewährt der Anwendung diese.
  3. Die Authentifizierung und die Authorisierung werden an den Authorisationsserver geschickt.
  4. Der Authorisationsserver schickt der Anwendung einen Authorisationscode (OTC) zu. Dieser ist kurzlebig.
  5. Nun tauscht die Anwendung den OTC Code zusammen mit den Client Credentials (Das ist die Authentifizierung der Anwendung) mit dem Authorisationsserver für das Token aus.
  6. Der Authorisationsserver antwortet mit dem Token für die Anwendung.
  7. Nun kann die Anwendung mit dem Token auf den Resource Server nach einer Resource anfragen.
  8. Der Resource Server schickt nach Validierung des Tokens die angeforderte Resource an die Anwendung.

Das Token ist mächtig und daher verbleit es im Backend der Anwendung und wird somit geschützt. Sollte das Token offengelegt (geleakt) werden, so hat man den vollen Zugriff auf die API mit Rechten des Anwenders. Deshalb sollte die Gültigkeit des Token nur kurz sein und es regelmäßig aktualisiert werden.

OAuth Client Credentials Flow

Spring Tools 4.4.2

Es ist mal wieder eine neue Version von den Spring Tools 4 erschienen.

  • Verbesserung: Neue actions um connect,refresh,disconnect live hover Informationen von laufenden Spring Boot Projecten zu steuern. Diese sind nun auch in den Boot Dashboard Menüs vornahen
  • Verbesserung: Über das Kontextmenü sind weitere Voreinstellungen für live hover möglich
  • Verbesserung: Die Console-View kann nun mit der Dashboard Auswahl verknüpft werden
  • Fehlerbehebung: Live hover werden wieder bei neueren Versionen von Spring Boot angezeigt, wenn sie auf CF deployt worden sind
  • Fehlerbehebung: Für Properties Keys wurde die Sortierung in @Value Annotationparametern gefixt

Weitere Änderungen

Wie immer habe ich hier nicht alle Änderugen aufgeführt. Diese könnt ihr auf der Release Info sehen.

Custom Starter

Spring Boot beinhaltet eigene Starter. Ein Starter ist eine Sammlung von Dependencys die aufeinander abgestimmt sind. Diese werden über das Dependency Management von dem Parent POM bzw. über ein Gradle Plugin mit den passenden Versionen verwaltet. So kann man sehr einfach und fehlerfrei Dependencys in eine Spring Boot Anwendung einbringen.

Nun bietet Spring Boot aber nicht für alle 3rd Party Libraries einen Spring Boot Starter. Es werden aber (nach Pull Request) auf der GitHub Seite Custom Starters gelistet.

Spring-Boot-CLI Tools

Spring Boot bietet auch ein Kommandozeilewerkzeug. Die Installation unter Manjaro erfolgt mit

yaourt --noconfirm -S spring-boot-cli

sehr schnell.

Password encoden

Nun kann mit dem spring Kommando einen Hash für ein Passwort schnell auf der Kommandozeile erstellen:

$ spring encodepassword meinGeheimesPasswort
{bcrypt}$2a$10$ip/Y7fBiC4Eh7vyvltUuruJnUpZeDD44JU8rbrvFfV94QIIzZkFKm

Spring Tools 4.4.1

Am 24.10.2019 ist die neue Version der Spring Tools 4.4.1 erschienen. Neben Bugs die behoben worden sind, gibt es Änderungen bei den Live Informationen (s.u.).

Spring Boot

  • In Eclipse funktioniert nun das Goto Symbol auch in XML Bean Dateien
  • Der Fehler das in der Autovervollständigung in der application.properties manchmal Zeichenmüll hinterlässt wurde behoben
  • Die Performance für das Scannen der XML Symbole wurde verbessert
  • CVE-2019-18212 und CVE-2019-18213 wurden behoben

Live Data anzeigen

Mit Spring Boot 2.2 wurde das JMX per default abgeschaltet. D.h. möchte man weiterhin die Liveinformationen der Anwendung angezeigt bekommen, so muss man JMX Actuator Endpoint wieder mit -Dspring.jmx.enabled=true aktivieren. Ab Spring Tools 4.2.0 wird der in Eclipse integrierte Spring Boot Lauch Configuration diese Einstellung automatisch setzen, so dass das alte Verhalten wiederhergestellt ist und die Live Informationen abgerufen werden können.

Core API revision

Java 8 basierend

Die gesamte Codebasis wird seit 5.0 auf Java 8 umgestellt. Dieses wurde nun weiter vorangetrieben. Teilweise jetzt erst wirklich auf Java 8 umgestellt.

Java 8 API Typen

Rückgabetypen wurden Stream, Duration, Instant, Executable und so weiter eingeführt.

Interfaces mit Defaultmethoden

Interfaces nutzen nun Default Methoden, um neue Funktionen bereitzustellen ohne dabei die Rückwärtskompatabilität zu brechen.

Nullability

In der gesamten Codebasis werden alle Methoden mit @NonNull oder @Nullable deklariert. Dadurch können die IDEs wie Eclipse und IntelliJ die Interaktion mit dem Spring Framework validieren. Viele der vorhandenen Null Checks konnten somit in dem Spring Framework entfernt werden.

Eigene APIs die auf Spring Framework Rückgabewerten basieren sollten nun auch von den Annotationen Gebrauch machen und somit im allgemeinen den Code von weiteren Null Checks befreien.

Performance Tuning

Component Scanning

Das Scannen des gesammten Classpath beim Programmstart kann viel Zeit in Anspruch nehmen. Dabei werden alle Klassen nach der Annotation @ComponentScan durchsucht. Im allgemeinen wird man die Startupzeit durch Angabe eines base packages verkürzen, da nicht mehr alle Klassen durchsucht werden müssen. Alternativ kann ein Scanning auch komplett verhindert werden, in dem man alle Komponentenklassen aufzählt.

Seit Spring Framework 5 kann man einen Annotationsprozessor zur Kompilierzeit verwenden (spring-context-indexer). Dieser erstellt eine META-INF/spring.components per JAR. Diese wird automatisch zur Laufzeit ausgewertet.

Component Model

Am effizientesten werden Komponenten in einer reinen Funktionalen Methode registriert. Dadurch entfällt das Component Scanning und es wird auch kein Reflection für die Factory Methoden verwendet. Ferner werden auch keine Annotationśkonfigurationen (Annotationpostprocessor) verwendet.

ProxyBeanMethods

Mit @Configuration(proxyBeanMethos=false) kann nun verhindert werden dass zur Laufzeit CGLIB Subklassen erzeugt werden. Dieses wird für die Imageerstellung mit der GraalVM benötigt.

Nachteil: Kein Abfangen von Cross @Bean Calls mehr möglich!

3rd Party Libs

Spring Boot Data unterstützen spring.data.jpa.repositories.bootstrap-mode=deferred. Damit werden der ORM Hibernate lazy initialisiert. Das ist ein nicht unerheblicher Anteil der Startupzeit einer Spring Anwendung. Die Initialisierung wird nun bei dem Ersten Zugriff durchgeführt.

Hibernate wurde auf 5.4.5 aktualisiert, welches interne Performance Steigerungen und weniger Speicherverbrauch zur Folge hat. Desweiteren wurde der Umgang mit Bytecode verbessert (Voraussetzung für lazy loading).

Jackson wurde auf mindesten 2.9.7 angehoben. Auch hier wurde die Startupzeit sowie die Responsezeit beim parsen von JSON verbessert.

Nur durch die Anhebung des Spring / Spring Boot Frameworks lassen sich Performancesteigerungen also erzielen.

GraalVM

Die Verwendung der GraalVM ist bereits seit Spring Framework 5.1 in Vorbereitung. Es werden unnötige interne Reflection vermieden. Nun ist in der Zwischenzeit set Spring Framework 5.1 das 19 GA von GraalVM erschienen. Spring Framework 5.2 kann mit native Image verwendet werden, aber es müssen die explizite Reflection Konfiguration und benötigte Kommandozeilenparameter angegeben werden damit ein Image erzeugt werden kann. Ziel der Entwicklung für Spring Framework 5.3 ist ein automatisches Setup (ootb) der Reflection Einstellungen durch eine Custom Graal Konfiguration zu ermöglichen.

Neues in Spring Data

In Spring Data Moore Release gibt es wieder jede Menge neues. Einiges davon stelle ich kurz in diesem Artikel vor. Einen großen Anteil hat die reaktive Programmierung inne.

Reaktives Transactional

Um Methoden Transaktionssicher zu machen, genügt es nun wie man es aus der imperativen Programmierung von Spring Data kennt die Annotation @Transactional an der Methode zu annotieren.

@Transactional
public Mono<Type> doSomething(Long id) {
    return repo.findById(id);
}

Elasticsearch reaktiv

Auch Elasticsearch hat eine reaktive API bekommen.

Die Vorteile der Reaktiven Programmierung sind das die Ergebnismenge nicht auf einmal in den Speicher geladen werden muss und sobald die ersten Daten bereitstehen werden sie im Flux zur Weiterverarbeitung bereitgestellt. Dieses ist besonders bei großen Datenmengen von Vorteil.

Es muss nur die Konfiguration vorgenommen werden. Der Typ ReactiveElasticsearchClient basiert auf dem WebClient.

class Config extends AbstractReaktiveElasticsearchConfiguration {
    @Bean
    @Override
    public ReactiveElasticsearchClient reactiveClient() {
        return ReactiveRestClients.create(localhost());
    }
} 

Nun kann das Template für die Abfrage genutzt werden. Als Ergebnis erhält man einen Flux.

@Autowired
ReactiveElasticsearchTemplate template;

// Query bauen
Criteria criteria = new Criteria("thema").contains("natur");
CriteriaQuery query = new CriteriaQuery(criteria);

// komplett reaktiv 
Flux<Dokument> result = template.find(query, Dokument.class);

Alternativ kann man Spring Data typisch eine reaktives Repository erstellen und Derived Queries darauf anwenden.

interface TestRepo extends ReactiveCrudRepository<...> {
     Flux<Dokument> findAllByKeywords(...);
}

@Autowired
TestRepo repo;

Flux<Dokument> result = repo.findAllByKeywords("natur");

Reactive QueryDSL

interface TestRepo extends ..., ReactiveQuerydslPredicateExecutor<...> {}

@Autowired
TestRepo repo;

//...
Predicate predicate = QCustomer.customer.lastname.eq("Pfau");
Flux<Customer> result = repo.findAll(predicate);

Performance in Spring Data

Eine Neuentwicklung sind die spring-data-dev-tools. Diese erlauben es JMH Benchmarks in JUnit Tests auszuführen. JMH dient als Messinstrument für die Performanceoptimierung in Spring Data.

Hier die Ergebnisse der Optimierungen zwischen RC1 und RC2:

Methode RC1 RC2 % Steigerung
findAll 52.213 61.244 17%
findByTitle 74.192 123.040 66%
repositoryByTitle 70.344 120.333 71%
repositoryByTitleDeclared 65.236 111.760 71%