{"id":1353,"date":"2021-11-16T12:29:36","date_gmt":"2021-11-16T11:29:36","guid":{"rendered":"https:\/\/www.loicmathieu.fr\/wordpress\/?p=1353"},"modified":"2021-11-16T14:36:59","modified_gmt":"2021-11-16T13:36:59","slug":"quarkus-tip-comment-ne-pas-creer-une-extension-quarkus","status":"publish","type":"post","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/quarkus-tip-comment-ne-pas-creer-une-extension-quarkus\/","title":{"rendered":"Quarkus Tip : Comment NE PAS cr\u00e9er une extension Quarkus"},"content":{"rendered":"<p>Quand on d\u00e9veloppe une application compos\u00e9e de plusieurs composants, il est fr\u00e9quent de vouloir partager du code dans une librairie externe, par exemple via un JAR externe int\u00e9gr\u00e9 comme une d\u00e9pendance de vos composants.<\/p>\n<p>Quarkus est un framework d&rsquo;extension, chaque extension qu&rsquo;il propose permet d&rsquo;int\u00e9grer une technologie (client BDD, framework ORM, &#8230;) \u00e0 Quarkus, pour qu&rsquo;elle puisse \u00eatre configur\u00e9e globalement, utilis\u00e9e facilement via CDI (injection de d\u00e9pendances), fonctionner avec GraalVM, &#8230;<\/p>\n<p>Quarkus a son propre syst\u00e8me de build, via son plugin Maven ou Gradle, qui permet de d\u00e9porter au build une partie du d\u00e9marrage de votre application via une extension. Il serait donc naturel de partager le code commun \u00e0 plusieurs composants d\u00e9velopp\u00e9s avec Quarkus via une extension.<\/p>\n<p>Hors, cr\u00e9er une extension est compliqu\u00e9 et n\u00e9cessite des comp\u00e9tences pouss\u00e9es sur le fonctionnement interne de Quarkus. A part si vous avez besoin de fonctionnalit\u00e9s pouss\u00e9es telles que d\u00e9crites dans le <a href=\"https:\/\/quarkus.io\/guides\/writing-extensions\" title=\"guide d'\u00e9criture des extensions\" rel=\"noopener\" target=\"_blank\">guide d&rsquo;\u00e9criture des extensions<\/a>, il est souvent suffisant de cr\u00e9er un JAR \u00ab\u00a0standard\u00a0\u00bb avec la technique d\u00e9crite dans la suite de ce billet.<\/p>\n<p>Nous allons donc cr\u00e9er un JAR standard via un module Maven tout ce qu&rsquo;il y a de plus classique ; la seule sp\u00e9cificit\u00e9 est que pour que le code de ce JAR soit \u00ab\u00a0d\u00e9couvert\u00a0\u00bb par Quarkus, il faut qu&rsquo;il soit index\u00e9 par Jandex. <a href=\"https:\/\/github.com\/wildfly\/jandex\" title=\"Jandex\" rel=\"noopener\" target=\"_blank\">Jandex<\/a> est utilis\u00e9 par Quarkus pour d\u00e9couvrir le code de votre application au build via une indexation du code de votre application, au lieu de le d\u00e9couvrir au runtime via des m\u00e9canismes plus standard tel que le scan de classpath et la r\u00e9flexion.<\/p>\n<p>Quarkus va automatiquement indexer le code de votre application, mais pas de ses d\u00e9pendances, on va donc ajouter le plugin Maven Jandex pour cr\u00e9er un index du code de votre JAR commun lors du packaging de celui-ci par Maven :<\/p>\n<pre>\n\n  \n    \n      org.jboss.jandex\n      jandex-maven-plugin\n      1.2.1\n      \n        \n          make-index\n          \n            jandex\n          \n        \n      \n    \n  \n\n<\/pre>\n<p>Maintenant, nous allons pouvoir \u00e9crire du code qui sera d\u00e9couvert par Quarkus : par exemple, fournir des beans CDI que l&rsquo;on pourra ensuite injecter dans notre code applicatif.<\/p>\n<p>Prenons par exemple la cr\u00e9ation d&rsquo;un client pour Consul bas\u00e9 sur le <a href=\"https:\/\/github.com\/rickfast\/consul-client\" title=\"Consul Client for Java\" rel=\"noopener\" target=\"_blank\">Consul Client for Java<\/a>.<\/p>\n<p>La premi\u00e8re \u00e9tape consiste \u00e0 cr\u00e9er une classe repr\u00e9sentant la configuration du client, pour cela, on va utiliser le principe du <a href=\"https:\/\/quarkus.io\/guides\/config-mappings\" title=\"Config Mapping\" rel=\"noopener\" target=\"_blank\">Config Mapping<\/a> : une interface qui repr\u00e9sente vos options de configurations :<\/p>\n<pre>\n@ConfigMapping(prefix = \"consul\")\ninterface ConsulConfig {\n    String host();\n    int port();\n}\n<\/pre>\n<p>Cette classe peut avoir une configuration par d\u00e9faut que se retrouve dans le fichier <code>META-INF\/microprofile.properties<\/code>, ce fichier est automatiquement d\u00e9couvert par le syst\u00e8me de configuration de Quarkus dans chaque JAR du classpath.\nVous pourrez ensuite surcharger cette configuration si n\u00e9cessaire dans le fichier <code>application.properties<\/code> de votre application.<\/p>\n<pre>\nconsul.host=localhost\nconsul.port=8500\n<\/pre>\n<p>On peut ensuite \u00e9crire un producer CDI qui se basera sur votre classe de configuration pour produire un client Consul comme un bean CDI injectable dans le code de votre application :<\/p>\n<pre>\n@ApplicationScoped \/\/ 1\npublic class ConsulClientProducer {\n    @Inject ConsulConfig config; \/\/ 2\n\n    @Produces \/\/ 3\n    @ApplicationScoped \/\/ 4\n    public Consul consulClient() {\n        HostAndPort hostPort = HostAndPort.fromParts(config.host(), config.port());\/\/ 5\n        return Consul.builder().withHostAndPort(hostPort).build(); \/\/ 6\n    }\n}\n<\/pre>\n<ol><li>Les producers CDI sont des beans CDI, ils doivent donc \u00eatre d\u00e9clar\u00e9s via une annotation CDI.<\/li>\n\n<li>Le config mapping qui d\u00e9finit la configuration de notre client Consul est inject\u00e9 dans notre producer.<\/li>\n\n<li>Les m\u00e9thodes produisant des beans CDI doivent \u00eatre annot\u00e9es par <code>@Produces<\/code>.<\/li>\n\n<li>Ici on veut produire un bean de scope <code>@ApplicationScoped<\/code>.<\/li>\n\n<li>On cr\u00e9e la configuration du client Consul depuis le config mapping inject\u00e9 dans notre producer.<\/li>\n\n<li>On cr\u00e9e le client Consul et on le retourne.<\/li>\n<\/ol>\n<p>Une fois ce JAR packag\u00e9, il suffit de l&rsquo;ajouter comme d\u00e9pendance \u00e0 notre application, puis de configurer les propri\u00e9t\u00e9s qui doivent l&rsquo;\u00eatre dans notre fichier <code>application.properties<\/code> (elle surchargeront celle du fichier <code>microprofile.properties<\/code> du JAR commun) :<\/p>\n<pre>\nconsul.host=my.consul.host\n<\/pre>\n<p>Pour finir, nous pouvons injecter le bean du client Consul dans notre code application, ici un endpoint REST (JAX-RS) :<\/p>\n<pre>\n@Path(\"\/\")\npublic class HelloConsulEndpoint {\n    @Inject Consul consulClient;\n\n    @GET\n    public String getFromConsul() {\n        KeyValueClient kvClient = consulClient.keyValueClient();\n        return kvClient.getValueAsString(\"foo\").get(); \n    }\n}\n<\/pre>\n<p>Ici, le client Consul est inject\u00e9 dans notre endpoint JAX-RS, puis utilis\u00e9 dans la m\u00e9thode <code>getFromConsul()<\/code> pour r\u00e9cup\u00e9rer la valeur d&rsquo;une cl\u00e9 depuis Consul et la retourner \u00e0 l&rsquo;utilisateur.<\/p>\n<p>J&rsquo;en ai parl\u00e9 en d\u00e9but d&rsquo;article, une des fonctionnalit\u00e9 les plus classique fournie par une extension, est le support de la compilation native GraalVM. M\u00eame si on peut en faire une plus pouss\u00e9e via une extension, on peut quand m\u00eame via un simple JAR commun fournir une liste de classe \u00e0 enregistrer pour r\u00e9flexion via l&rsquo;annotation <a>@RegisterForReflection<\/code>code&gt;@RegisterForReflection&lt;\/code<\/a>.\nVoici un exemple qui enregistrer 3 classes fictives pour r\u00e9flexion (cette \u00e9tape n&rsquo;est pas n\u00e9cessaire pour notre client Consul) :<\/p>\n<pre>\n@RegisterForReflection(targets={ FirstClass.class, SecondClass.class, FictiveClass})\npublic class NativeImageReflectiveConfiguration {\n}\n<\/pre>\n<p>On peut aussi fournir directement les configurations GraalVM standard via les <a href=\"https:\/\/www.graalvm.org\/reference-manual\/native-image\/BuildConfiguration\/#embedding-a-configuration-file\" title=\"fichiers de configuration standard GraalVM\" rel=\"noopener\" target=\"_blank\">fichiers de configuration standard<\/a> ou via des <a href=\"https:\/\/blog.frankel.ch\/solving-substitution-graalvm-issue\/\" title=\"substitutions\" rel=\"noopener\" target=\"_blank\">substitutions<\/a>.<\/p>\n<p>Et voil\u00e0 comment <strong>ne pas<\/strong> cr\u00e9er une extension Quarkus.\nSi vous insistez \u00e0 vouloir en cr\u00e9er une, vous pouvez regarder <a href=\"https:\/\/www.youtube.com\/watch?v=b8G01WK8Q9U&amp;list=PLg0UT5MZOM_YUqJAsLox1U7cZrpfAGD5B&amp;index=1&amp;t=6s\" title=\"Talk Cr\u00e9er une extension Quarkus \u00e0 Devoxx FR 2021\" rel=\"noopener\" target=\"_blank\">mon talk sur fait \u00e0 Devoxx FR 2021<\/a> sur le sujet ;)<\/p>","protected":false},"excerpt":{"rendered":"<p>Quand on d\u00e9veloppe une application compos\u00e9e de plusieurs composants, il est fr\u00e9quent de vouloir partager du code dans une librairie externe, par exemple via un JAR externe int\u00e9gr\u00e9 comme une d\u00e9pendance de vos composants. Quarkus est un framework d&rsquo;extension, chaque extension qu&rsquo;il propose permet d&rsquo;int\u00e9grer une technologie (client BDD, framework ORM, &#8230;) \u00e0 Quarkus, pour qu&rsquo;elle puisse \u00eatre configur\u00e9e globalement, utilis\u00e9e facilement via CDI (injection de d\u00e9pendances), fonctionner avec GraalVM, &#8230; Quarkus a son propre syst\u00e8me de build, via son&#8230;<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/quarkus-tip-comment-ne-pas-creer-une-extension-quarkus\/\">Lire la suite<span class=\"screen-reader-text\"> Lire la suite<\/span><\/a><\/p><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[9],"tags":[11,167],"class_list":["post-1353","post","type-post","status-publish","format-standard","hentry","category-informatique","tag-java","tag-quarkus"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":1345,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/quarkus-et-les-google-cloud-functions\/","url_meta":{"origin":1353,"position":0},"title":"Quarkus et les  Google Cloud Functions","author":"admin","date":"mardi  2 novembre 2021","format":false,"excerpt":"Quarkus est un framework de d\u00e9veloppement de microservice pens\u00e9 pour le cloud et les conteneurs. Il est pens\u00e9 pour avoir une utilisation m\u00e9moire r\u00e9duite et un temps de d\u00e9marrage le plus court possible. Il se base principalement sur des standards (Jakarta EE, Eclipse MicroProfile, \u2026) et permet l'utilisation de librairies\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1560,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/quarkus-tip-tester-une-fonction-google-cloud\/","url_meta":{"origin":1353,"position":1},"title":"Quarkus Tip : Tester une fonction Google Cloud","author":"admin","date":"jeudi 29 d\u00e9cembre 2022","format":false,"excerpt":"J'ai r\u00e9cemment contribu\u00e9 une PR \u00e0 Quarkus qui contient un framework de test pour les fonctions Google Cloud. Quarkus supporte la cr\u00e9ation de fonction Google Cloud de trois mani\u00e8res diff\u00e9rentes : En utilisant l'API de Google Cloud. En utilisant une extension HTTP de Quarkus : RESTEasy, Reactive routes, Servlet, Spring\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2089,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/deployer-une-application-quarkus-dans-cloud-run\/","url_meta":{"origin":1353,"position":2},"title":"D\u00e9ployer une application Quarkus dans Cloud Run","author":"admin","date":"mardi 30 d\u00e9cembre 2025","format":false,"excerpt":"Quarkus est un framework de d\u00e9veloppement de microservice pens\u00e9 pour le cloud et les conteneurs. Il est pens\u00e9 pour avoir une utilisation m\u00e9moire r\u00e9duite et un temps de d\u00e9marrage le plus court possible. Il se base principalement sur des standards (Jakarta EE, Eclipse MicroProfile, \u2026) et permet l\u2019utilisation de librairies\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1960,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/creer-un-chatbot-avec-google-gemini-vertex-ai-et-quarkus\/","url_meta":{"origin":1353,"position":3},"title":"Cr\u00e9er un chatbot avec Google Gemini Vertex AI et Quarkus","author":"admin","date":"vendredi 27 juin 2025","format":false,"excerpt":"J'ai r\u00e9cemment cr\u00e9\u00e9 une extension Quarkus qui permet d'acc\u00e9der \u00e0 Google Vertex AI. Dans cet article, je vais utiliser cette extension pour cr\u00e9er un chatbot. La premi\u00e8re \u00e9tape consiste \u00e0 cr\u00e9er un projet Quarkus contenant les extensions REST et Google Cloud Vertex AI. Voici les extensions \u00e0 ajouter \u00e0 votre\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/Capture-decran-du-2025-06-27-14-22-26-1024x376.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/Capture-decran-du-2025-06-27-14-22-26-1024x376.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/Capture-decran-du-2025-06-27-14-22-26-1024x376.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":1005,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/quarkus-et-testcontainers\/","url_meta":{"origin":1353,"position":4},"title":"Quarkus et Testcontainers","author":"admin","date":"lundi 17 f\u00e9vrier 2020","format":false,"excerpt":"Si vous ne connaissait pas Quarkus, voici un article d'introduction : Zoom sur Quarkus. Quarkus offre un support des Tests Unitaires (TU) avec JUnit 5 via l'annotation @QuarkusTest, la documentation du support des TU de Quarkus peut \u00eatre trouv\u00e9 ici. Voici un exemple de TU tir\u00e9 du Quickstart Hibernate ORM\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1326,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/quarkus-tip-selectionner-un-bean-au-runtime\/","url_meta":{"origin":1353,"position":5},"title":"Quarkus Tip : S\u00e9l\u00e9ctionner un bean au runtime","author":"admin","date":"vendredi 15 octobre 2021","format":false,"excerpt":"Lors du d\u00e9veloppement d'une application, il est tr\u00e8s fr\u00e9quent d'avoir plusieurs impl\u00e9mentations d'un service, et de devoir s\u00e9lectionner l'une o\u00f9 l'autre en fonction de l\u2019environnement sur lequel elle est d\u00e9ploy\u00e9e. Un exemple classique : un service qui appelle une API d'un partenaire externe qu'on veut appeler uniquement en production, et\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts\/1353","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/comments?post=1353"}],"version-history":[{"count":0,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts\/1353\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/media?parent=1353"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/categories?post=1353"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/tags?post=1353"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}