{"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\/informatique\/quarkus-tip-comment-ne-pas-creer-une-extension-quarkus\/","title":{"rendered":"Quarkus Tip: How NOT to create a Quarkus extension"},"content":{"rendered":"<p>When you develop an application composed of several components, it is frequent to want to share some code in an external library, for example via an external JAR integrated as a dependency of your components.<\/p>\n<p>Quarkus is an extension framework, each extension it offers allows to integrate a technology (BDD client, ORM framework, &#8230;) to Quarkus, so it can be configured globally, used easily via CDI (dependency injection), work with GraalVM, &#8230;<\/p>\n<p>Quarkus has its own build system, via its Maven or Gradle plugin, which allows to deport to build time the bootstarting of your application via an extension. So it would be a natural fit to share the common code to several components developed with Quarkus via an extension.<\/p>\n<p>But creating an extension is complicated and requires advanced skills on the internal functioning of Quarkus. Except if you need advanced features as described in the <a href=\"https:\/\/quarkus.io\/guides\/writing-extensions\" title=\"extension writing guide\" rel=\"noopener\" target=\"_blank\">extension writing guide<\/a>, it is often enough to create a &#8220;standard&#8221; JAR with the technique described in the rest of this post.<\/p>\n<p>So we will create a standard JAR via a classical Maven module; the only specificity is that for the code of this JAR to be &#8220;discovered&#8221; by Quarkus, it must be indexed by Jandex. <a href=\"https:\/\/github.com\/wildfly\/jandex\" title=\"Jandex\" rel=\"noopener\" target=\"_blank\">Jandex<\/a> is used by Quarkus to discover your application&#8217;s code at build time via indexing your application&#8217;s code, instead of discovering it at runtime via more standard mechanisms such as classpath scanning and reflection.<\/p>\n<p>Quarkus will automatically index the code of our application, but not of its dependencies, so we will add the Maven Jandex plugin to create an index of the code of our common JAR when packaging it by 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>Now, we will be able to write code that will be discovered by Quarkus: for example, provide CDI beans that we can then inject into our application code.<\/p>\n<p>Let&#8217;s take for example the creation of a client for Consul based on the <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>The first step is to create a class representing the client&#8217;s configuration, for this we will use the <a href=\"https:\/\/quarkus.io\/guides\/config-mappings\" title=\"Config Mapping\" rel=\"noopener\" target=\"_blank\">Config Mapping<\/a> principle: an interface that represents your configuration items:<\/p>\n<pre>\n@ConfigMapping(prefix = \"consul\")\ninterface ConsulConfig {\n    String host();\n    int port();\n}\n<\/pre>\n<p>This class can have a default configuration that is found in the <code>META-INF\/microprofile.properties<\/code> file, this file is automatically discovered by the Quarkus configuration system in each JAR of the classpath.\nYou can override this configuration if necessary in the <code>application.properties<\/code> file of your application.<\/p>\n<pre>\nconsul.host=localhost\nconsul.port=8500\n<\/pre>\n<p>We can then write a CDI producer based on your configuration class to produce a Consul client as a CDI bean that can be injected into your application code:<\/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>The CDI producers are CDI beans, so they must be declared via a CDI annotation.<\/li>\n\n<li>The config mapping that defines the configuration of our Consul client is injected into our producer.<\/li>\n\n<li>The methods producing CDI beans must be annotated with <code>@Produces<\/code>.<\/li>\n\n<li>Here we want to produce a bean of scope <code>@ApplicationScoped<\/code>.<\/li>\n\n<li>We create the Consul client configuration from the config mapping injected into our producer.<\/li>\n\n<li>We create the Consul client and return it.<\/li>\n<\/ol>\n<p>Once this JAR is packaged, we just need to add it as a dependency to our application, and then set the properties that need to be set in our <code>application.properties<\/code> file (it will override the one in the <code>microprofile.properties<\/code> file from the common JAR) :<\/p>\n<pre>\nconsul.host=my.consul.host\n<\/pre>\n<p>Finally, we can inject the Consul client bean into our application code, here a REST endpoint (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>Here, the Consul client is injected into our JAX-RS endpoint, and then used in the <code>getFromConsul()<\/code> method to retrieve a key value from Consul and return it to the user.<\/p>\n<p>I mentioned it at the beginning of the article, one of the most classic features provided by an extension, is the support of the GraalVM native image compilation. Even if you can do a more advanced configuration via an extension, you can still do it via a simple common JAR providing a list of classes to register for reflection via the <a>@RegisterForReflection<\/code>code&gt;@RegisterForReflection&lt;\/code<\/a> annotation.\nHere is an example that register 3 dummy classes for reflection (this step is not necessary for our Consul client):<\/p>\n<pre>\n@RegisterForReflection(targets={ FirstClass.class, SecondClass.class, ThridClass})\npublic class NativeImageReflectiveConfiguration {\n}\n<\/pre>\n<p>One can also directly provide standard GraalVM configurations via <a href=\"https:\/\/www.graalvm.org\/reference-manual\/native-image\/BuildConfiguration\/#embedding-a-configuration-file\" title=\"standard GraalVM configuration files\" rel=\"noopener\" target=\"_blank\">standard configuration files<\/a> or via <a href=\"https:\/\/blog.frankel.ch\/solving-substitution-graalvm-issue\/\" title=\"substitutions\" rel=\"noopener\" target=\"_blank\">substitutions<\/a>.<\/p>\n<p>And that&#8217;s how <strong>not<\/strong> to create a Quarkus extension.\nIf you insist on wanting to create one, you can watch <a href=\"https:\/\/www.youtube.com\/watch?v=b8G01WK8Q9U&amp;list=PLg0UT5MZOM_YUqJAsLox1U7cZrpfAGD5B&amp;index=1&amp;t=6s\" title=\"Talk Creating a Quarkus Extension at Devoxx FR 2021\" rel=\"noopener\" target=\"_blank\">my talk on done at Devoxx FR 2021<\/a> on the subject ;) (french only).<\/p>","protected":false},"excerpt":{"rendered":"<p>When you develop an application composed of several components, it is frequent to want to share some code in an external library, for example via an external JAR integrated as a dependency of your components. Quarkus is an extension framework, each extension it offers allows to integrate a technology (BDD client, ORM framework, &#8230;) to Quarkus, so it can be configured globally, used easily via CDI (dependency injection), work with GraalVM, &#8230; Quarkus has its own build system, via its&#8230;<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/quarkus-tip-comment-ne-pas-creer-une-extension-quarkus\/\"> Read More<span class=\"screen-reader-text\">  Read More<\/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\/informatique\/quarkus-et-les-google-cloud-functions\/","url_meta":{"origin":1353,"position":0},"title":"Quarkus and  the Google Cloud Functions","author":"admin","date":"Tuesday November  2nd, 2021","format":false,"excerpt":"Quarkus is a microservice framework designed for the cloud and the containers. It is designed to have a reduced memory usage and the shortest possible startup time. It is mainly based on standards (Jakarta EE, Eclipse MicroProfile, ...) and allows the use of mature and widespread Java libraries via its\u2026","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1560,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/quarkus-tip-tester-une-fonction-google-cloud\/","url_meta":{"origin":1353,"position":1},"title":"Quarkus Tip: Testing a Google Cloud function","author":"admin","date":"Thursday December 29th, 2022","format":false,"excerpt":"I recently contributed a PR to Quarkus that contains a testing framework for Google Cloud functions. Quarkus supports creating Google Cloud functions three different ways: Using the Google Cloud API. Using a Quarkus HTTP extension: RESTEasy, Reactive routes, Servlet, Spring Web. Using Funqy, the cloud provider agnostic Quarkus function API.\u2026","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2089,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/deploy-a-quarkus-application-in-cloud-run\/","url_meta":{"origin":1353,"position":2},"title":"Deploy a Quarkus application in Cloud Run","author":"admin","date":"Tuesday December 30th, 2025","format":false,"excerpt":"Quarkus is a microservice development framework designed for the cloud and containers. It is designed to have reduced memory usage and the shortest possible startup time. It is mainly based on standards (Jakarta EE, Eclipse MicroProfile, etc.) and allows the use of mature and widely used Java libraries via its\u2026","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1960,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/creer-un-chatbot-avec-google-gemini-vertex-ai-et-quarkus\/","url_meta":{"origin":1353,"position":3},"title":"Creating a chatbot with Google Gemini Vertex AI and Quarkus","author":"admin","date":"Friday June 27th, 2025","format":false,"excerpt":"I recently created a Quarkus extension that provides access to Google Vertex AI. In this article, I'm going to use this extension to create a chatbot. The first step is to create a Quarkus project containing the REST and Google Cloud Vertex AI extensions. Here are the extensions to add\u2026","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/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\/informatique\/quarkus-et-testcontainers\/","url_meta":{"origin":1353,"position":4},"title":"Quarkus and Testcontainers","author":"admin","date":"Monday February 17th, 2020","format":false,"excerpt":"If you did not know Quarkus, here is an introductory article: Zoom sur Quarkus (french). Quarkus offers Unit Test (TU) support with JUnit 5 via the @QuarkusTest annotation, documentation for Quarkus TU support can be found here. Here is an example of a TU from the Hibernate ORM Quickstart :\u2026","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1326,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/quarkus-tip-selectionner-un-bean-au-runtime\/","url_meta":{"origin":1353,"position":5},"title":"Quarkus Tip : Select a bean at runtime","author":"admin","date":"Friday October 15th, 2021","format":false,"excerpt":"When developing an application, it is very common to have several implementations of a servicen and to have to select one or the other depending on the environment on which it is deployed. A classic example: a service that calls an API of an external partner that we want to\u2026","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/posts\/1353","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/comments?post=1353"}],"version-history":[{"count":0,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/posts\/1353\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/media?parent=1353"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/categories?post=1353"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/tags?post=1353"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}