Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Quarkus
  3. Développer une extension Quarkus
Extrait - Quarkus Développer des applications microservices en Java pour le cloud et Kubernetes
Extraits du livre
Quarkus Développer des applications microservices en Java pour le cloud et Kubernetes Revenir à la page d'achat du livre

Développer une extension Quarkus

Build versus Runtime

Après avoir écrit une application en Java, il faut la construire en un artefact qui, en fonction de la cible de déploiement, peut être un JAR ou une image native. 

En Java, la construction d’une application se fait via la compilation avec javac, puis le packaging avec Maven ou Gradle.

Cette phase de construction, appelée build, peut être définie « comme toutes les actions faites à partir du code source de l’application pour le convertir en un exécutable qui est soit un JAR, soit une image native ».

Ces actions sont le plus souvent la compilation, le traitement des annotations, la génération du bytecode...

Le runtime est la phase de démarrage puis d’exécution de l’application.

Au démarrage de l’application, il y a généralement beaucoup de choses qui se passent : chargement des librairies et des fichiers de configuration, scan du classpath, injection des dépendances, configuration des frameworks utilisés (ORM, JAX-RS...), instanciation des classes...

Le plus souvent, les frameworks démarrent au runtime ; c’est ce que l’on appelle la phase de bootstrapping d’un framework.

Cela a les conséquences suivantes :

  • Crée un délai à la disponibilité de l’application.

  • Consomme beaucoup de ressources au démarrage...

Les trois phases de bootstrapping

Il y a trois phases distinctes de bootstrapping d’une application Quarkus :

images/14EP01.png
  • Augmentation : pendant le build, les extensions Quarkus chargeront et analyseront le bytecode de votre application (y compris les dépendances) et sa configuration. À ce stade, une extension peut lire les fichiers de configuration, analyser les classes, lire des annotations spécifiques, etc. C’est la phase de collecte des métadonnées de votre application qui permettra ensuite aux extensions de prétraiter les actions de démarrage des frameworks (bootstrapping). Le « résultat » de cette phase sera directement enregistré en bytecode.

  • Static Init : pendant le build pour les images natives, sinon au runtime, Quarkus exécutera une méthode d’initialisation statique qui contient des actions et/ou configurations d’extensions. Le « résultat » de cette phase sera directement enregistré en bytecode.

  • Runtime Init : exécution classique du démarrage d’une application.

Plus vous exécutez de code au cours des deux premières phases, plus votre application démarrera rapidement. Même si la phase Static Init est réalisée au runtime, elle est préparée au build grâce aux mêmes techniques que lors de la phase d’Augmentation...

Steps et items

À chacune des trois phases de bootstrapping, une extension peut exécuter des build steps (autrement dit, des étapes) qui vont produire ou consommer des build items (des éléments en français).

Chaque extension va fournir deux modules Maven :

  • deployment : contient les steps et les items de l’extension. Uniquement utilisé au build, ce module ne sera pas inclus dans le packaging final de l’application. 

  • runtime : contient l’API de l’extension si elle en fournit une, ses dépendances (via son fichier pom.xml), les producers CDI et, si nécessaire, un recorder. Un recorder est un objet permettant d’enregistrer du bytecode lors de la construction de l’application, bytecode qui sera ensuite rejoué au démarrage de l’application.

Chaque extension va contenir dans son module deployment l’ensemble des étapes indispensables à la réalisation des trois phases de bootstrapping du framework que l’extension intègre. Ces étapes, appelées build steps, sont des méthodes annotées par @BuildStep.

Quarkus va ensuite ordonner puis exécuter tous les build steps de toutes les extensions.

Un build item est une classe qui étend io.quarkus.builder.item. BuildItem et qui représente une information passée d’une étape de build à une autre....

Jandex

Jandex est un indexeur de fichiers .class de Java. Il va créer un index pour le code de votre application et permettre d’effectuer des opérations de recherche dans le code de l’application telles que celles-ci :

  • Parcourir et rechercher des annotations.

  • Parcourir et rechercher des déclarations et des types, y compris des informations de type générique.

  • Parcourir et rechercher dans la hiérarchie d’héritage des classes et des interfaces.

Quarkus va créer un index des classes de votre application qui sera disponible dans chaque build step. Cela permet de remplacer l’usage traditionnel du scan de classpath et de la réflexion qui sont lents et obligent le chargement des métadonnées des classes. L’utilisation de Jandex sera plus rapide que la réflexion et aura une empreinte mémoire plus faible.

Certaines extensions peuvent ajouter des classes relatives à l’extension à l’index Jandex. Il est aussi possible de créer un index pour des librairies externes ; ceci est expliqué dans le chapitre Développement d’applications avec Quarkus, section Bases : configuration, logs, injection de dépendances et tests.

Plusieurs build items permettent d’accéder à l’index de Jandex, dont les suivants :

  • ApplicationIndexBuildItem : permet d’accéder à...

Développer une extension pas à pas

Pour créer une extension, la première étape est de générer la structure de l’extension. Pour cela, nous allons utiliser le plugin Maven de Quarkus qui permet de créer une extension que nous allons nommer chapitre-14-extension.

La commande suivante va permettre de créer l’extension et ses modules Maven runtime et deployment :

mvn io.quarkus.platform:quarkus-maven-plugin:2.16.1.Final:
create-extension -N \ 
    -DgroupId=fr.loicmathieu.eni.quarkus \ 
    -DextensionId=chapitre-14-extension \ 
    -DwithoutTests 

-DgroupId permet de configurer le groupId des deux modules de l’extension, --extensionId permet de configurer le nom de l’extension et -DwithoutTests évite la génération des tests. Les tests d’une extension ne seront pas expliqués dans ce livre.

À la racine de l’extension se trouveront un fichier pom.xml parent et les deux modules Maven runtime et deployment.

Dans le module deployment, il y aura un processeur qui contiendra un build step permettant de définir le nom de l’extension :

class Chapitre14ExtensionProcessor { 
    private static final String FEATURE = "chapitre14-extension"; 
 
    @BuildStep 
    FeatureBuildItem feature() { 
        return new FeatureBuildItem(FEATURE); 
    } 
} 

Dans le module runtime, il n’y aura pour l’instant qu’un fichier quarkus-extension.yaml dans le répertoire src/main/resources. Ce fichier permet de configurer les métadonnées de l’extension.

L’extension peut être construite et installée localement via mvn clean install

Pour utiliser l’extension, il faut l’ajouter à votre application via sa dépendance Maven runtime :

<dependency> 
  <groupId>fr.loicmathieu.eni.quarkus</groupId> 
  <artifactId>chapitre-14-extension</artifactId> 
  <version>1.0.0-SNAPSHOT</version> 
</dependency> 

Au démarrage de l’application, on pourra vérifier que l’extension...