{"id":1090,"date":"2020-05-29T13:42:57","date_gmt":"2020-05-29T11:42:57","guid":{"rendered":"https:\/\/www.loicmathieu.fr\/wordpress\/?p=1090"},"modified":"2020-05-29T13:51:18","modified_gmt":"2020-05-29T11:51:18","slug":"quarkus-jlink-et-application-class-data-sharing-appcds","status":"publish","type":"post","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/quarkus-jlink-et-application-class-data-sharing-appcds\/","title":{"rendered":"Quarkus, jlink et Application Class Data Sharing (AppCDS)"},"content":{"rendered":"<p>Quarkus est optimis\u00e9 pour d\u00e9marrer rapidement et avoir une empreinte m\u00e9moire tr\u00e8s faible. Ceci est vrai en d\u00e9ployant dans une JVM standard mais encore plus en d\u00e9ployant notre application comme un ex\u00e9cutable natif via GraalVM.<\/p>\n<p>Quarkus facilite grandement la cr\u00e9ation d\u2019ex\u00e9cutable natif, gr\u00e2ce \u00e0 \u00e7a, une application Quarkus d\u00e9marre en quelques dizaines de millisecondes et avec une empreinte m\u00e9moire tr\u00e8s faible : quelques dizaines de Mo de RSS (Resident Set Size &#8211; totale d&rsquo;utilisation de m\u00e9moire du processus Java vu par l&rsquo;OS).<\/p>\n<p>Si on reprend la comparaison disponible sur le graphique ci-dessous, on passe, pour une stack classique REST JSON \/ Hibernate, de 2s de temps de d\u00e9marrage \u00e0 42ms et de 145 Mo de RSS \u00e0 28 Mo. Et encore, avec un seul c\u0153ur ! \u00c0 titre d&rsquo;exemple, mon application <code>bookmark-service<\/code> de mon Dojo Quarkus <a href=\"https:\/\/github.com\/loicmathieu\/bookmarkit\" target=\"_blank\" rel=\"noopener noreferrer\">bookmarkit<\/a> d\u00e9marre en 1,2s sur mon laptop.<\/p>\n<img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-1091\" src=\"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/quarkus_metrics_graphic_bootmem_wide.png?resize=640%2C296&#038;ssl=1\" alt=\"\" width=\"640\" height=\"296\" srcset=\"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/quarkus_metrics_graphic_bootmem_wide.png?resize=1024%2C473&amp;ssl=1 1024w, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/quarkus_metrics_graphic_bootmem_wide.png?resize=300%2C139&amp;ssl=1 300w, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/quarkus_metrics_graphic_bootmem_wide.png?resize=768%2C355&amp;ssl=1 768w, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/quarkus_metrics_graphic_bootmem_wide.png?resize=1536%2C710&amp;ssl=1 1536w, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/quarkus_metrics_graphic_bootmem_wide.png?resize=2048%2C946&amp;ssl=1 2048w, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/quarkus_metrics_graphic_bootmem_wide.png?resize=584%2C270&amp;ssl=1 584w, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/quarkus_metrics_graphic_bootmem_wide.png?w=1280&amp;ssl=1 1280w, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/quarkus_metrics_graphic_bootmem_wide.png?w=1920&amp;ssl=1 1920w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/>\n<p>Un autre point non mentionn\u00e9, est la taille de l&rsquo;image Docker. Une application native ne contiendra que le code utilis\u00e9 par l&rsquo;application (gr\u00e2ce au dead code \u00e9limination de GraalVM), ainsi qu&rsquo;une JVM minimaliste (SubstrateVM), et sera donc plus petite qu&rsquo;une image standard qui embarque l&rsquo;int\u00e9gralit\u00e9 des librairies tierces ainsi qu&rsquo;une JVM compl\u00e8te.<\/p>\n<p>Mais, d\u00e9ployer son application Quarkus comme une application native a quelques inconv\u00e9nients :<\/p>\n<ul><li>A cause du <em>close world assumption<\/em> de GraalVM, il faut que toutes les librairies utilis\u00e9es soient compatibles GraalVM. Ceci est garantie pour les extensions Quarkus, mais pour les autres, c&rsquo;est \u00e0 vous de v\u00e9rifier, et il peut parfois y avoir de mauvaises surprises.<\/li>\n\n<li>SubstrateVM est une JVM partielle, elle ne supporte ni JMX ni JVM-TI (et donc pas d&rsquo;agents Java), ce qui peut grandement complexifier le monitoring et l&rsquo;administration de votre application.<\/li>\n\n<li>Une application native a des performances en pointe qui sont inf\u00e9rieures \u00e0 une application d\u00e9ploy\u00e9e dans la JVM. Principalement parce que le Just-In-Time Compiler (le JIT) de Java va profiler votre application lors de son utilisation et pourra donc effectuer des optimisations plus pertinentes que GraalVM qui r\u00e9alise ces optimisations \u00e0 la compilation (compilateur Ahead-Of-Time &#8211; AOT).<\/li>\n<\/ul>\n<p>Si vous voulez d\u00e9ployer votre application Quarkus dans une JVM standard, mais optimiser son temps de d\u00e9marrage et la taille de l&rsquo;image Docker, alors <strong>Jlink<\/strong> et <strong>AppCDS<\/strong> peuvent vous aider !<\/p>\n<p>Dans les paragraphes suivants, je vais utiliser l&rsquo;application <a href=\"https:\/\/github.com\/loicmathieu\/bookmarkit\/tree\/master\/bookmark-service\" target=\"_blank\" rel=\"noopener noreferrer\">bookmark-service<\/a> comme exemple. Une JVM 11 minimum est n\u00e9cessaire (j&rsquo;ai utilis\u00e9 OpenJDK 11.0.5).<\/p>\n<h2>Jlink<\/h2>\n<p><strong>Jlink<\/strong> permet de g\u00e9n\u00e9rer une JVM customis\u00e9e qui ne contiendra que les modules n\u00e9cessaires au fonctionnement de votre application. Ceci est rendu possible gr\u00e2ce \u00e0 la modularisation du JDK qui a \u00e9t\u00e9 faite pour Java 9 (<a href=\"https:\/\/openjdk.java.net\/projects\/jigsaw\/spec\/\" target=\"_blank\" rel=\"noopener noreferrer\">JSR-376<\/a> &#8211; projet Jigsaw). Qui dit taille r\u00e9duite de JVM, dit image Docker plus petite !<\/p>\n<p><strong>Jlink<\/strong> prend en entr\u00e9e la liste des modules \u00e0 inclure dans votre JVM customis\u00e9e. Pour connaitre cette liste, il faut utiliser l&rsquo;outil <strong>jdeps<\/strong>.<\/p>\n<p>Tout d&rsquo;abord, il faut configurer Quarkus pour g\u00e9n\u00e9rer un fat jar (ou uber jar) pour que <strong>jdeps<\/strong> puisse analyser tout le code de votre application. Pour ce faire, il faut ajouter la propri\u00e9t\u00e9 suivante dans votre <code>application.properties<\/code> :<\/p>\n<pre><code>quarkus.package.uber-jar=true<\/code><\/pre>\n<p>On package ensuite l&rsquo;application via <code>mvn clean package<\/code>.<\/p>\n<p>Puis on lance la commande <strong>jdeps<\/strong> avec l&rsquo;option <code>--list-deps<\/code> qui permet de lister les modules dont votre application d\u00e9pend.<\/p>\n<p>Voici le r\u00e9sultat de la commande <strong>jdeps<\/strong> avec le uber jar de l&rsquo;application <code>bookmark-service<\/code> :<\/p>\n<pre><code>$ jdeps --list-deps target\/bookmark-service-1.0-SNAPSHOT-runner.jar \n   JDK removed internal API\/org.relaxng.datatype\n   java.base\/sun.security.util\n   java.base\/sun.security.x509\n   java.compiler\n   java.datatransfer\n   java.desktop\n   java.instrument\n   java.logging\n   java.management\n   java.naming\n   java.rmi\n   java.security.jgss\n   java.security.sasl\n   java.sql\n   java.transaction.xa\n   java.xml\n   jdk.jconsole\n   jdk.management\n   jdk.unsupported\n<\/code><\/pre>\n<p>Pour cr\u00e9er une JVM customis\u00e9e, il faut utiliser <strong>jlink<\/strong> en lui donnant la liste des modules r\u00e9sultants de l&rsquo;appel \u00e0 la commande <strong>jdeps<\/strong> via l&rsquo;option <code>-add-modules<\/code>. Petite subtilit\u00e9, les deux modules <code>java.base\/sun.security.util<\/code> et <code>java.base\/sun.security.x509<\/code> ne doivent pas \u00eatre int\u00e9gr\u00e9es, mais on doit int\u00e9grer le module <code>java.base<\/code> \u00e0 la place. Je ne sais pas d&rsquo;o\u00f9 vient cette incoh\u00e9rence de r\u00e9sultat de la commande <strong>jdeps<\/strong>, mais le module <code>java.base<\/code> est utilis\u00e9 par toute application Java, donc il doit syst\u00e9matiquement \u00eatre pr\u00e9sent.<\/p>\n<p>Pour l&rsquo;application <code>bookmark-service<\/code>, voici la commande <strong>jlink<\/strong> que j&rsquo;ai utilis\u00e9 :<\/p>\n<pre><code>$ jlink --no-header-files --no-man-pages --output target\/customjdk --compress=2 --strip-debug\n--module-path $JAVA_HOME\/jmods --add-modules java.base,java.base,java.base,java.compiler,\njava.datatransfer,java.desktop,java.instrument,java.logging,java.management,java.naming,\njava.rmi,java.security.jgss,java.security.sasl,java.sql,java.transaction.xa,\njava.xml,jdk.jconsole,jdk.management,jdk.unsupported\n<\/code><\/pre>\n<p>Comme je voulais avoir une JVM la plus petite possible, j&rsquo;ai ajout\u00e9 les options suivantes \u00e0 la commande <strong>jlink<\/strong> :<\/p>\n<ul><li><code>--no-header-files<\/code> : Ne pas inclure les fichiers header,<\/li>\n\n<li><code>--no-man-pages<\/code> : Ne pas inclure les pages de manuel,<\/li>\n\n<li><code>--compress=2<\/code> : Compression de niveau ZIP pour les fichiers compressibles,<\/li>\n\n<li><code>--strip-debug<\/code> : Ne pas inclure les informations de debug.<\/li>\n<\/ul>\n<p>Apr\u00e8s cela, on peut utiliser la JVM g\u00e9n\u00e9r\u00e9e dans le r\u00e9pertoire <code>target\/customjdk<\/code> pour lancer notre application :<\/p>\n<pre><code>$ target\/customjdk\/bin\/java -Xmx32m -jar target\/bookmark-service-1.0-SNAPSHOT-runner.jar\n<\/code><\/pre>\n<p>Si on compare le d\u00e9marrage de notre application avec notre JVM customis\u00e9e et la JVM standard, il n&rsquo;y a pas d&rsquo;avantage au RSS ni au temps de d\u00e9marrage. Le seul int\u00e9r\u00eat est la taille de la JVM qui est pass\u00e9e de 314Mo \u00e0 51Mo !<\/p>\n<p>Id\u00e9alement, il faudrait automatiser \u00e7a dans votre build Docker via un Dockerfile multi-stage &#8230;<\/p>\n<p>Pour aller plus loin sur <strong>jlink,<\/strong> je vous invite \u00e0 consulter cet article : <a href=\"https:\/\/medium.com\/azulsystems\/using-jlink-to-build-java-runtimes-for-non-modular-applications-9568c5e70ef4\" target=\"_blank\" rel=\"noopener noreferrer\">Using jlink to build java runtimes for non modular applications<\/a>.<\/p>\n<h2>AppCDS &#8211; Application Class Data Sharing<\/h2>\n<p>Attention : si vous voulez utiliser <strong>AppCDS<\/strong> avec <strong>jlink<\/strong>, il faudra utiliser la JVM customis\u00e9e dans les commandes de ce paragraphe au lieu de votre JVM par d\u00e9faut.<\/p>\n<p>Une des raisons du temps de d\u00e9marrage cons\u00e9quent d&rsquo;une application Java, est que, pour chaque classe, la JVM doit la charger depuis le disque, la v\u00e9rifier, puis cr\u00e9er une structure de donn\u00e9es sp\u00e9cifique (class metadata).<\/p>\n<p>Application Class Data Sharing (AppCDS) est une fonctionnalit\u00e9 via laquelle on peut cr\u00e9er une archive des metadatas de nos classes, pour \u00e9viter de le faire au d\u00e9marrage. Une fois ces metadatas charg\u00e9s, il n&rsquo;y a aucune diff\u00e9rence de comportement avec une application n&rsquo;utilisant pas AppCDS.<\/p>\n<p>L&rsquo;utilisation d&rsquo;<strong>AppCDS<\/strong> se fait en trois \u00e9tapes :<\/p>\n<p><strong>Etape 1<\/strong> : Cr\u00e9ation de la liste de classes \u00e0 archiver.<\/p>\n<pre><code>java -XX:DumpLoadedClassList=target\/classes.lst -jar target\/bookmark-service-1.0-SNAPSHOT-runner.jar\n<\/code><\/pre>\n<p>J&rsquo;ai arr\u00eat\u00e9 l&rsquo;application juste apr\u00e8s son lancement, mais on peut imaginer l&rsquo;utiliser un peu plus longtemps (lancement de test fonctionnel par exemple) pour s&rsquo;assurer que tout le code de l&rsquo;application ait bien \u00e9t\u00e9 appel\u00e9, et donc que le plus de classes possible seront list\u00e9es.<\/p>\n<p><strong>Etape 2<\/strong> : G\u00e9n\u00e9ration de l&rsquo;archive en utilisant l&rsquo;option JVM <code>-Xshare:dump<\/code> qui demande \u00e0 <strong>AppCDS<\/strong> de la cr\u00e9er.<\/p>\n<pre><code>java -Xshare:dump -XX:SharedClassListFile=target\/classes.lst -XX:SharedArchiveFile=target\/app-cds.jsa --class-path target\/bookmark-service-1.0-SNAPSHOT-runner.jar\n<\/code><\/pre>\n<p>Cette commande ne lance pas l&rsquo;application. Elle va seulement g\u00e9n\u00e9rer un fichier <code>app-cds.jsa<\/code> de 69Mo qu&rsquo;on pourra ensuite utiliser pour lancer notre application.<\/p>\n<p><strong>Etape 3<\/strong> : On lance l&rsquo;application en lui passant l&rsquo;archive cr\u00e9\u00e9e.<\/p>\n<pre><code>java -XX:SharedArchiveFile=target\/app-cds.jsa -jar target\/bookmark-service-1.0-SNAPSHOT-runner.jar\n<\/code><\/pre>\n<p>Avec une archive, l&rsquo;application se lance en 500ms au lieu de 1,2s, ce qui fait <strong>-60% de temps de d\u00e9marrage<\/strong> !<\/p>\n<p>On n&rsquo;a h\u00e9las, pas de diff\u00e9rence au niveau empreinte m\u00e9moire.<\/p>\n<p>Pour aller plus loin : <a href=\"https:\/\/blog.codefx.org\/java\/application-class-data-sharing\/\" target=\"_blank\" rel=\"noopener noreferrer\">Application Class Data Sharing<\/a>.<\/p>\n<h2>Conclusion<\/h2>\n<p><strong>Jlink<\/strong> permet de r\u00e9duire tr\u00e8s fortement la taille de votre image Docker. Si vous d\u00e9ployez votre application comme un conteneur Docker et que vous ne ma\u00eetrisez pas forc\u00e9ment le n\u0153ud sur lequel elle est d\u00e9ploy\u00e9e (cloud publique ou cloud priv\u00e9 partag\u00e9 avec d&rsquo;autres applications), cela peut \u00eatre int\u00e9ressant pour limiter le temps de t\u00e9l\u00e9chargement de celle-ci. Attention par contre \u00e0 bien penser \u00e0 re-cr\u00e9er votre JVM customis\u00e9e \u00e0 chaque fois que vous ajoutez une nouvelle librairie car celle-ci pourrait utiliser un module absent de votre pr\u00e9c\u00e9dente JVM customis\u00e9e.<\/p>\n<p><strong>AppCDS<\/strong> me semble tr\u00e8s int\u00e9ressant, il r\u00e9duit tr\u00e8s fortement le temps de d\u00e9marrage de votre application sans aucun inconv\u00e9nient autre que n\u00e9cessiter la cr\u00e9ation de l&rsquo;archive de classes au pr\u00e9alable. Par contre, la cr\u00e9ation de cette archive n&rsquo;est pas triviale, mais au vu de l&rsquo;optimisation (-60%) \u00e7a vaut le coup !<\/p>\n<p>Un remerciement tout sp\u00e9cial \u00e0 Logan pour sa relecture et la correction des nombreuses fautes d\u2019orthographe \ud83d\ude09<\/p>","protected":false},"excerpt":{"rendered":"<p>Quarkus est optimis\u00e9 pour d\u00e9marrer rapidement et avoir une empreinte m\u00e9moire tr\u00e8s faible. Ceci est vrai en d\u00e9ployant dans une JVM standard mais encore plus en d\u00e9ployant notre application comme un ex\u00e9cutable natif via GraalVM. Quarkus facilite grandement la cr\u00e9ation d\u2019ex\u00e9cutable natif, gr\u00e2ce \u00e0 \u00e7a, une application Quarkus d\u00e9marre en quelques dizaines de millisecondes et avec une empreinte m\u00e9moire tr\u00e8s faible : quelques dizaines de Mo de RSS (Resident Set Size &#8211; totale d&rsquo;utilisation de m\u00e9moire du processus Java vu&#8230;<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/quarkus-jlink-et-application-class-data-sharing-appcds\/\">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":[184,11,185,183,159,167],"class_list":["post-1090","post","type-post","status-publish","format-standard","hentry","category-informatique","tag-appcds","tag-java","tag-jdeps","tag-jlink","tag-performance","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":1090,"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":2089,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/deployer-une-application-quarkus-dans-cloud-run\/","url_meta":{"origin":1090,"position":1},"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":1440,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/google-cloud-functions-2nd-gen\/","url_meta":{"origin":1090,"position":2},"title":"Google Cloud Functions 2nd gen","author":"admin","date":"mardi 29 mars 2022","format":false,"excerpt":"Google vient de sortir en beta la seconde g\u00e9n\u00e9ration des Google Cloud Functions. Pour ceux qui ne connaissent pas encore les Google Cloud Functions vous pouvez lire mes articles J\u2019ai test\u00e9 Java Google Cloud Functions et Quarkus et les Google Cloud Functions. Cette seconde g\u00e9n\u00e9ration apporte : Un temps de\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\/cloud-function-gen2-instances.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/cloud-function-gen2-instances.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/cloud-function-gen2-instances.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":1960,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/creer-un-chatbot-avec-google-gemini-vertex-ai-et-quarkus\/","url_meta":{"origin":1090,"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":1090,"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":1560,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/quarkus-tip-tester-une-fonction-google-cloud\/","url_meta":{"origin":1090,"position":5},"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":[]}],"_links":{"self":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts\/1090","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=1090"}],"version-history":[{"count":0,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts\/1090\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/media?parent=1090"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/categories?post=1090"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/tags?post=1090"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}