Welche Einstellung haben Sie? Anwendungskonfiguration mit MicroProfile Config

MicroProfile (https://microprofile.io/) enthält u. a. den Baustein Microprofile Config, mit dem JEE-Anwendungen aus verschiedenen Quellen heraus Konfigurationsparameter erhalten können. Neben einem API stehen auch Injektionsmöglichkeiten zur Verfügung.

Configuration API

MicroProfile Config ist durch Vorläufer-Projekte wie Apache Tamaya oder DeltaSpike Config beeinflusst und besitzt diverse Implementierungen wie SmallRye Config im WildFly. Zum portablen Zugriff auf den konkreten Provider dient die Klasse ConfigProvider und das Interface Config. Im einfachsten Fall kann ein Konfigurationswert so erfragt werden:

Config config = ConfigProvider.getConfig();
String value = config.getValue("java.version", String.class);

Config Sources

Die Konfigurationswerte werden diesen Quellen entnommen (in absteigender Priorität):

  • System Properties
  • Environment Variables
  • Classpath resource(s) META-INF/microprofile-config.properties

Nach Wunsch können die Prioritäten angepasst und zusätzliche Konfigurationsquellen ergänzt werden.

Injektion von Konfigurationswerten

Für die bequeme Nutzung in CDI Beans steht der Qualifier @ConfigProperty zur Verfügung:

@Inject
@ConfigProperty(name = "answer")
int answer;

Sollte eine solche Property-Referenz nicht befriedigt werden, d. h. sollte es im konkreten Beispiel keinen konfigurierten Wert mit dem Namen answer geben, schlägt das Deployment der Anwendung fehl. Ist das nicht erwünscht, kann als Injektionsziel ein Optional genutzt werden:

@Inject
@ConfigProperty(name = "HOME")
Optional home;

Plattformen

MicroProfile Config wird u. a. von folgenden JEE-Servern unterstützt:

  • OpenLiberty (mit aktiviertem Feature mpConfig-1.3).
  • Payara.
  • WildFly.

Die genannten Klassen befinden sich bspw. in der Maven-Dependency org.eclipse.microprofile.config:microprofile-config-api (derzeit in Version 1.3).

Demo

In https://github.com/GEDOPLAN/microprofile-demo/tree/master/microprofile-config finden Sie ein Beispielprojekt mit einem REST-Service, der API-Nutzung und Injektionsmöglichkeiten zeigt. Die Anwendung kann als WAR-File auf einen der genannten Server deployt werden. Alternativ können über vorkonfigurierte Maven-Profile Docker-Images zum direkten Ausprobieren erstellt werden.

Bis bald – vielleicht auch in einem unserer Trainings in Berlin, Bielefeld, Köln oder bei Ihnen!
https://gedoplan-it-training.de/

Werbeanzeigen

Unterhaus weiterhin einig im Nicht-entscheiden – droht jetzt der harte Pexit?

Das britische Parlament hat das Austrittsabkommen zum dritten Mal abgelehnt. Bis zum 12. April muss geklärt werden, wie es weitergehen soll. Droht jetzt auch für den beliebten JEE-Server Payara der Pexit, d. h. die Abschottung vom Rest der Welt?

Der Server wird von der Payara Services Ltd in Malvern, United Kingdom, angeboten und als Open Source Software entwickelt. Könnte bei einem Pexit ohne Deal Entwicklern aus dem restlichen Europa der freie Zugang zum Quellcode entzogen werden?

Auf der Payara-Webseite finden sich Aussagen wie „Always Open Source“, „Public open source development“ und „encouraging users’ involvement“, aber lassen sich diese vor dem Hintergrund der entscheidungsunfähigen Politik noch halten?

Payara hat neben dem Hauptsitz auch ein Office in Portugal. Vielleicht lassen sich Downloads, Contributions und Service Requests zukünftig über dieses europäische Büro abwickeln.

Die letzten Entscheidungen stehen noch aus; hoffentlich kann Payara doch noch in der Community verbleiben!

Übrigens: Wir bieten unsere JEE-Kurse auch auf Payara an und das vermittelte Wissen ist garantiert nicht vom britischen Parlament abhängig. Schauen Sie doch mal vorbei: https://gedoplan-it-training.de/.

Transaktionssteuerung mit @Transactional

Transaktionen sind nötig, um Daten atomar, konsistent, isoliert und dauerhaft bearbeiten und speichern zu können (ACID-Prinzip). Methoden von CDI-Beans können durch eine simple Annotation mit einem aktiven Transaktionskontext versehen werden.

Transaktionsinterceptor mit dem Binding @Transactional

Schon seit der Version 1.1 von CDI steht ein global aktivierter Transaktionsinterceptor zur Verfügung. Er wird mit der Annotation @Transactional einer Methode einer CDI-Bean zugeordnet:

public class SomeService {
  ...
  @Transactional
  public void doSomethingTransactionally() {
    ...
  }

Beim Aufruf der Methode ohne aktive Transaktion wird nun eine Transaktion gestartet und nach dem Verlassen der Methode wieder geschlossen. Die Regeln für das Transaktionsende sind etwas seltsam:

  • Endet die Methode mit einem Return, wird ein Commit versucht.
  • Wirft die Methode eine sog. System Exception, resultiert dies in einem Rollback. System Exceptions sind i. W. die unchecked Exceptions (ergänzt um die RemoteException, die aber explizit kaum eine Rolle spielt).
  • Wirft die Methode eine Application Exception – das sind alle anderen Exeptions – wird ein Commit (!) versucht.

Insbesondere der letzte Punkt ist (zumindest mir) unverständlich: Für mich modellieren Exceptions immer Ausnahmesituationen, die den jeweiligen Geschäftsprozess ungültig machen. Glücklicherweise kann man mit einem Parameter der Annotation auch in diesem Fall ein Rollback ansteuern:

  @Transactional(rollbackOn=Exception.class)
  public void doSomethingTransactionally() {

Transaktionsmodus

Die Art der Transaktionssteuerung durch @Transactional kann mit dem Parameter value bestimmt werden:

  • TxType.REQUIRED ist der Default, der in den allermeisten Fällen passend ist. Beim Aufruf einer davon betroffenen Methode wird geprüft, ob bereits eine aktive Transaktion vorliegt. Wenn ja, wird diese für den Methodenaufruf genutzt. Andernfalls wird eine neue Transaktion gestartet und am Methodenende wieder beendet.
  • TxType.REQUIRES_NEW startet bei Methodenbeginn stets eine neue Transaktion, die am Methodenende wieder beendet wird. Eine ggf. bereits aktive Transaktion wird zuvor suspendiert. Dieser Modus sollte dann verwendet werden, wenn die Ergebnisse des Methodenaufrufs auch dann dauerhaft abgespeichert werden sollen, wenn die umgebende Transaktoin zurückgerollt wird. Beispiel: Auditing/Protokollierung von Methodenaufrufen.
  • TxType.MANDATORY verlangt eine aktive Transaktion bei Methodenbeginn und wirft andernfalls eine TransactionRequiredException. Dieser Modus ist könnte prinzipiell für Repositories (a.k.a DAOs) interessant sein, da deren feingranulare Methoden i. A. von einem Service aufgerufen werden, der selbst transaktional ist. Leider werden Lifecycle-Methoden (@PostConstruct-annotierte Methoden etc.) nicht durch die @Transactional-Interceptoren intercepted. Häufig werden darin Repository-Methoden aufgerufen. Dann sollte für Repositories wie auch bei anderen Services TxType.REQUIRED verwendet werden.
  • Die weiteren Modi TxType.NOT_SUPPORTED, TxType.SUPPORTS und TxType.NEVER sind i. A. unbrauchbar.

Danke für’s Lesen und bis bald – vielleicht auch in einem unserer Trainings in Berlin, Bielefeld, Köln oder bei Ihnen!
https://gedoplan-it-training.de/