<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Retour-D'expérience on Java &amp; Moi</title><link>https://javaetmoi.com/categories/retour-dexp%C3%A9rience/</link><description>Recent content in Retour-D'expérience on Java &amp; Moi</description><generator>Hugo</generator><language>fr</language><lastBuildDate>Mon, 06 Apr 2026 13:26:43 +0000</lastBuildDate><atom:link href="https://javaetmoi.com/categories/retour-dexp%C3%A9rience/feed.xml" rel="self" type="application/rss+xml"/><item><title>Découverte de Spring Modulith</title><link>https://javaetmoi.com/2026/04/decouverte-de-spring-modulith/</link><pubDate>Mon, 06 Apr 2026 13:26:43 +0000</pubDate><guid isPermaLink="false">https://javaetmoi.com/?p=2642</guid><description>&lt;p&gt;En 2025, j’ai eu l’opportunité de mettre en place &lt;a href="https://spring.io/projects/spring-modulith"&gt;&lt;strong&gt;Spring Modulith&lt;/strong&gt;&lt;/a&gt; sur une nouvelle application web. Pour partager cette expérience avec mes collègues, j’ai préparé une démonstration live montrant comment intégrer Spring Modulith dans une application Spring Boot.&lt;/p&gt;
&lt;p&gt;J’avais besoin pour cela d’une application simple et universelle. Vous commencez à me connaitre : mon choix s’est naturellement porté sur la version canonique de &lt;strong&gt;Spring Petclinic&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Pris au jeu, j’ai progressivement enrichi l’application afin d’illustrer plusieurs fonctionnalités clés de Spring Modulith. J’ai ensuite mis ce fork à disposition de la communauté Spring Petclinic dont le code source complet est disponible sur GitHub : &lt;a href="https://github.com/spring-petclinic/spring-petclinic-modulith"&gt;spring-petclinic-modulith&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Dans ce billet, je vous propose de découvrir Spring Modulith, puis de suivre pas à pas comment l’application démo Spring Petclinic a été enrichie pour tirer parti de ses fonctionnalités.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="Bannière Spring PetClinic Modulith"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2026/04/banner-spring-petclinic-modulith.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>JSpecify + NullAway + ErrorProne : la configuration Maven ultime pour dire adieu aux NullPointerException</title><link>https://javaetmoi.com/2025/07/jspecify-nullaway-errorprone-la-configuration-maven-ultime-pour-dire-adieu-aux-nullpointerexception/</link><pubDate>Sat, 05 Jul 2025 17:06:00 +0000</pubDate><guid isPermaLink="false">https://javaetmoi.com/?p=2599</guid><description>&lt;p&gt;La gestion de la &lt;strong&gt;nullabilité&lt;/strong&gt; en Java a longtemps été source de bugs et de fragmentation.
Contrairement à Kotlin par exemple, Java ne possède pas encore nativement de moyen d’exprimer la nullité d’un type.
Qui n’aura donc jamais ragé contre une &lt;code&gt;NullPointerException&lt;/code&gt; survenue en production ? En juin 2024, avec l’arrivée de la spécification &lt;a href="https://jspecify.dev/"&gt;&lt;strong&gt;JSpecify&lt;/strong&gt;&lt;/a&gt;, soutenue par des acteurs majeurs comme Google, Microsoft, JetBrains, Oracle, Sonar ou bien encore Broadcom (Spring),
l’écosystème Java dispose enfin d’une &lt;strong&gt;bibliothèque unifiée d’annotations de nullité&lt;/strong&gt;.
Pour bénéficier d’une détection efficace des NullPointerException dès la compilation, il est nécessaire de coupler JSpecify à des outils d’analyse statique comme &lt;a href="https://github.com/uber/NullAway"&gt;&lt;strong&gt;NullAway&lt;/strong&gt;&lt;/a&gt; (Uber) et &lt;a href="https://errorprone.info/"&gt;&lt;strong&gt;ErrorProne&lt;/strong&gt;&lt;/a&gt; (Google).&lt;/p&gt;
&lt;p&gt;Ce court article explique comment mettre en place sur un projet d’entreprise la &lt;strong&gt;configuration Maven&lt;/strong&gt; correspondante qui fera casser votre build et votre CI lorsque vous essayerez de passer une variable &lt;code&gt;null&lt;/code&gt; en paramètre d’une méthode qui ne les accepte pas.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="Screenshot du site de JSpecify"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2025/07/Screenshot-site-JSpecify.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>De Spring Data JPA à jOOQ</title><link>https://javaetmoi.com/2025/06/de-spring-data-jpa-a-jooq/</link><pubDate>Mon, 16 Jun 2025 06:57:01 +0000</pubDate><guid isPermaLink="false">https://javaetmoi.com/?p=2580</guid><description>&lt;p&gt;Lors de la conférence Devoxx France 2025, j’ai participé à un hands-on lab de 2h intitulé &lt;a href="https://www.devoxx.fr/agenda-2025/talk/sortir-des-orms-avec-jooq/"&gt;Sortir des ORMs avec jOOQ&lt;/a&gt;. Acronyme de « &lt;strong&gt;Java Object Oriented Querying&lt;/strong&gt; », &lt;strong&gt;jOOQ&lt;/strong&gt; se présente comme une &lt;strong&gt;alternative à JPA&lt;/strong&gt; permettant d’ &lt;strong&gt;écrire des requêtes SQL&lt;/strong&gt; en Java via une &lt;strong&gt;fluent API&lt;/strong&gt;. Animé par Sylvain Decout et Samuel Lefebvre, cet atelier visait à migrer une application Spring Boot / JPA vers jOOQ à l’aide du &lt;strong&gt;starter Spring Boot&lt;/strong&gt; pour jOOQ. Pour les curieux, le repo de l’atelier est disponible sur Github : &lt;a href="https://github.com/sylvaindecout/jooq-handson"&gt;jooq-handson&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Fort de cette découverte, je me suis à mon tour prêté à l’exercice de migrer vers jOOQ la couche de persistance Spring Data JPA de l’application démo Spring Petclinic. Un nouveau fork est né : &lt;a href="https://github.com/spring-petclinic/spring-petclinic-jooq"&gt;&lt;strong&gt;spring-petclinic-jooq&lt;/strong&gt;&lt;/a&gt;. Bienvenue à ce dernier dans la communauté Spring Petclinic.&lt;/p&gt;
&lt;p&gt;L’usage de jOOQ se rapproche de l’utilisation de JdbcTemplate. Le développeur maitrise le nombre de requêtes envoyées à la base de données relationnelle. Ce qui les différencie, c’est la syntaxe : pas de SQL, mais une &lt;strong&gt;API Java fluide&lt;/strong&gt; et &lt;strong&gt;type-safe&lt;/strong&gt; spécifique à jOOQ qu’il va falloir appréhender. Rassurez-vous, cette API se rapproche du SQL : on y retrouve les mots clés &lt;strong&gt;select&lt;/strong&gt;, &lt;strong&gt;update&lt;/strong&gt;, &lt;strong&gt;insertInto&lt;/strong&gt;, &lt;strong&gt;where&lt;/strong&gt;, &lt;strong&gt;from&lt;/strong&gt;, &lt;strong&gt;join&lt;/strong&gt;, &lt;strong&gt;on&lt;/strong&gt;, &lt;strong&gt;as&lt;/strong&gt;… A ceux-ci, on ajoute des mots clés spécifiques à jOOQ : &lt;strong&gt;paginate&lt;/strong&gt;, &lt;strong&gt;fetch&lt;/strong&gt;, &lt;strong&gt;convertFrom&lt;/strong&gt; … La &lt;a href="https://www.jooq.org/learn/"&gt;&lt;strong&gt;documentation&lt;/strong&gt;&lt;/a&gt; de jOOQ est très &lt;strong&gt;complète&lt;/strong&gt;. On y apprend comment écrire des requêtes complexes à base de window function ou de Common Table Expressions (CTE) et comment utiliser des fonctionnalités avancées de SQL que peu de frameworks ORM supportent nativement : &lt;a href="https://www.jooq.org/doc/latest/manual/sql-building/column-expressions/json-functions/"&gt;JSON functions&lt;/a&gt;, &lt;a href="https://blog.jooq.org/how-to-use-sql-pivot-to-compare-two-tables-in-your-database/"&gt;PIVOT&lt;/a&gt;, &lt;a href="https://www.jooq.org/doc/latest/manual/sql-building/sql-statements/merge-statement/"&gt;MERGE&lt;/a&gt;, &lt;a href="https://www.jooq.org/doc/latest/manual/sql-building/sql-statements/select-statement/set-operations/set-operation-union/"&gt;UNION&lt;/a&gt; …&lt;/p&gt;
&lt;p&gt;Cet article a pour objectif d’expliquer les &lt;strong&gt;étapes&lt;/strong&gt; adoptées pour &lt;strong&gt;migrer l’implémentation Spring Data JPA des repository vers jOOQ&lt;/strong&gt;. Des exemples de code avant / après y sont proposés.&lt;/p&gt;</description></item><item><title>Les clés de l'architecture pour les dévs</title><link>https://javaetmoi.com/2025/04/cles-de-l-architecture-pour-les-devs/</link><pubDate>Tue, 22 Apr 2025 17:54:32 +0000</pubDate><guid isPermaLink="false">https://javaetmoi.com/?p=2508</guid><description>&lt;p&gt;Conférence : &lt;a href="https://www.devoxx.fr/"&gt;Devoxx France 2025&lt;/a&gt;&lt;br&gt;
Date : 17 avril 2025&lt;br&gt;
Speakers : &lt;a href="https://www.linkedin.com/in/martraire/?originalSubdomain=fr"&gt;Cyrille Martraire&lt;/a&gt; (Arolla), &lt;a href="https://www.linkedin.com/in/eric-le-merdy-bb60704/?originalSubdomain=fr"&gt;Eric Le Merdy&lt;/a&gt; (QuickSign) remplaçant de &lt;a href="https://www.linkedin.com/in/christian-sperandio-25182a12"&gt;Christian Sperandio&lt;/a&gt; (Arolla)&lt;br&gt;
Format : Conférence (45mn) / &lt;a href="https://www.youtube.com/watch?v=ZoYDxF_7LoI&amp;amp;t=528s"&gt;Replay Youtube&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cette conférence a pour &lt;strong&gt;objectif&lt;/strong&gt; d’ &lt;strong&gt;ouvrir les portes&lt;/strong&gt; en nous donnant les &lt;strong&gt;clés de l’architecture&lt;/strong&gt;. Pour seconder Cyrille, Eric a du remplacer Christian au pied levé. &lt;br&gt;
Un constat est posé. Sur les &lt;strong&gt;dix dernières années&lt;/strong&gt;, les &lt;strong&gt;systèmes&lt;/strong&gt; ont changé : ils sont devenus &lt;strong&gt;modulaires&lt;/strong&gt;, de plus en plus &lt;strong&gt;distribués&lt;/strong&gt;. La modularité permise par le Cloud permet de répartir la charge. Il y’a &lt;strong&gt;de&lt;/strong&gt; &lt;strong&gt;plus en plus d’interconnexions entre briques applicatives&lt;/strong&gt;. &lt;br&gt;
&lt;strong&gt;L’architecture bouge tout le temps&lt;/strong&gt;, évolue constamment. &lt;br&gt;
&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="Cyrille Martraire et Eric Le Merdy sur la scène de Devoxx France 2025"
class="image_figure image_external image_processed"
width="1384"
height="778"
src="https://javaetmoi.com/word-image-2508-1_8428793415211744030.jpg"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Que doit-on savoir ? Pour commencer, on ne saura jamais tout et il faudra vivre avec. Personne ne sait tout. Même le plus capé des architectes.&lt;/p&gt;
&lt;p&gt;Comme fil conducteur, Cyrille et Eric prennent un &lt;strong&gt;exemple réel&lt;/strong&gt; issu du monde des &lt;strong&gt;télécommunications&lt;/strong&gt;. &lt;br&gt;
Pour cahier des charges, le client précise que le &lt;strong&gt;système&lt;/strong&gt; va &lt;strong&gt;recevoir des fichiers chaque minute&lt;/strong&gt; et doit &lt;strong&gt;les intégrer tous les 15mn&lt;/strong&gt;. Contexte : ces fichiers viennent d’équipements télécom.&lt;/p&gt;</description></item><item><title>Spring Petclinic sous extensions Quarkus</title><link>https://javaetmoi.com/2025/04/spring-petclinic-sous-extensions-quarkus/</link><pubDate>Sun, 13 Apr 2025 16:55:14 +0000</pubDate><guid isPermaLink="false">https://javaetmoi.com/?p=2443</guid><description>&lt;p&gt;Spring et Quarkus dans le même repository Git, ou presque. Cela vous intrigue ? &lt;br&gt;Figurez-vous qu’il y’a quelques mois, la lecture du très bon &lt;strong&gt;livre &lt;a href="https://agoncal.teachable.com/p/ebook-understanding-quarkus"&gt;Understanding Quarkus 2.x&lt;/a&gt;&lt;/strong&gt; d’Antonio Gongalves m’a donné envie de pratiquer ce framework alternatif à Spring Boot. Et pour apprendre une nouvelle technologie, quoi de plus stimulant que de se fixer un objectif. Je me suis donc donné comme challenge de migrer vers Quarkus l’application démo Spring Boot que je connais bien. Une fois migrée, l’application devait rester &lt;strong&gt;iso-fonctionnelle&lt;/strong&gt;. &lt;br&gt;A travers leur repo &lt;a href="https://github.com/redhat-developer-demos/quarkus-petclinic"&gt;quarkus-petclinic&lt;/a&gt;, RedHat avait fait l’exercice avant moi. Malheureusement, l’historique Git a été écrasé, ne laissant aucune trace du chemin de migration parcouru. Pendant 3 mois, j&amp;rsquo;ai donc travaillé sur un nouveau fork que je suis fier de vous présenter : &lt;a href="https://github.com/arey/quarkus-spring-petclinic"&gt;&lt;strong&gt;quarkus-spring-petclinic&lt;/strong&gt;&lt;/a&gt;. Ajouté à la communauté Spring Petclinic, ce fork a un double objectif :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Montrer comment &lt;strong&gt;migrer une application Spring Boot 3.4 vers Quarkus 3.21&lt;/strong&gt;, avec le minium d&amp;rsquo;effort et en modifiant le moins de code possible&lt;/li&gt;
&lt;li&gt;Utiliser les &lt;strong&gt;extensions Spring&lt;/strong&gt; proposées par &lt;strong&gt;Quarkus&lt;/strong&gt; pour garder un lien avec le monde Spring tout en soulignant l&amp;rsquo;effort de l&amp;rsquo;équipe Quarkus pour supporter Spring, un framework incontournable de l&amp;rsquo;écosystème Java&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Les &lt;strong&gt;extensions Spring pour Quarkus&lt;/strong&gt; utilisées sont au nombre de quatre : &lt;strong&gt;Spring DI&lt;/strong&gt;, &lt;strong&gt;Spring Web&lt;/strong&gt;, &lt;strong&gt;Spring Data JPA&lt;/strong&gt; et &lt;strong&gt;Spring Cache&lt;/strong&gt;.&lt;br&gt;Le changement majeur aura été de porter le templating des pages HTML de &lt;strong&gt;Thymeleaf&lt;/strong&gt; vers &lt;strong&gt;Qute&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Débutant en Quarkus, le code proposé ne respecte peut-être pas toutes les règles de l’art prônées par l’équipe de dév Quarkus. Je m’en excuse par avance. Si vous voulez contribuer et corriger le tir : &lt;a href="https://github.com/spring-petclinic/quarkus-spring-petclinic/issues"&gt;issue&lt;/a&gt; et &lt;a href="https://github.com/spring-petclinic/quarkus-spring-petclinic/pulls"&gt;Pull Request&lt;/a&gt; sont les bienvenues.&lt;/p&gt;
&lt;p&gt;Le &lt;a href="https://github.com/spring-petclinic/quarkus-spring-petclinic/compare/spring-boot-version...v3.21.0"&gt;différenciel complet&lt;/a&gt; entre la version Spring Boot et la version Quarkus de Petclinic peut-être visualisé sur Github.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt=" "
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2025/04/word-image-2443-1.png"
title=" "
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Intégrer un Chatbot dans une webapp Java avec LangChain4j</title><link>https://javaetmoi.com/2024/11/integrer-un-chatbot-dans-une-webapp-java-avec-langchain4j/</link><pubDate>Mon, 11 Nov 2024 18:34:24 +0000</pubDate><guid isPermaLink="false">https://javaetmoi.com/?p=2391</guid><description>&lt;p&gt;Cet article explique comment intégrer un &lt;strong&gt;chatbot&lt;/strong&gt; utilisant l’ &lt;strong&gt;IA générative&lt;/strong&gt; dans une &lt;strong&gt;application de gestion&lt;/strong&gt; codée en &lt;strong&gt;Java&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Nous nous appuierons sur le framework Open Source &lt;a href="https://docs.langchain4j.dev/"&gt;&lt;strong&gt;LangChain4j&lt;/strong&gt;&lt;/a&gt;, une adaptation Java de la célèbre librairie python LangChain,
visant à simplifier l&amp;rsquo;intégration de grands modèles de langage ( &lt;strong&gt;LLM&lt;/strong&gt;). LangChain4j permet de créer des &lt;strong&gt;agents conversationnels&lt;/strong&gt;, des &lt;strong&gt;assistants virtuels&lt;/strong&gt; (comme notre chatbot),
ou des applications capables d&amp;rsquo;effectuer des &lt;strong&gt;analyses de texte&lt;/strong&gt; et de répondre en fonction de données contextuelles, le tout sans devoir écrire de code complexe et avec un &lt;strong&gt;haut niveau d’abstraction&lt;/strong&gt;.
Elle facilite notamment l&amp;rsquo;utilisation des API des Large Langage Model comme &lt;a href="https://docs.langchain4j.dev/integrations/language-models/open-ai"&gt;OpenAI&lt;/a&gt; et &lt;a href="https://docs.langchain4j.dev/integrations/language-models/hugging-face"&gt;Hugging Face&lt;/a&gt;,
et propose différents connecteurs pour des bases de données vectorielles, incluant &lt;a href="https://docs.langchain4j.dev/integrations/embedding-stores/elasticsearch"&gt;Elasticsearch&lt;/a&gt; et &lt;a href="https://docs.langchain4j.dev/integrations/embedding-stores/qdrant"&gt;Qdrant&lt;/a&gt;.
Pour accélérer son intégration, LangChain4j propose des extensions pour &lt;strong&gt;Quarkus&lt;/strong&gt; et des starters pour &lt;strong&gt;Spring Boot&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Pour illustrer cet article, nous utiliserons l’illustre application démo &lt;strong&gt;Spring Petclinic&lt;/strong&gt; et son récent fork dédié à LangChain4j : &lt;a href="https://github.com/spring-petclinic/spring-petclinic-langchain4j"&gt;&lt;strong&gt;spring-petclinic-langchain4j&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;Propulsé par Spring Boot, Spring Petclinic s’appuie sur &lt;strong&gt;Spring Data JPA&lt;/strong&gt; pour l’accès aux données et &lt;strong&gt;Thymeleaf&lt;/strong&gt; pour la couche présentation HTML / CSS / JavaScript.&lt;br&gt;En septembre 2024, Oded Shopen, contributeur en 2020 du fork &lt;a href="https://github.com/spring-petclinic/spring-petclinic-cloud/"&gt;Spring Petclinic Cloud&lt;/a&gt;, &lt;a href="https://spring.io/blog/2024/09/26/ai-meets-spring-petclinic-implementing-an-ai-assistant-with-spring-ai-part-i"&gt;a proposé une intégration de Spring AI dans Spring Petclinic&lt;/a&gt;. De son travail, est né le projet &lt;a href="https://github.com/spring-petclinic/spring-petclinic-ai"&gt;spring-petclinic-ai&lt;/a&gt;. Le repository &lt;a href="https://github.com/spring-petclinic/spring-petclinic-langchain4j"&gt;spring-petclinic-langchain4j&lt;/a&gt; est un &lt;strong&gt;portage&lt;/strong&gt; du framework &lt;strong&gt;&lt;a href="https://spring.io/projects/spring-ai/"&gt;Spring AI&lt;/a&gt;&lt;/strong&gt; vers &lt;strong&gt;LangChain4j&lt;/strong&gt;. Y a été ajouté notamment une fonctionnalité de &lt;strong&gt;streaming&lt;/strong&gt;.&lt;br&gt;Extraits du sample, les exemples de code s’appuient sur les versions 3.3 de Spring Boot et &lt;strong&gt;0.35.0 de LangChaing4j&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt=" "
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2024/11/langchain4j-question-llm.png"
title=" "
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Compatibilité Jakarta EE 9 de vieux frameworks</title><link>https://javaetmoi.com/2024/08/compatibilite-jakarta-ee-9-de-vieux-frameworks/</link><pubDate>Sun, 25 Aug 2024 15:54:14 +0000</pubDate><guid isPermaLink="false">https://javaetmoi.com/?p=2374</guid><description>&lt;h2 id="de-java-ee-à-jakarta-ee"&gt;De Java EE à Jakarta EE&lt;/h2&gt;
&lt;p&gt;En &lt;strong&gt;2017&lt;/strong&gt;, &lt;strong&gt;Oracle&lt;/strong&gt; a fait &lt;strong&gt;don de la spécification Java EE&lt;/strong&gt; (précédemment connu sous le nom de J2EE) à la fondation &lt;strong&gt;Eclipse&lt;/strong&gt;.
Java EE regroupe différentes API utilisées aussi bien par des serveurs d’applications, des containers de servlets et des frameworks comme Quarkus ou Spring :
&lt;strong&gt;Servlet&lt;/strong&gt;, JSP, JSF, JPA, JTA, JAX-WS, JAX-RS, JAXB, WebSocket, Bean Validation, CDI, EL … &lt;br&gt;&lt;/p&gt;
&lt;p&gt;Sous l’égide d’Eclipse, Java EE a été rebaptisé Jakarta EE. La fondation a récupéré la base de code Java et les TCK.
En &lt;strong&gt;2019&lt;/strong&gt; est sortie une version &lt;strong&gt;Jakarta EE 8&lt;/strong&gt; pleinement compatible avec Java EE 8.
Comme seul changement notable pour les dév &lt;strong&gt;, le groupId des artefacts Maven a été renommé de javax à jakarta&lt;/strong&gt;.
Le patch du numéro de version a été incrémenté. A titre d’exemple, l’artefact &lt;code&gt;jakarta.faces:jakarta.faces-api:2.3.1&lt;/code&gt; est identique à &lt;code&gt;javax.faces:javax.faces-api:2.3&lt;/code&gt;.
Pas si anodin, ce changement de GAV Maven fait que notre outil de build peut être amené, via le mécanisme de dépendances transitives,
à placer dans le classpath deux mêmes artefacts ayant des groupId différents. Les exclusions maven permettent de corriger le tir.&lt;/p&gt;
&lt;p&gt;En décembre 2020, la communauté Java est secouée par la sortie de &lt;strong&gt;Java EE 9&lt;/strong&gt;. 20 ans de rétrocompatibilité s’écroulent.
Oracle a souhaité conserver la &lt;strong&gt;marque Java&lt;/strong&gt;. Les packages &lt;code&gt;javax.*&lt;/code&gt; de la spécification Java EE ont été renommés en &lt;code&gt;jakarta.*&lt;/code&gt;.
Certains sous-packages ont également été renommés.&lt;/p&gt;
&lt;p&gt;Pour exemple, la classe &lt;code&gt;Marshaller&lt;/code&gt; de l’API JAXB change de package : de &lt;code&gt;javax.xml.bind.Marshaller&lt;/code&gt; vers &lt;code&gt;jakarta.xml.bind.Marshaller&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Générateur de squelette d’application basé sur Spring Initializr</title><link>https://javaetmoi.com/2022/07/generateur-de-squelette-dapplication-base-sur-spring-initializr/</link><pubDate>Sun, 03 Jul 2022 12:25:17 +0000</pubDate><guid isPermaLink="false">https://javaetmoi.com/?p=2217</guid><description>&lt;p&gt;Dans une &lt;strong&gt;grande entreprise&lt;/strong&gt;, le &lt;strong&gt;développement d’applications métiers&lt;/strong&gt; doit respecter les &lt;strong&gt;règles&lt;/strong&gt; en vigueur : normes de développement, normes de sécurité, barrière qualité, socle technique borné, intégration à l’usine de dév …&lt;br&gt;Le &lt;strong&gt;démarrage d’une nouvelle application Java&lt;/strong&gt; peut être accélérée de bien des manières : usage d’outils Low Code comme &lt;a href="https://www.vermeg.com/fr/produit-palmyra/"&gt;Palmyra&lt;/a&gt;, générateur de squelettes d’application comme &lt;a href="https://www.jhipster.tech/"&gt;JHipster&lt;/a&gt;, utilisation d’applications blanches déclinées par catégorie d’appli (ex : batch, web), copier/coller/élagage d’une application de référence, guide de démarrage sous forme wiki … Chaque technique présente ses avantages et ses inconvénients. Mais certaines ne couvrent pas toutes les règles évoquées précédemment.&lt;br&gt;Afin d’ &lt;strong&gt;accélérer le développement&lt;/strong&gt; d’une nouvelle application, mon objectif était de générer un &lt;strong&gt;squelette d’application minimaliste&lt;/strong&gt; dont le code généré est parfaitement maitrisé et avec des &lt;strong&gt;dépendances choisies à la carte&lt;/strong&gt; par le tech lead. Libre à lui ensuite de retravailler le code généré pour mettre en place l’architecture cible de l’application, en choisissant par exemple de partir sur une architecture hexagonale.&lt;/p&gt;
&lt;p&gt;Bien connu des développeurs Spring Boot, je me suis appuyé sur le code backend faisant tourner le site &lt;a href="https://start.spring.io/"&gt;https://start.spring.io/&lt;/a&gt;, à savoir le projet &lt;strong&gt;&lt;a href="https://github.com/spring-io/initializr"&gt;Spring Initializr&lt;/a&gt;&lt;/strong&gt; conçu et maintenu majoritairement par Stéphane Nicoll. Léger, codé en Java, reposant sur Spring Boot et documenté, ce projet a été conçu pour être personnalisé et extensible. Cela en a fait un excellent candidat.&lt;br&gt;La première mouture de ce générateur développé en quelques jours m’aura permis de générer :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;la configuration du socle Spring Boot d’entreprise&lt;/li&gt;
&lt;li&gt;la configuration du logger permettant de standardiser les logs au format JSON&lt;/li&gt;
&lt;li&gt;la sécurisation des API REST avec Spring Security, OpenID Connect et le SSO d’entreprise&lt;/li&gt;
&lt;li&gt;les contrôleurs et DTO d’une API REST à partir d’une spécification OpenAPI 3&lt;/li&gt;
&lt;li&gt;le Dockerfile et la configuration du pipeline CI/CD&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Configuration Spring Security d’un client de l’API REST Salesforce sécurisée avec OAuth 2.0</title><link>https://javaetmoi.com/2021/11/configuration-spring-security-dun-client-de-lapi-rest-salesforce-securisee-avec-oauth-2-0/</link><pubDate>Sat, 06 Nov 2021 16:53:05 +0000</pubDate><guid isPermaLink="false">https://javaetmoi.com/?p=2138</guid><description>&lt;h2 id="contexte"&gt;Contexte&lt;/h2&gt;
&lt;p&gt;De nos jours, il est courant de devoir &lt;strong&gt;consommer&lt;/strong&gt; une &lt;strong&gt;API REST sécurisée&lt;/strong&gt; à l’aide du standard &lt;strong&gt;OAuth 2.0&lt;/strong&gt; ou de sa surcouche &lt;strong&gt;OpenID Connect&lt;/strong&gt; (OIDC). &lt;br&gt;Schématiquement, le consommateur génère un &lt;strong&gt;jeton (token)&lt;/strong&gt; opaque ou JWT en appelant un serveur d’autorisation (Authorization server) puis, à chaque appel d’API REST, le transmet en tant que bearer via l’ &lt;strong&gt;en-tête HTTP&lt;/strong&gt; &lt;strong&gt;Authorization&lt;/strong&gt;. Ce token a souvent une &lt;strong&gt;durée de vie&lt;/strong&gt; transmise par le serveur d’autorisation via la propriété &lt;strong&gt;expires_in&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;OAuth 2.0 propose quatre cinématiques (flows), la plus commune étant l’Authorization Code Flow. Lorsque l’API REST est appelée depuis une application web, il est courant de voir utiliser le Client Credentials Flow ou le &lt;strong&gt;&lt;a href="https://www.oreilly.com/library/view/getting-started-with/9781449317843/ch04.html"&gt;Resource&lt;/a&gt;&lt;/strong&gt; &lt;strong&gt;&lt;a href="https://www.oreilly.com/library/view/getting-started-with/9781449317843/ch04.html"&gt;Owner Password Credentials Flow&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Récemment, j’ai été amené à &lt;strong&gt;consommer l’API REST du&lt;/strong&gt; &lt;strong&gt;CRM Salesforce&lt;/strong&gt; &lt;strong&gt;depuis une application Spring Boot&lt;/strong&gt;. Cette API était sécurisée avec le Resource Owner password Credentials Flow. Salesforce joue à la fois le rôle de l’Authorization Server et du Resource Owner. Le client (l’application Spring Boot) transmet ses &lt;strong&gt;credentials&lt;/strong&gt; (login et mot de passe) à l’Authorization Server pour obtenir un &lt;strong&gt;Access Token&lt;/strong&gt;. &lt;br&gt;Cet article a pour objectif de vous présenter la &lt;strong&gt;configuration Spring Security&lt;/strong&gt; mise en œuvre pour appeler cette API. Les extraits de code proviennent du repository GitHub &lt;a href="https://github.com/arey/spring-security-oauth2-salesforce-sample"&gt;&lt;strong&gt;arey/spring-security-oauth2-salesforce-sample&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Bonnes pratiques de logging</title><link>https://javaetmoi.com/2021/01/bonnes-pratiques-de-logging/</link><pubDate>Sun, 03 Jan 2021 11:44:26 +0000</pubDate><guid isPermaLink="false">https://javaetmoi.com/?p=2100</guid><description>&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_external image_processed"
width="512"
height="512"
src="https://javaetmoi.com/lof-file-1_3583990369974809130.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Publier en 2021 un article sur les logs n’est pas très novateur ; je vous l’accorde. Le &lt;strong&gt;logging&lt;/strong&gt; est une pratique vieille comme l’informatique, ou presque. C’est une &lt;strong&gt;pratique universelle&lt;/strong&gt; qu’on retrouve &lt;strong&gt;quel que soit le langage de programmation&lt;/strong&gt; et quel que soit le type d’application. Pour autant, elle est survolée en fac et en école d’ingénieur. Les dévs apprennent bien souvent à logger sur le tas, en fonction de leurs besoins et de ce qui est déjà mis en place sur leur application. Rares sont également les entreprises mettant à disposition des normes et des bonnes pratiques en termes de traces applicatives.&lt;/p&gt;
&lt;p&gt;Dans cet article, je ne vous expliquerai pas comment utiliser &lt;a href="http://www.slf4j.org/"&gt;SLF4J&lt;/a&gt;, &lt;a href="http://logback.qos.ch/"&gt;Logback&lt;/a&gt;, &lt;a href="https://logging.apache.org/log4j/2.x/"&gt;Log4j 2&lt;/a&gt; ou la controversée &lt;a href="https://docs.oracle.com/javase/8/docs/technotes/guides/logging/index.html"&gt;API de Logging&lt;/a&gt; du langage Java. C’est un prérequis que bon nombre d’entre vous connaissent déjà. Beaucoup de ressources existent à ce sujet, en commençant par leurs documentations officielles.&lt;/p&gt;
&lt;p&gt;Non, &lt;strong&gt;je vous y exposerai plutôt les bonnes pratiques que je préconise&lt;/strong&gt;, tant au niveau d’une application que d’une organisation. Je répondrai également aux questions les plus courantes : &lt;strong&gt;quand utiliser tel ou tel niveau de log ?&lt;/strong&gt; &lt;strong&gt;que mettre dans les messages de logs ?&lt;/strong&gt;&lt;br&gt;Nom de mon blog oblige, j&amp;rsquo;utiliserai des exemples venant du monde Java. Mais vous pourrez aisément transposer ces bonnes pratiques à d’autres technologies. Et bien entendu, elles sont à adapter en fonction de votre contexte et de vos besoins.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="Bonnes pratiques de logging"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2021/01/logo-splunk.jpg"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Certification Microsoft Azure Fondamentals</title><link>https://javaetmoi.com/2020/02/certification-microsoft-azure-fondamentals/</link><pubDate>Sat, 08 Feb 2020 18:35:40 +0000</pubDate><guid isPermaLink="false">https://javaetmoi.com/?p=2080</guid><description>&lt;p&gt;&lt;a href="https://www.youracclaim.com/earner/earned/badge/e18659c6-5f65-4efa-becd-c4293079ea4b"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_external image_processed"
width="150"
height="150"
src="https://javaetmoi.com/azure-fundamentals-600x600-1-150x150_6489878026618608652.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt; Assurée par un formateur Microsoft, la formation « Microsoft Azure Fondamentals » se déroule sur une journée et permet de se préparer à la &lt;strong&gt;&lt;a href="https://docs.microsoft.com/fr-fr/learn/certifications/exams/az-900"&gt;certification AZ-900 « Microsoft Azure Fondamentals »&lt;/a&gt;&lt;/strong&gt;. A l’issue de la formation, un voucher est donné à chaque participant. Ces derniers sont invités à passer leur certification dans la foulée.&lt;/p&gt;
&lt;p&gt;La formation est découpée en 4 modules.
Les notes ci-dessous m’auront permis d’obtenir &lt;a href="https://www.youracclaim.com/earner/earned/badge/e18659c6-5f65-4efa-becd-c4293079ea4b"&gt;ma certification&lt;/a&gt; du premier coup. J’espère qu’elles vous aideront à vous préparer. En rouge, sont notés les mots clés, concepts et noms de produits à retenir par cœur.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="azure-fundamentals-600x600"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2020/02/azure-fundamentals-600x600-1.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Désendettement de Spring Cloud Netflix</title><link>https://javaetmoi.com/2019/11/desendettement-de-spring-cloud-netflix/</link><pubDate>Thu, 28 Nov 2019 08:37:31 +0000</pubDate><guid isPermaLink="false">https://javaetmoi.com/?p=2045</guid><description>&lt;p&gt;&lt;a href="https://javaetmoi.com/wp-content/uploads/2019/11/spring-cloud-netflix.png"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_external image_processed"
width="225"
height="225"
src="https://javaetmoi.com/spring-cloud-netflix_1305183779605428790.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt;Le projet &lt;a href="https://spring.io/projects/spring-cloud-netflix"&gt;Spring Cloud Netflix&lt;/a&gt; facilite l’intégration de différents projets de la suite &lt;a href="https://netflix.github.io/"&gt;Netflix OSS&lt;/a&gt; dans des applications Spring Boot / Spring Cloud : Eureka, Zuul 1, Ribbon, Hystrix, Archaius, Feign. Jusqu’en 2018, le projet &lt;a href="https://github.com/spring-petclinic/spring-petclinic-microservices"&gt;Spring Petclinic Microservices&lt;/a&gt; dont j’assure la maintenance utilisait ces 4 premiers projets.&lt;/p&gt;
&lt;p&gt;Or, certains des projets historiques de Netflix OSS ne sont plus activement développés. Ils sont rentrés en mode maintenance. C’est notamment le cas d’ &lt;a href="https://github.com/Netflix/Hystrix#hystrix-status"&gt;Hystrix&lt;/a&gt;, de Zuul 1 et de Ribbon. En décembre 2018, lors de l’annonce de la &lt;a href="https://spring.io/blog/2018/12/12/spring-cloud-greenwich-rc1-available-now"&gt;sortie de Spring Cloud Greenwich RC1&lt;/a&gt;, Pivotal recommande de migrer vers des projets tiers et de nouveaux modules Spring Cloud :&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Anciennement****Solutions cibles&lt;/strong&gt; Hystrix &lt;a href="https://github.com/resilience4j/resilience4j"&gt;Resilience4j&lt;/a&gt;Hystrix Dashboard / Turbine &lt;a href="https://micrometer.io/"&gt;Micrometer&lt;/a&gt; + Monitoring System Ribbon &lt;a href="https://cloud.spring.io/spring-cloud-static/spring-cloud-commons/2.2.0.RC2/reference/html/#spring-cloud-loadbalancer"&gt;Spring Cloud Loadbalancer&lt;/a&gt; Zuul 1 &lt;a href="https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.0.RC2/reference/html/"&gt;Spring Cloud Gateway&lt;/a&gt; Archaius 1 Spring Boot external config + Spring Cloud Config&lt;/p&gt;
&lt;p&gt;Dans le cadre de Spring Petclinic Microservices, seul Eureka est épargné et continue de jouer son rôle d’annuaire de service. Un désendettement vers &lt;strong&gt;Resilience4j&lt;/strong&gt;, &lt;strong&gt;Micrometer&lt;/strong&gt;, &lt;strong&gt;Spring Cloud Loadbalancer&lt;/strong&gt; et &lt;strong&gt;Spring Cloud Gateway&lt;/strong&gt; s’est naturellement imposé (issue &lt;a href="https://github.com/spring-petclinic/spring-petclinic-microservices/issues/117"&gt;#117&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Cet article retrace les différentes étapes de
migration. J’espère qu’il vous sera utile si vous avez le même chemin à
parcourir.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="Désendettement de Spring Cloud Netflix"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2019/11/spring-cloud-netflix.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>18 prises de notes à Devoxx France 2019</title><link>https://javaetmoi.com/2019/05/18-prises-de-notes-a-devoxx-france-2019/</link><pubDate>Fri, 03 May 2019 17:28:03 +0000</pubDate><guid isPermaLink="false">https://javaetmoi.com/?p=1987</guid><description>&lt;p&gt;Ce fut ma 8ième participation à Devoxx France. Les années passent et je suis toujours aussi friand de cette bulle d’oxygène dans mon quotidien encore bien trop souvent parsemé de Struts, JSF et MagicDraw. Un grand bravo aux organisateurs, bénévoles et aux speakers.&lt;/p&gt;
&lt;p&gt;D&amp;rsquo;ici quelques jours, &lt;strong&gt;l’intégralité des vidéos des conférences et universités présentées lors de Devoxx France&lt;/strong&gt; &lt;strong&gt;2019&lt;/strong&gt; sont disponibles sur la &lt;a href="https://www.youtube.com/channel/UCsVPQfo5RZErDL41LoWvk0A/videos"&gt;chaîne Devoxx FR de Youtube&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Si vous souhaitez rapidement vous faire un avis sur leur contenu avant de les visionner ou si vous souhaitez garder une trace écrite de ce que vous y avez appris, je mets librement à disposition l’ensemble de &lt;strong&gt;mes 18 notes&lt;/strong&gt; prises au cours de ces 3 jours riches en contenus et en découvertes.&lt;/p&gt;
&lt;p&gt;Lors de cette édition 2019, les 2 frameworks hypes du moment &lt;strong&gt;Quarkus&lt;/strong&gt; et &lt;strong&gt;Micronaut&lt;/strong&gt; étaient sur le devant de la scène en permettant de développer des applications Java modernes et natives grâce à &lt;strong&gt;GraalVM&lt;/strong&gt;. Poussée par l’essor des &lt;strong&gt;microservices&lt;/strong&gt;, l’intégration de Java à &lt;strong&gt;Docker&lt;/strong&gt; et son orchestrateur &lt;strong&gt;Kubernetes&lt;/strong&gt; est de plus en plus poussée. Les indémodables étaient également de la partie : design d’ &lt;strong&gt;API REST&lt;/strong&gt;, &lt;strong&gt;montée de version de Java&lt;/strong&gt;, &lt;strong&gt;qualimétrie, JavaEE&lt;/strong&gt;(oups, pardon, JakartaEE) et &lt;strong&gt;sécurité&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://javaetmoi.com/wp-content/uploads/2019/05/Devoxx-France-2019.jpg"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_external image_processed"
width="1024"
height="554"
src="https://javaetmoi.com/Devoxx-France-2019-1024x554_134393457400624656.jpg"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="Devoxx France 2019"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2019/05/Devoxx-France-2019-banner.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Dashboard Grafana dockerizé</title><link>https://javaetmoi.com/2019/03/dashboard-grafana-docker/</link><pubDate>Thu, 28 Mar 2019 17:27:32 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1959</guid><description>&lt;p&gt;A l’instar de SLF4J pour les logs, &lt;strong&gt;&lt;a href="https://micrometer.io/"&gt;Micrometer&lt;/a&gt;&lt;/strong&gt; est la &lt;strong&gt;façade d’export de métriques&lt;/strong&gt; utilisée par Spring Boot et ses Actuators. Micrometer supporte une douzaine de systèmes de monitoring : Datalog, Netflix Atlas, New Relic, JMX, CloudWatch, InfluxDB ou bien encore Prometheus.&lt;/p&gt;
&lt;p&gt;Récemment, j’ai poursuivi le travail initié par Kevin Crawley pour intégrer &lt;strong&gt;Prometheus&lt;/strong&gt; et &lt;strong&gt;Grafana&lt;/strong&gt; dans la version microservices de Spring Petclinic. Proposée par Maciej Szarliński, l’idée consistait à remplacer les compteurs &lt;strong&gt;Micrometer&lt;/strong&gt; de typeregistry.counter(&amp;ldquo;create.visit&amp;rdquo;).increment() par l’ &lt;a href="https://micrometer.io/docs/concepts"&gt;annotation @Timed.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;J’ai profité de ce changement pour améliorer le packaging &lt;strong&gt;Docker&lt;/strong&gt; de Grafana et en simplifier l’accès. Pour accéder au dashboard personnalisé exposant l’évolution du nombre d’animaux et de propriétaires, un &lt;em&gt;docker-compose up&lt;/em&gt; suivi d’un clic sur l’ &lt;a href="http://localhost:3000/d/69JXeR0iw/spring-petclinic-metrics"&gt;URL du dashboard&lt;/a&gt; sont désormais suffisant.&lt;br&gt;&lt;strong&gt;Ce billet présente les configurations Docker et Grafana mises en oeuvre&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="wp-content/uploads/2019/03/2019-03-Dashboard-Grafana-dockerise%CC%81-grafana.png"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="Dashboard Grafana Spring Petclinic Metrics"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2019/03/2019-03-Dashboard-Grafana-dockerise%CC%81-grafana.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="2019-03 - Dashboard Grafana dockerisé - grafana"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2019/03/2019-03-Dashboard-Grafana-dockerise%CC%81-grafana.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Black Hell : mon premier jeu vidéo</title><link>https://javaetmoi.com/2019/02/black-hell-mon-premier-jeu-video/</link><pubDate>Mon, 11 Feb 2019 16:27:37 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1906</guid><description>&lt;a href="wp-content/uploads/2019/02/2019-02-Black-Hell-Ecran-accueil.png"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2019/02/2019-02-Black-Hell-Ecran-accueil.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt; Pour ce premier article de 2019, je vous propose un &lt;strong&gt;voyage dans le temps&lt;/strong&gt;, au contenu plus personnel. J’ai récemment dîné avec mon vieil ami Nicolas Lidzborski qui travaille chez Google aux US et que je n’avais pas revu depuis une dizaine d’années. Comme toute retrouvaille, nous nous sommes remémorés des souvenirs du Lycée, ses profs et son club IF. De sa chambre d’ado, Nicolas a retrouvé une illustration que nous avions réalisé pendant le &lt;strong&gt;&lt;a href="#ZgotmplZ"&gt;concours Soft la Nuit&lt;/a&gt;&lt;/strong&gt; de 1996, un marathon de 24h pendant lequel 20 équipes de 4 jeunes devaient développer un logiciel. Et oui, mon premier &lt;strong&gt;hackaton&lt;/strong&gt; commence à dater. Afin de pouvoir se qualifier, nous avions du présenter des projets personnels. Mon &lt;a href="https://github.com/arey/black-hell"&gt;jeu vidéo Black Hell&lt;/a&gt; en faisait partie. Par curiosité, et avec un brin de nostalgie, je suis parti à la recherche d’un backup de disquette. J’en ai ressorti code source et binaire. Et surprise : avec l’émulateur &lt;a href="https://www.dosbox.com/"&gt;DOSBox&lt;/a&gt;, j’ai réussi à le faire tourner, à la fois sous Windows 10 et MacOS.</description></item><item><title>Configurez Logback en Java</title><link>https://javaetmoi.com/2018/03/configurez-logback-en-java/</link><pubDate>Fri, 30 Mar 2018 17:01:59 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1811</guid><description>&lt;p&gt;&lt;a href="wp-content/uploads/2018/03/logback-logo.jpg"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2018/03/logback-logo.jpg"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Afin de &lt;strong&gt;normaliser&lt;/strong&gt; la &lt;strong&gt;configuration Logback&lt;/strong&gt; des applications web sur lesquelles j’interviens, j’ai récemment eu besoin de programmer Logback via son &lt;strong&gt;API en Java&lt;/strong&gt; et non en utilisant la syntaxe XML Joran.
Moins courant que le traditionnel &lt;strong&gt;logback.xml&lt;/strong&gt;, cette possibilité de configurer Logback par le code offre davantage de possibilités, ne serait-ce que par son caractère dynamique.&lt;/p&gt;
&lt;p&gt;Par le passé, j’avais déjà eu l’occasion de manipuler l’API Logback dans des tests unitaires afin de changer dynamiquement le niveau de log des loggers.
Cette fois-ci, je l’ai utilisé pour déclarer les différents appenders et configurer toute l’ &lt;strong&gt;infrastructure applicative de logs&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Activer l’appender Console uniquement sur le poste de dév (afin qu’en prod, les logs ne se retrouvent pas en double dans le fichier server.log de JBoss)&lt;/li&gt;
&lt;li&gt;Factoriser la stratégie de journalisation des différents appenders fichiers (troubleshooting, overview, soap …)&lt;/li&gt;
&lt;li&gt;Récupérer différentes informations applicatives (ex : nom de la JVM, application, nom de l’environnement, login de l’utilisateur authentifié) à destination du collecteur de logs (Logstash ou Splunk)&lt;/li&gt;
&lt;li&gt;Exposer l’accès aux loggers au travers d’une API REST&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La configuration des logs reste paramétrable via un fichier de properties externe. En effet, le paramétrage peut différer d’un environnement de déploiement à l’autre (ex : chemin du répertoire des fichiers logs). La configuration Logback reste extensible par l’inclusion d’un fichier XML au format Joran.&lt;/p&gt;
&lt;p&gt;Dans cet article, je vais vous présenter quelques bouts de code simplifié manipulant l’API Java de Logback.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="logback-logo"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2018/03/logback-logo.jpg"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Build Gradle en Kotlin d’une webapp Spring Boot</title><link>https://javaetmoi.com/2017/11/build-gradle-dsl-kotlin-webapp-spring-boot/</link><pubDate>Wed, 22 Nov 2017 07:40:41 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1786</guid><description>&lt;p&gt;&lt;a href="wp-content/uploads/2017/11/gradle-logo.png"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2017/11/gradle-logo.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt; En guise de conclusion de &lt;a href="http://javaetmoi.com/2017/09/migrez-application-java-spring-boot-vers-kotlin/"&gt;mon précédent billet&lt;/a&gt;, je proposais de &lt;strong&gt;migrer le &lt;a href="https://github.com/spring-petclinic/spring-petclinic-kotlin/blob/c66b152b83be2cdf8c28ca4e3e8869158b47a40b/pom.xml"&gt;build Maven&lt;/a&gt; d&lt;/strong&gt; &lt;strong&gt;’une application web Spring Boot 2 en un build Gradle bas&lt;/strong&gt; &lt;strong&gt;é sur le langage Kotlin&lt;/strong&gt;. C’est désormais chose faite. Mais bien que Gradle &lt;strong&gt;privil&lt;/strong&gt; &lt;strong&gt;égie&lt;/strong&gt; aujourd’hui l’usage du &lt;strong&gt;DSL&lt;/strong&gt; &lt;strong&gt;Kotlin&lt;/strong&gt; au détriment de &lt;strong&gt;Groovy&lt;/strong&gt;, son &lt;a href="https://docs.gradle.org/4.3.1/userguide/userguide.html"&gt;guide d’utilisation&lt;/a&gt; n’a pas encore été actualisé et il est difficile de trouver de la documentation. Il faut passer par le projet GitHub &lt;a href="https://github.com/gradle/kotlin-dsl"&gt;kotlin-dsl&lt;/a&gt; pour accéder à quelques tutoriaux et des exemples. Heureusement, GitHub fourmille d’autres d’exemples, notamment du côté des projets soutenus par les contributeurs Pivotal sur Spring Boot.&lt;/p&gt;
&lt;p&gt;Sans plus tarder, voici le fichier de conf &lt;a href="https://github.com/spring-petclinic/spring-petclinic-kotlin/blob/master/build.gradle.kts"&gt;build.gradle.kts&lt;/a&gt; de la version Kotlin de Spring Petclinic.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="gradle-logo"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2017/11/gradle-logo.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Découvrir Kotlin en migrant une webapp Spring Boot</title><link>https://javaetmoi.com/2017/09/migrez-application-java-spring-boot-vers-kotlin/</link><pubDate>Mon, 25 Sep 2017 16:50:26 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1753</guid><description>&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2017/09/Kotlin_logo.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Lors la dernière conférence Google I/O qui s’est tenue en mai 2017, Google a officialisé le &lt;strong&gt;support de Kotlin sur Android&lt;/strong&gt;. Google n’est pas le seul acteur de l’IT à miser sur ce nouveau langage créé par JetBrains (l’éditeur de l’IDE IntelliJ) et s’exécutant sur la JVM (mais pas que). En effet, dès février 2016, &lt;a href="https://spring.io/blog/2016/02/15/developing-spring-boot-applications-with-kotlin"&gt;Pivotal proposait de développer des applications &lt;strong&gt;Spring Boot&lt;/strong&gt; avec Kotlin&lt;/a&gt;. En janvier 2017, ils annonçaient que &lt;a href="https://spring.io/blog/2017/01/04/introducing-kotlin-support-in-spring-framework-5-0"&gt;la version 5 du &lt;strong&gt;framework Spring&lt;/strong&gt; proposerait des &lt;strong&gt;fonctionnalités exclusives à Kotlin&lt;/strong&gt;&lt;/a&gt;. Chez Gradle, le langage Kotlin est désormais privilégié au détriment de Groovy.&lt;/p&gt;
&lt;p&gt;Pour découvrir ce nouveau venu dans la galaxie des langages de programmation, je me suis intéressé à migrer vers Kotlin l’application démo Spring Petclinic développée en Java et Spring Boot. Je souhaitais ici partager son code source : &lt;a href="https://github.com/spring-petclinic/spring-petclinic-kotlin"&gt;&lt;strong&gt;spring-petclinic-kotlin&lt;/strong&gt;&lt;/a&gt; et énumérer les différences notables avec sa version Java.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="Logo Kotlin"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2017/09/Kotlin_logo.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Implémentation Java de l'algorithme de Kruskal</title><link>https://javaetmoi.com/2017/09/algo-java-kruskal-recherche-arbre-couvrant-poids-minium/</link><pubDate>Sat, 16 Sep 2017 10:28:59 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1759</guid><description>&lt;p&gt;&lt;a href="wp-content/uploads/2017/09/300px-Minimum_spanning_tree.svg_.png"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="Arbre couvrant de poids minimum"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2017/09/300px-Minimum_spanning_tree.svg_.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Faisant partie des &lt;a href="https://fr.wikipedia.org/wiki/Cat%C3%A9gorie:Algorithme_de_la_th%C3%A9orie_des_graphes" title="Catégorie:Algorithme de la théorie des graphes"&gt;algorithmes de la théorie des graphes&lt;/a&gt;, l&amp;rsquo; &lt;a href="https://fr.wikipedia.org/wiki/Algorithme_de_Kruskal"&gt;algorithme de Kruskal&lt;/a&gt; permet de rechercher un arbre recouvrant de poids minimum.&lt;/p&gt;
&lt;p&gt;Une application pratique de l&amp;rsquo;algorithme de Kruskal consiste à relier tous les ordinateurs d&amp;rsquo;un même réseau local avec une longueur optimale de fibre optique.&lt;/p&gt;
&lt;p&gt;Dans ce billet, vous trouverez une implémentation Java de cet algorithme. Il m&amp;rsquo;aura permis de résoudre le &lt;a href="https://www.isograd.com/FR/solutionconcours.php"&gt;problème Fibre Optique donné en finale du concours du Meilleur Dev de France 2017&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="300px-Minimum_spanning_tree.svg"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2017/09/300px-Minimum_spanning_tree.svg_.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Implémentation Java de l'algorithme de rendu de monnaie par programmation dynamique</title><link>https://javaetmoi.com/2017/07/algo-rendu-monnaie-programmation-dynamique-java/</link><pubDate>Sat, 01 Jul 2017 08:07:45 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1742</guid><description>&lt;p&gt;&lt;a href="wp-content/uploads/2017/07/300px-Rendu_monnaie.svg_.png"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2017/07/300px-Rendu_monnaie.svg_.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt; Dans ce billet, j’ai eu l’envie de vous partager mon implémentation Java du très célèbre &lt;a href="https://fr.wikipedia.org/wiki/Probl%C3%A8me_du_rendu_de_monnaie"&gt;problème du rendu de monnaie&lt;/a&gt; dont voici l’énoncé : étant donné un système de monnaie, comment rendre de façon optimale une somme donnée, c&amp;rsquo;est-à-dire avec le nombre minimal de pièces et de billets ?
Par exemple, dans le système monétaire de l’Euro, la manière la plus optimale de rendre 6 euros consiste à rendre un billet de 5 € et une pièce de 1 €, même si d’autres combinaisons existent (ex : 3 x 2 € ou 6 x 1 €).&lt;/p&gt;
&lt;p&gt;Dans le cas d’un système monétaire non canonique, utiliser un &lt;a href="https://fr.wikipedia.org/wiki/Algorithme_glouton"&gt;algorithme glouton&lt;/a&gt; ne donnera pas nécessairement un résultat optimal. Il est nécessaire de passer par la méthode algorithmique dite de &lt;a href="https://fr.wikipedia.org/wiki/Programmation_dynamique"&gt;programmation dynamique&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="300px-Rendu_monnaie.svg"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2017/07/300px-Rendu_monnaie.svg_.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Formulaire dynamique en Vue.Js</title><link>https://javaetmoi.com/2017/05/formulaire-dynamique-en-vue-js/</link><pubDate>Thu, 18 May 2017 16:15:36 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1726</guid><description>&lt;p&gt;Dans ce billet, nous allons mettre en pratique l’initiation à Vue.js reçue le mois dernier. Je vous propose de &lt;strong&gt;coder un pseudo Google Form&lt;/strong&gt; avec l’aide de &lt;a href="https://vuejs.org/"&gt;&lt;strong&gt;Vue.js&lt;/strong&gt;&lt;/a&gt;, de &lt;strong&gt;Bootsrap&lt;/strong&gt; et du framework de validation &lt;a href="http://vee-validate.logaretm.com/"&gt;&lt;strong&gt;VeeValidate&lt;/strong&gt;&lt;/a&gt;.
Le &lt;strong&gt;formulaire HTML&lt;/strong&gt; est généré automatiquement à partir d’un &lt;strong&gt;paramétrage JSON&lt;/strong&gt; récupéré par une API REST. Nous n’aborderons pas ici la partie serveur.
Un utilisateur peut sauvegarder son formulaire à l’état de brouillon afin de poursuivre ultérieurement sa saisie. Le formulaire à afficher peut donc être pré-saisi.
La &lt;strong&gt;validation&lt;/strong&gt; est &lt;strong&gt;dynamique&lt;/strong&gt;: elle se fait au fur et à mesure de la saisie du formulaire.
Voici un exemple de formulaire :&lt;/p&gt;
&lt;p&gt;&lt;a href="wp-content/uploads/2017/05/2017-05-Formulaire-dynamique-en-Vue.js.png"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt=""
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2017/05/2017-05-Formulaire-dynamique-en-Vue.js.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="Formulaire dynamique en Vue.Js"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2017/05/2017-05-Formulaire-dynamique-en-Vue.js.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Les Streams Java 8 par l'exemple</title><link>https://javaetmoi.com/2016/06/les-streams-java-8-par-lexemple/</link><pubDate>Fri, 10 Jun 2016 05:32:14 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1615</guid><description>&lt;p&gt;Bien que &lt;strong&gt;Java 8&lt;/strong&gt; soit sorti il y’a 2 ans, tous les développeurs n’ont pas eu encore la chance de pouvoir utiliser, en entreprise, tous les concepts issus de la &lt;strong&gt;programmation fonctionnelle&lt;/strong&gt; et qui ont été introduits dans cette version majeure : expressions lambda, interfaces fonctionnelles, méthodes par défaut, Optional, références de méthode, Streams …
Pourtant, Java 8 est à nos portes : des projets de migration de serveur d’application se terminent, les socles d’entreprise se mettent à jour, des frameworks exploitent ces nouveautés (ex : JUnit 5) &amp;hellip; Et on va enfin pouvoir exploiter à bon escient toutes ces nouvelles fonctionnalités. Mais avant cela, une mise à niveau est indispensable. Et c’est dans cet objectif que j’ai récemment initié mes collègues aux &lt;strong&gt;Streams&lt;/strong&gt;.
A partir d’un jeux de données réduit (une liste de 3 clients), &lt;strong&gt;j’ai implémenté quelques règles de gestion à la fois en Java 7 avec des boucles et en Java 8 avec des Streams&lt;/strong&gt;, histoire de leur montrer la différence.&lt;/p&gt;</description></item><item><title>Ces outils qui nous font gagner du temps</title><link>https://javaetmoi.com/2016/03/outils-pour-developpeurs-java/</link><pubDate>Mon, 21 Mar 2016 07:16:35 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1549</guid><description>&lt;p&gt;Au quotidien, tout &lt;strong&gt;développeur Java&lt;/strong&gt; utilise un IDE, un JDK, un outil build et un navigateur. Ce sont des standards. A côté, chaque développeur utilise un ou plusieurs petits outils permettant d’améliorer son quotidien. Par outil, j’entends aussi bien un &lt;strong&gt;plugin&lt;/strong&gt;, un &lt;strong&gt;logiciel&lt;/strong&gt; ou une &lt;strong&gt;fonctionnalité&lt;/strong&gt; avancée de son IDE.
Dans cette présentation, j’ai eu envie de partager des &lt;strong&gt;outils fonctionnant sous Windows&lt;/strong&gt;(mais pas que). J’utilise certains depuis des années, d’autres depuis seulement quelques semaines suite aux recommandations de collègues.
A vous de voir si vous souhaitez les tester puis les adopter, ou non.&lt;/p&gt;
&lt;p&gt;[slideshare id=59714114&amp;amp;doc=2016-03-17-cesoutilsquivousfontgagnerdutemps-160318071738]&lt;/p&gt;</description></item><item><title>Formatez votre code</title><link>https://javaetmoi.com/2015/12/formatez-votre-code-editorconfig/</link><pubDate>Fri, 04 Dec 2015 07:27:57 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1488</guid><description>&lt;p&gt;&lt;a href="wp-content/uploads/2015/11/editorconfig-stickers.png"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="editorconfig-stickers"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2015/11/editorconfig-stickers.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt; Lors du démarrage d’un projet sur lequel plusieurs développeurs vont être amenés à travailler, se pose très tôt la question des &lt;strong&gt;styles et règles de formatage&lt;/strong&gt; à appliquer au code. En effet, afin de pouvoir comparer l’historique des révisions d’un fichier, une bonne pratique veut que l’on ne change pas les règles de formatage au cours de route. Si tel était le cas, les changements importants seraient noyés par les changements d’indentations et autres retours à la ligne.
Parmi les normes de développements d’une entreprise ou d’un projet Open Source, un chapitre couvre généralement les règles de formatage. C’est par exemple le cas du &lt;a href="https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Code-Style"&gt;guide de style de code&lt;/a&gt; du projet Spring Framework. Ces règles peuvent également être définies au sein d’un outil de qualimétrie comme &lt;a href="http://nemo.sonarqube.org/coding_rules#qprofile=java-sonar-way-45126%7Cactivation=true"&gt;SonarQube&lt;/a&gt;. Chaque violation de règle entraine alors un défaut.
Ce &lt;strong&gt;billet propose 2 solutions&lt;/strong&gt; permettant à des développeurs &lt;a href="https://www.jetbrains.com/idea/"&gt;IntelliJ&lt;/a&gt;, &lt;a href="https://spring.io/tools"&gt;Spring Tools Suite&lt;/a&gt; (STS) et &lt;a href="https://eclipse.org/home/index.php"&gt;Eclipse&lt;/a&gt; de travailler ensemble.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="editorconfig-stickers"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2015/11/editorconfig-stickers.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Docker file de la database MusicBrainz</title><link>https://javaetmoi.com/2015/11/docker-file-database-musicbrainz/</link><pubDate>Mon, 02 Nov 2015 06:12:35 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1471</guid><description>&lt;p&gt;&lt;a href="wp-content/uploads/2015/07/docker-logo.jpg"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="docker-logo"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2015/07/docker-logo.jpg"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt; Lorsqu’on développe dans son coin une démo basée sur une nouvelle techno, il est fréquent d’avoir besoin de données de tests. Soit on se les construit à la main, soit on en récupère sur Internet. Le mouvement &lt;a href="https://fr.wikipedia.org/wiki/Open_data"&gt;Open Data&lt;/a&gt; et les API mises à disposition par les grands du Web permettent de récupérer des données en temps réel. Dans les conférences, nombre de démos live utilisent les API de Twitter ou de Github. Ces données sont généralement formatées en JSON. Une connexion réseau est alors nécessaire.&lt;/p&gt;
&lt;p&gt;Dans le cadre d’une série d’articles sur Elasticsearch et AngularJS, j’ai eu le besoin d’indexer des données de manière &lt;strong&gt;offline&lt;/strong&gt;. Cherchant une &lt;strong&gt;source de donnée musicale&lt;/strong&gt;, j’ai opté pour &lt;a href="https://musicbrainz.org/"&gt;&lt;strong&gt;MusicBrainz&lt;/strong&gt;&lt;/a&gt; qui, à l’instar d’IMDb pour le cinéma, est une plateforme ouverte collectant des méta-données sur les artistes, leurs albums et leurs chansons puis les mettant à disposition du publique. Cette plateforme est composée d’une base de données relationnelles et d’une interface web permettant d’effectuer des recherches, de consulter les données et de participer à l’enrichissement de la base. &lt;a href="http://blog.last.fm/2011/11/24/the-brainz-are-back-in-town"&gt;Last.fm&lt;/a&gt;, &lt;a href="http://www.theguardian.com/open-platform/blog/linked-data-open-platform"&gt;The Guardian&lt;/a&gt; ou bien encore la &lt;a href="http://www.bbc.co.uk/music/brainz/"&gt;BBC&lt;/a&gt; s’interfacent avec MusicBrainz.&lt;/p&gt;
&lt;p&gt;Dans l’article &lt;a href="http://javaetmoi.com/2013/11/musicbrainz-elasticsearch-angularjs-openshift/"&gt;Elastifiez la base MusicBrainz sur OpenShift&lt;/a&gt;, je proposais 2 méthodes pour installer la base de données : récupérer une VM ou un dump de la base PostgreSQL. Dans les 2 cas, la procédure d’installation demandait une intervention humaine.
Ce billet vous en propose une 3ième : automatiser l’installation de base de données à l’aide de &lt;a href="https://www.docker.com/"&gt;&lt;strong&gt;Docker&lt;/strong&gt;&lt;/a&gt;. Après &lt;strong&gt;quelques lignes de commande&lt;/strong&gt; et un peu de &lt;strong&gt;patience&lt;/strong&gt; le temps de l’import du dump PostgreSQL, vous pourrez vous connecter localement à la base musicale contenant des données à jour.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="docker-logo"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2015/07/docker-logo.jpg"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Hibernate Validator 5 sur un conteneur de Servlet 2.5</title><link>https://javaetmoi.com/2015/10/hibernate-validator-5-sur-conteneur-servlet-2-5/</link><pubDate>Thu, 01 Oct 2015 05:17:30 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1462</guid><description>&lt;p&gt;Implémentation de référence de &lt;a href="http://beanvalidation.org/"&gt;Bean Validation 1.1&lt;/a&gt;, &lt;a href="http://docs.jboss.org/hibernate/validator/5.1/reference/en-US/html/validator-gettingstarted.html#validator-gettingstarted-uel"&gt;Hibernate Validator 5.x requière une implémentation d&amp;rsquo;Unified Expression Language respectant la JSR-341&lt;/a&gt; (correspond aux &lt;a href="https://jcp.org/en/jsr/detail?id=341"&gt;&lt;strong&gt;EL 2.2&lt;/strong&gt;&lt;/a&gt;).
EL 2.2 étant apparue avec Java EE 6, il n’est donc pas possible d’utiliser Hibernate Validator 5 dans un serveur d’application Java EE 5 et un conteneur de servlets 2.5. C’est pourquoi &lt;a href="http://hibernate.org/validator/faq/#does-hibernate-validator-5-x-work-with-tomcat-6"&gt;Hibernate Validator 5 ne fonctionne pas avec Tomcat 6&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="wp-content/uploads/2015/09/hibernate-validator-logo.png"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="hibernate-validator-logo"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2015/09/hibernate-validator-logo.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Essayer et vous tomberez au runtime sur l’exception suivante :
NoSuchMethodError: javax.el.ExpressionFactory.newInstance()Ljavax/el/ExpressionFactory)&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="hibernate-validator-logo"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2015/09/hibernate-validator-logo.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Benchmark de frameworks de mapping objet</title><link>https://javaetmoi.com/2015/09/benchmark-frameworks-java-mapping-objet/</link><pubDate>Wed, 16 Sep 2015 05:20:37 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1442</guid><description>&lt;p&gt;&lt;a href="wp-content/uploads/2015/09/logo-java-performance.png"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="logo-java-performance"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2015/09/logo-java-performance.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt; Ce billet a pour origine un commentaire posté dans &lt;a href="http://javaetmoi.com/2015/08/check-list-revue-code-et-architecture-java/"&gt;mon précédent billet&lt;/a&gt; et dans lequel Laurent demandait un &lt;strong&gt;retour d’expérience&lt;/strong&gt; sur l’utilisation de &lt;strong&gt;frameworks Java de mapping objet vers objet&lt;/strong&gt; tels &lt;a href="https://github.com/DozerMapper/dozer"&gt;Dozer&lt;/a&gt; ou &lt;a href="http://modelmapper.org/"&gt;ModelMapper&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Dans l’architecture d’une &lt;strong&gt;applicative n-tiers&lt;/strong&gt;, une couche de mapping objet / objet peut intervenir à plusieurs niveaux :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;En entrée ou en sortie d’un web service SOAP afin de convertir en objet métier les DTO générés à partir du WSDL, ou inversement.&lt;/li&gt;
&lt;li&gt;Entre la couche de présentation et la couche de services métiers lorsque la première expose des DTO et la seconde travaille avec des objets métiers.&lt;/li&gt;
&lt;li&gt;Entre la couche de services métiers et la couche d’accès aux données afin de mapper les entités persistances en objets métiers.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Dans le premier exemple, le développeur n’a guère le choix. Dans les 2 autres, il s’agit d’un choix d’architecture.
L’introduction d’une couche de mapping n’est pas un choix à prendre à la légère : ayant pour objectif de découpler les couches, elle complexifie l’application et peut détériorer ses performances. Le choix d’en introduire une et d’utiliser un framework pour faciliter sa mise en œuvre n’est pas non plus évident.&lt;/p&gt;
&lt;p&gt;Ce billet est découpé en 2 parties :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Une première dressant les &lt;strong&gt;avantages&lt;/strong&gt; et les &lt;strong&gt;inconvénients&lt;/strong&gt; d’utiliser &lt;strong&gt;Dozer&lt;/strong&gt; par rapport à une &lt;strong&gt;approche manuelle&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;et une seconde présentant les résultats d’un &lt;strong&gt;micro-benchmark&lt;/strong&gt; comparant plusieurs frameworks : &lt;strong&gt;Dozer&lt;/strong&gt;, &lt;strong&gt;Orika&lt;/strong&gt;, &lt;strong&gt;Selma&lt;/strong&gt;, &lt;strong&gt;MapStruct&lt;/strong&gt; et &lt;strong&gt;ModelMapper&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="logo-java-performance"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2015/09/logo-java-performance.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Check-list revue de code Java</title><link>https://javaetmoi.com/2015/08/check-list-revue-code-et-architecture-java/</link><pubDate>Thu, 27 Aug 2015 05:20:24 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1435</guid><description>&lt;p&gt;&lt;a href="wp-content/uploads/2015/08/clean_code_72_color.png"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="clean_code_logo"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2015/08/clean_code_72_color.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt; Réaliser des &lt;strong&gt;revues de code e&lt;/strong&gt; st une activité que je pratique régulièrement sur les projets que j’encadre techniquement. De manière général, elles &lt;strong&gt;se déroulent sur le poste du développeur&lt;/strong&gt;. Ce dernier me présente ses derniers changements, justifie ses choix et m’explique ses difficultés. En fonction de son expérience sur le projet, la périodicité des revues varie d’1 fois par jour à 2 fois par mois.
Les améliorations à apporter sont réalisées en séance en pair programming ou bien consignées directement dans le code à l’aide d’un TODO. Je profite de ces moments privilégiés pour expliquer et/ou échanger autour des règles de coding et d’architecture logicielle.&lt;/p&gt;
&lt;p&gt;Dans le cadre de l’ &lt;strong&gt;externalisation du développement&lt;/strong&gt; d’une application, les revues de code se pratiquent différemment. En effet, la livraison du code intervient souvent après un long effet tunnel. Dès le début des développements, les développeurs doivent connaître mes attentes. Ce billet a pour objectif de les formaliser de manière synthétique.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="clean_code_logo"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2015/08/clean_code_72_color.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Plateforme LAMP avec Docker Compose</title><link>https://javaetmoi.com/2015/07/plateforme-lamp-docker-compose/</link><pubDate>Wed, 15 Jul 2015 05:31:19 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1429</guid><description>&lt;p&gt;&lt;a href="wp-content/uploads/2015/07/docker-logo.jpg"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="docker-logo"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2015/07/docker-logo.jpg"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Afin de préparer la migration technique d’un site web, j’ai eu besoin de reconstruire un environnement à l’identique de la production.&lt;/p&gt;
&lt;p&gt;Hébergé sur un serveur Linux, ce site est propulsé par Apache 2.2, PHP 5.6 et MySQL 5.5.
C’était l’occasion parfaite pour découvrir &lt;strong&gt;Docker&lt;/strong&gt;. Une première étape consiste à décomposer cette plateforme LAMP en &lt;strong&gt;conteneurs&lt;/strong&gt; Docker ayant chacun leur responsabilité. Voici les 3 conteneurs identifiés :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;site&lt;/strong&gt;: conteneur Apache et PHP sur lequel les pages PHP du site sont déployées&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;database&lt;/strong&gt;: conteneur MySQL hébergeant la base de données utilisée par les pages PHP&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;phpmyadmin&lt;/strong&gt;: conteneur dédié à l’outil d’administration de base de données phpMyAdmin&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Pour orchestrer le démarrage des conteneurs, gérer leur configuration et définir leurs interactions, l’utilisation de l’outil &lt;a href="https://docs.docker.com/compose/"&gt;&lt;strong&gt;Docker Compose&lt;/strong&gt;&lt;/a&gt; paraissait évidente.&lt;/p&gt;
&lt;p&gt;Dans ce billet, vous trouverez le fichier docker-compose correspondant, un Dockerfile personnalisant l’image officielle php:5.6-apache, les lignes de commandes démarrant les conteneurs sous MacOSX et alimentant la base à partir d’un script SQL.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="docker-logo"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2015/07/docker-logo.jpg"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Personnaliser Spring Batch Admin</title><link>https://javaetmoi.com/2015/06/personnaliser-spring-batch-admin/</link><pubDate>Tue, 23 Jun 2015 19:15:14 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1410</guid><description>&lt;p&gt;&lt;a href="wp-content/uploads/2015/06/spring-batch-admin-screenshot.jpg"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="spring-batch-admin-screenshot"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2015/06/spring-batch-admin-screenshot.jpg"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt; Pour rappel, &lt;strong&gt;Spring Batch Admin&lt;/strong&gt; est une &lt;strong&gt;console de supervision des traitements par lots implémentés avec Spring Batch&lt;/strong&gt;. En plus d&amp;rsquo;un &lt;strong&gt;frontal web&lt;/strong&gt;, elle offre une &lt;strong&gt;API JSON&lt;/strong&gt; et expose des métriques via JMX.
Bien que dépendant du projet Spring Batch, Spring Batch Admin dispose de &lt;a href="https://github.com/spring-projects/spring-batch-admin"&gt;son propre repo GitHub&lt;/a&gt; et de son propre cycle de vie. Cet article se base sur la &lt;a href="https://spring.io/blog/2015/01/16/spring-batch-and-spring-batch-admin-releases"&gt;version 2.0.0.M1 sortie en janvier 2015.&lt;/a&gt; Développé en Spring MVC et composé de 3 JARs, Spring Batch Admin peut aussi bien être intégrée dans une application existante que déployée dans son propre WAR.&lt;/p&gt;
&lt;p&gt;Ouvert aux extensions, Spring Batch Admin a tout pour devenir un véritable &lt;strong&gt;serveur de batchs&lt;/strong&gt; : monitoring, chargement et mise à jour à chaud de la configuration des jobs, ordonnancement, exécution de jobs sur réception de fichiers …
En 3 ans, c&amp;rsquo;est la seconde fois que je suis amené à personnaliser Spring Batch Admin. Le manuel de référence fourmille d&amp;rsquo;explications. Ce billet recense quelques informations complémentaires qui, je l&amp;rsquo;espère, pourront vous être utiles :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Transformer Spring Batch Admin en une application auto-exécutable embarquant sa propre base de données et son propre conteneur de servlet&lt;/li&gt;
&lt;li&gt;Personnaliser l’interface d’admin&lt;/li&gt;
&lt;li&gt;Adapter les templates FreeMarker au besoin métier&lt;/li&gt;
&lt;li&gt;Exécuter un job suite à la réception d’un fichier&lt;/li&gt;
&lt;li&gt;Router un message en fonction du résultat de l’exécution d’un job&lt;/li&gt;
&lt;li&gt;Ajouter un contrôleur REST&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="spring-batch-admin-screenshot"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2015/06/spring-batch-admin-screenshot.jpg"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Embarquer Jetty dans une web app</title><link>https://javaetmoi.com/2015/06/web-app-jetty-standalone/</link><pubDate>Wed, 03 Jun 2015 05:19:45 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1339</guid><description>&lt;p&gt;&lt;a href="wp-content/uploads/2015/04/jetty-logo.png"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="jetty-logo"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2015/04/jetty-logo.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt; Une fois le développement d’une &lt;strong&gt;application web&lt;/strong&gt; terminé, vient le moment (douloureux ou non) de son &lt;strong&gt;installation sur un serveur&lt;/strong&gt;. En général, plusieurs pré-requis sont nécessaires : JRE, &lt;strong&gt;serveur d’application&lt;/strong&gt;, base de données … Aujourd’hui, Docker et/ou des outils comme Ansible et Puppet facilitent le provisionning du middleware. Néanmoins, il est possible de simplifier encore davantage cette phase d’installation. Des applications comme Sonar et Jenkins le font depuis des années : &lt;strong&gt;packager l’application avec son propre conteneur de Servlets&lt;/strong&gt; et sa propre base de données. Afin de pouvoir déployer des applications les plus légères possibles, les architectures micro-services poussent dans ce sens. Et c’est d’ailleurs ce que proposent des frameworks comme Play Framework et Spring Boot. Ce dernier permet en effet de créer un JAR exécutable démarrant au choix un Tomcat ou un Jetty.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ce billet explique pas à pas comment embarquer un conteneur Jetty dans sa propre application&lt;/strong&gt;. Nul besoin d’utiliser Spring ou Scala.&lt;/p&gt;
&lt;p&gt;Pour distribuer votre web app, vous aurez le choix entre :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;une &lt;strong&gt;archive ZIP&lt;/strong&gt; contenant JARs, scripts shells et fichiers de configuration.&lt;/li&gt;
&lt;li&gt;ou un unique &lt;strong&gt;JAR auto-exécutable&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Le packaging est assuré par différents plugins Maven.&lt;/p&gt;
&lt;p&gt;Disposer d’une JVM et le seul pré-requis. Sachant qu’OpenJDK est installé sur la plupart des distributions Linux, ce n’est pas nécessairement une contrainte. Seule la version de Java devra être vérifiée avec soin.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="jetty-logo"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2015/04/jetty-logo.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Plugin exit pour LogStash</title><link>https://javaetmoi.com/2014/11/plugin-exit-pour-logstash/</link><pubDate>Sun, 09 Nov 2014 11:15:07 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1254</guid><description>&lt;p&gt;&lt;a href="wp-content/uploads/2014/11/logstash.png"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="logstash"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2014/11/logstash.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt; Ce billet a pour objectif de vous présenter un cas d’usage du &lt;strong&gt;plugin exit&lt;/strong&gt; pour LogStash.
Une utilisation répandue de LogStash consiste à alimenter Elasticsearch à partir de fichiers de logs.
Extensible via un mécanisme de plugins, LogStash sait gérer plusieurs types de source et plusieurs types de destinations.
&lt;strong&gt;Une utilisation alternative de LogStash consiste à l’utiliser comme batch d’indexation&lt;/strong&gt;. Le fichier à indexer a une fin. Et &lt;strong&gt;l’utilisateur souhaite que LogStash s’arrête une fois les données importées&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="logstash"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2014/11/logstash.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Notes de migration vers JSF 2 et Richfaces 4</title><link>https://javaetmoi.com/2014/06/notes-migration-jsf2-richfaces4-jboss5-eap/</link><pubDate>Sat, 28 Jun 2014 16:19:58 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1165</guid><description>&lt;p&gt;&lt;a href="wp-content/uploads/2014/06/2014-07-jsf2-richfaces4-dans-jboss5-richfaces-logo.png"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="JBoss Richfaces Logo"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2014/06/2014-07-jsf2-richfaces4-dans-jboss5-richfaces-logo.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt; Début 2014, j’ai étudié la faisabilité technique d’une &lt;strong&gt;migration&lt;/strong&gt; de &lt;strong&gt;JSF 1.2&lt;/strong&gt; &lt;strong&gt;+ Richfaces 3.3&lt;/strong&gt; &lt;strong&gt;vers JSF 2.1 + Richfaces 4.3&lt;/strong&gt; sans changer de serveur d’application.
Notre serveur &lt;a href="https://access.redhat.com/site/articles/112673#EAP_5"&gt;JBoss 5.1 EAP&lt;/a&gt; étant certifié &lt;strong&gt;JavaEE 5&lt;/strong&gt;, la première difficulté consistait à &lt;strong&gt;désinstaller l’implémentation &lt;a href="https://javaserverfaces.java.net/"&gt;Mojarra&lt;/a&gt; de JSF 1.2 embarquée dans JBoss&lt;/strong&gt;. Cette opération est le pré-requis à l’installation de la version de JSF de son choix. Cette dernière aura alors pour unique contrainte d’être compatible avec le moteur de &lt;strong&gt;Servlet 2.5&lt;/strong&gt; sur lequel repose JBoss Web.
Plus classique, la seconde difficulté consistait à &lt;strong&gt;monter les versions de JSF et de Richfaces&lt;/strong&gt; d’une application existante.
J’ai arrêté mon étude après avoir migré le premier écran de cette application. Ayant conservé quelques notes, je me suis dit qu’elles pourraient intéresser certains ou certaines d’entre vous.
Ce billet commence par expliquer comment &lt;strong&gt;désinstaller JSF 1.2&lt;/strong&gt;, se poursuit par le déploiement du &lt;strong&gt;Showcase de Richfaces 4.3.5&lt;/strong&gt; dans JBoss 5.1 EAP et se termine par la mise à disposition de mes &lt;strong&gt;notes de migration&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="JBoss Richfaces Logo"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2014/06/2014-07-jsf2-richfaces4-dans-jboss5-richfaces-logo.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Plusieurs JBoss Messaging pour une même base</title><link>https://javaetmoi.com/2014/03/plusieurs-jboss-messaging-meme-base/</link><pubDate>Mon, 24 Mar 2014 18:26:20 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=1019</guid><description>&lt;p&gt;Ce billet ne devrait intéresser que les développeurs Java ou administrateurs JBoss en charge de la configuration de &lt;strong&gt;JBoss Messaging&lt;/strong&gt;, le broker JMS intégré aux versions 4.3 et 5.x du serveur d’application JBoss EAP.
Pour fil conducteur, prenons l’exemple d’une application Java EE déployée dans un pseudo cluster JBoss où, par choix d’architecture technique, &lt;strong&gt;chaque serveur JBoss est autonome&lt;/strong&gt;. A ce titre, les sessions HTTP ne sont pas partagées entre les différents serveurs JBoss ; le répartiteur de charge fonctionne en affinité de session De plus, chaque serveur dispose de ses propres files JMS (clustering JBoss Messaging non mis en œuvre). Les &lt;strong&gt;messages JMS&lt;/strong&gt; sont &lt;strong&gt;persistés dans une base de données&lt;/strong&gt;, Oracle dans notre cas &lt;strong&gt;.&lt;/strong&gt; La persistance des messages peut se faire de 2 manières :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Utiliser un schéma Oracle différent pour chaque serveur JBoss du cluster&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Utiliser le même schéma pour tous les serveurs JBoss du cluster&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;JBoss Messaging supportant le &lt;strong&gt;multi-tenancy&lt;/strong&gt;, cet article explique comment mettre en œuvre la 2ième solution.&lt;/p&gt;
&lt;p&gt;&lt;a href="wp-content/uploads/2014/03/2014-04-jboss-messaging-meme-schema.png"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="Architecture JBoss Messaging"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2014/03/2014-04-jboss-messaging-meme-schema.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="Architecture JBoss Messaging"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2014/03/2014-04-jboss-messaging-meme-schema.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Memory Leak du client CXF</title><link>https://javaetmoi.com/2014/02/memory-leak-client-cxf-attachment/</link><pubDate>Sat, 22 Feb 2014 09:28:31 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=977</guid><description>&lt;p&gt;Les tests de charge d’une nouvelle fonctionnalité m’a récemment permis de détecter un comportement inattendu de &lt;strong&gt;CXF&lt;/strong&gt; s’apparentant à une &lt;strong&gt;fuite mémoire&lt;/strong&gt;. Fusion de Celtix et de XFire, le &lt;a href="http://cxf.apache.org/"&gt;framework CXF&lt;/a&gt; propose une implémentation cliente et serveur de web services SOAP et REST. Le comportement suspect concerne la partie &lt;strong&gt;cliente&lt;/strong&gt; d’un &lt;strong&gt;web service SOAP&lt;/strong&gt; avec &lt;strong&gt;pièce-jointes&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Les symptômes ont été observés dans les conditions suivantes. Un tir de charge avec JMeter simule l’upload de fichiers de 4 Mo. Trente utilisateurs connectés simultanément uploadent des fichiers PDF. D’une durée de 5mn, le scénario fonctionnel mettant en jeu l’upload de fichiers est réitéré pendant 3h. A l’issu du tir, aucune erreur technique ou fonctionnelle n’est remontée. Par contre, l’analyse de l’empreinte mémoire est suspecte : non seulement cette nouvelle fonctionnalité a nécessité davantage de mémoire que lors des tirs précédents, mais surtout : &lt;strong&gt;la mémoire n’est jamais libérée&lt;/strong&gt;, même après l’expiration des sessions utilisateurs.&lt;/p&gt;
&lt;p&gt;&lt;a href="wp-content/uploads/2014/02/2014-02-cxf-attachments-memory-leak-2.jpg"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="2014-02-cxf-attachments-memory-leak-2"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2014/02/2014-02-cxf-attachments-memory-leak-2.jpg"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="2014-02-cxf-attachments-memory-leak-2"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2014/02/2014-02-cxf-attachments-memory-leak-2.jpg"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Développer et industrialiser une web app avec AngularJS</title><link>https://javaetmoi.com/2014/02/developper-industrialiser-web-app-recherche-angularjs/</link><pubDate>Sun, 09 Feb 2014 19:13:56 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=898</guid><description>&lt;p&gt;Au travers du billet &lt;a href="https://github.com/angular/angular-seed/blob/master/README.md"&gt;Elastifiez la base MusicBrainz sur OpenShift&lt;/a&gt;, je vous ai expliqué comment indexer dans &lt;strong&gt;Elasticsearch&lt;/strong&gt; et avec &lt;strong&gt;Spring Batch&lt;/strong&gt; l’encyclopédie musicale &lt;strong&gt;MusicBrainz.&lt;/strong&gt; L’index avait ensuite été déployé sur le Cloud &lt;strong&gt;OpenShift&lt;/strong&gt; de RedHat.&lt;br&gt;Une application HTML 5 était mise à disposition pour consulter les albums de musique ainsi indexés. Pour m’y aider, &lt;a href="https://twitter.com/lucianprecup"&gt;Lucian Precup&lt;/a&gt; m’avait autorisé à adapter l’application qu’il avait mise au point pour l’atelier &lt;a href="http://agenda2013.scrumday.fr/event/149"&gt;Construisons un moteur de recherche&lt;/a&gt; de la conférence Scrum Day 2013.&lt;br&gt;Afin d’approfondir mes connaissances de l’ &lt;strong&gt;écosystème JavaScript,&lt;/strong&gt; je me suis amusé à recoder cette &lt;strong&gt;application front-end&lt;/strong&gt; en partant de zéro. Ce fut l’occasion d’adopter les meilleures pratiques en vigueur : framework JavaScript MV*, outils de builds, tests, qualité du code, packaging …&lt;br&gt;Au travers de ce article, je vous présenterai comment :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Mettre en place un projet Anguler à l’aise d’ &lt;strong&gt;Angular Seed&lt;/strong&gt;, &lt;strong&gt;Node.js&lt;/strong&gt; et &lt;strong&gt;Bower&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Développer en full &lt;strong&gt;AngularJS&lt;/strong&gt; et &lt;strong&gt;Angular UI Bootstrap&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Utiliser le framework &lt;strong&gt;elasticsearch-js&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Internationaliser&lt;/strong&gt; une application Angular&lt;/li&gt;
&lt;li&gt;Tester unitairement et fonctionnellement une application JS avec &lt;strong&gt;Jasmine&lt;/strong&gt; et &lt;strong&gt;Karma&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Analyser du code source JavaScript avec &lt;strong&gt;jshint&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Packager avec &lt;strong&gt;Grunt&lt;/strong&gt; le livrable à déployer&lt;/li&gt;
&lt;li&gt;Utiliser l’ &lt;strong&gt;usine de développement&lt;/strong&gt; JavaScript disponible sur le Cloud : Travis CI, Coversall.io et David&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Le code source de l’application est bien entendu &lt;a href="https://github.com/arey/angular-musicbrainz"&gt;disponible sur GitHub&lt;/a&gt; et &lt;a href="http://angular-musicbrainz.javaetmoi.com/"&gt;testable en ligne&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="Angular MusicBrainz web app screenshot"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2014/02/angular-musicbrainz-screenshot.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Retour d’expérience sur les problématiques Elasticsearch</title><link>https://javaetmoi.com/2013/12/retour-experience-problematiques-elasticsearch/</link><pubDate>Mon, 16 Dec 2013 14:23:37 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=879</guid><description>&lt;p&gt;&lt;em&gt;« Près de 2 ans passés chez un client en tant que référent technique d’un &lt;strong&gt;middle de recherche&lt;/strong&gt; basé sur le moteur de recherche &lt;a href="http://www.elasticsearch.org/"&gt;Elasticsearch&lt;/a&gt;, il me paraît aujourd’hui opportun de vous faire part des différentes &lt;strong&gt;problématiques&lt;/strong&gt; rencontrées au cours des &lt;strong&gt;développements&lt;/strong&gt; et de son &lt;strong&gt;exploitation&lt;/strong&gt;. »&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;En 2 versions majeures et une montée de version d’Elasticsearch, les problématiques abordées ont été nombreuses : occupation mémoire, ré-indexation sans interruption de service, Split Brain, IDF et partitionnement. Prêts pour ce retour d’expérience ? »&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="Logo Elastisearch"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2013/12/logo-elastisearch.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Elastifiez la base MusicBrainz sur OpenShift</title><link>https://javaetmoi.com/2013/11/musicbrainz-elasticsearch-angularjs-openshift/</link><pubDate>Fri, 15 Nov 2013 19:35:01 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=782</guid><description>&lt;p&gt;Pour les besoins d’un workshop sur Elasticsearch, je me suis amusé à &lt;strong&gt;indexer une encyclopédie musicale&lt;/strong&gt; et à mettre en ligne une petite &lt;strong&gt;application HTML 5&lt;/strong&gt; permettant de réaliser des &lt;strong&gt;recherches&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Comme source de données musicale, j’ai opté pour &lt;strong&gt;&lt;a href="http://musicbrainz.org/" title="MusicBrainz Home"&gt;MusicBrainz&lt;/a&gt;&lt;/strong&gt; qui est une plateforme ouverte collectant des méta-données sur les artistes, leurs albums et leurs chansons puis les mettant à disposition du publique.&lt;/p&gt;
&lt;p&gt;Pour indexer les données depuis une base PostgreSQL, j’ai privilégié &lt;strong&gt;Spring Batch&lt;/strong&gt; au détriment d&amp;rsquo;une river. Pour l’IHM, j’ai adapté un prototype basé sur &lt;strong&gt;AngularJS&lt;/strong&gt;, jQuery et Bootstrap qu’avait réalisé &lt;a href="https://twitter.com/lucianprecup"&gt;Lucian Precup&lt;/a&gt; pour la &lt;a href="http://agenda2013.scrumday.fr/event/149"&gt;Scrum Day 2013&lt;/a&gt;. La mise en ligne de l’index Elasticsearch m’aura permis de tester la plateforme Cloud &lt;strong&gt;OpenShift&lt;/strong&gt; de Redhat.&lt;/p&gt;
&lt;p&gt;Cet article a pour objectif de décrire les différentes étapes qui m’ont été nécessaires pour réaliser ma démo et d’expliquer ce que j’ai librement rendu accessible sur &lt;a href="https://github.com/arey/musicbrainz-elasticsearch/blob/musicbrainz-elasticsearch-1.0.0/src/main/java/com/javaetmoi/core/batch/item/EsDocumentWriter.java"&gt;GitHub&lt;/a&gt; et &lt;a href="http://musicsearch.javaetmoi.com/"&gt;Internet&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="logo-musicbrainz"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2013/11/logo-musicbrainz.jpg"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Ecraser une branche par une autre avec Git</title><link>https://javaetmoi.com/2013/08/ecraser-une-branche-par-une-autre-avec-git/</link><pubDate>Thu, 01 Aug 2013 18:13:55 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=735</guid><description>&lt;a href="wp-content/uploads/2013/07/git-logo.png"&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="Logo du SCM GIT"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2013/07/git-logo.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt; Dans le cycle de vie d’une application, il arrive parfois qu’ &lt;strong&gt;une branche prenne le pas sur une autre branche&lt;/strong&gt; et qu’il soit nécessaire d’écraser la seconde par la première. Prenons l’exemple d’une application où, par convention, le master (ou le trunk sous SVN) est considéré comme la branche de développement (axée vers le futur) et que l’utilisation du système de branches soit habituellement consacrée aux branches de maintenance. Dans certaines circonstances (ex : nouveaux développements à commencer pour la version N+2, migration technique à réaliser …), une branche peut prendre le dessus du master. Afin de retrouver la convention d’origine, une &lt;strong&gt;recopie de la branche sur le master&lt;/strong&gt; va, à termes, être nécessaire. Que ce soit avec Git ou git-svn, nous allons voir comment &lt;strong&gt;&lt;a href="http://git-scm.com/"&gt;Git&lt;/a&gt;&lt;/strong&gt; peut nous y aider en &lt;strong&gt;quelques lignes de commande&lt;/strong&gt;.</description></item><item><title>Mod_headers à la rescousse du jsessionid</title><link>https://javaetmoi.com/2013/05/mod_headers-rescousse-jsessionid-jboss/</link><pubDate>Thu, 23 May 2013 18:45:16 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=692</guid><description>Au cours de la migration d’une cinquantaine d’applications web de Websphere vers &lt;strong&gt;JBoss 5.1 EAP&lt;/strong&gt;, nous avons été confrontés à un problème de sécurité mis en évidence par l’infrastructure de pré-production : le firewall bloquait systématiquement toute requête comportant un &lt;strong&gt;jsessionid&lt;/strong&gt; dans l’ &lt;strong&gt;URL&lt;/strong&gt;.
Modifier les règles du firewall pour laisser passer ce type de requêtes aurait introduit une faille de sécurité exploitable par appropriation de session web. Cette faille nous a d’ailleurs été révélée en parallèle par l’outil d’audit de sécurité &lt;a href="http://www-03.ibm.com/software/products/us/en/appscan/"&gt;IBM AppScan&lt;/a&gt;.
Ce billet rappelle l’origine du problème et précise quelle solution a été employée pour le résoudre le plus rapidement possible.</description></item><item><title>Promotion de code en continue avec git-svn</title><link>https://javaetmoi.com/2013/03/promotion-code-continue-merge-git-svn/</link><pubDate>Tue, 19 Mar 2013 19:48:16 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=626</guid><description>&lt;p&gt;Dans le cadre d’un important &lt;strong&gt;chantier&lt;/strong&gt; de &lt;strong&gt;migration technique&lt;/strong&gt; d’une &lt;strong&gt;application&lt;/strong&gt;, j’ai eu l’occasion de pratiquer ce que j’appellerais la &lt;strong&gt;promotion de code en continue&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Pour resituer le contexte, ce chantier dura plus de 6 mois. Entre le début et la fin de la migration, l’application a été livrée plusieurs fois en production, embarquant à chaque fois de nombreuses évolutions fonctionnelles. Nous avons donc dû nous organiser pour migrer l’application sans pénaliser l’avancement du reste de l’équipe.
Les changements techniques étant bien trop transverses à l’application, la stratégie de &lt;a href="http://martinfowler.com/bliki/FeatureToggle.html"&gt;Feature Toggle&lt;/a&gt; ne pouvait s’appliquer. Nous nous sommes donc dirigés vers une technique assimilable au &lt;a href="http://martinfowler.com/bliki/FeatureBranch.html"&gt;Feature Branch&lt;/a&gt; ; notre migration technique n’étant rien d’autre qu’une feature comme une autre. Logiquement, une branche dédiée à la migration a été créée.&lt;/p&gt;
&lt;p&gt;Notre stratégie fut de &lt;strong&gt;merger régulièrement dans cette branche le code issu de la branche de développement&lt;/strong&gt;. Une fois la migration terminée, la branche de migration a été à son tour mergée dans la branche de développement.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="Workflow de promotion en continue du trunk vers la branche"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2013/03/2013-03-promotion-continue-avec-git-svn.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;</description></item><item><title>Une bien mystérieuse UnknownHostException</title><link>https://javaetmoi.com/2013/01/unknownhostexception-jvm-version/</link><pubDate>Sun, 27 Jan 2013 18:29:58 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=587</guid><description>Après un précédent billet relatant un bug lié à la version du driver Oracle utilisé, voici un nouveau billet portant sur &lt;strong&gt;bug&lt;/strong&gt; lié, cette fois ci, à la &lt;strong&gt;version de la JVM utilisée&lt;/strong&gt;. Ce bug nous a été révélé très tardivement dans le cycle de développement de l’application Java incriminée. En effet, PV de recette en poche, les tests de charge menés avec JMeter sur l’environnement de pré-production ne nous avaient rien révélé. Seuls les tests de robustesse nous ont alertés d’une mystérieuse &lt;strong&gt;&lt;em&gt;java.net.UnknownHostException&lt;/em&gt;&lt;/strong&gt; survenant 4 à 5 minutes après l’arrêt volontaire d’une application tierce.</description></item><item><title>Oracle : dis-moi quelle heure est-il ?</title><link>https://javaetmoi.com/2013/01/bug-date-heure-drivers-oracle-10g-9i/</link><pubDate>Sat, 19 Jan 2013 18:14:11 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=564</guid><description>&lt;p&gt;Récemment, je suis tombé sur un &lt;strong&gt;bug&lt;/strong&gt; lié à l’utilisation d’une &lt;strong&gt;version de driver&lt;/strong&gt; &lt;strong&gt;JDBC pour Oracle&lt;/strong&gt; plus récente que la version de la base Oracle attaquée en SQL via JDBC.&lt;/p&gt;
&lt;h1 id="les-symptômes"&gt;Les symptômes&lt;/h1&gt;
&lt;p&gt;Dans notre contexte applicatif, la date et l’heure des données lues en base sont utilisées pour détecter des conflits de version, d’une manière similaire au versioning Hibernate. Concrètement, cela nous permet d’éviter qu’une donnée traitée par batch quotidien écrase une donnée plus fraiche provenant d’un système tiers. Ce mécanisme permet notamment d’exécuter un batch sans interruption de service de l’application web associée. Le bug que je vais vous décrire nous a été révélé tardivement. Sous certaines conditions, nous avons en effet constaté que le batch ne rattrapait jamais des données. C’est &lt;strong&gt;comme si l’heure n’était jamais prise en compte&lt;/strong&gt; &lt;strong&gt;dans le code Java&lt;/strong&gt;.&lt;/p&gt;</description></item><item><title>Isoler le classloader de son EAR sous JBoss</title><link>https://javaetmoi.com/2013/01/isoler-classloader-ear-jboss/</link><pubDate>Sat, 05 Jan 2013 09:41:40 +0000</pubDate><guid isPermaLink="false">http://javaetmoi.com/?p=520</guid><description>&lt;p&gt;Lors de la &lt;strong&gt;migration&lt;/strong&gt; d’une application d’un &lt;strong&gt;serveur d’application&lt;/strong&gt; vers un autre, il est fréquent d’être confronté à des problématiques de &lt;strong&gt;conflits de librairies&lt;/strong&gt;. C’est par exemple le cas lorsqu’une application initialement déployée sur un Websphere Application Server 6.1 doit migrer sur &lt;strong&gt;JBoss 5.1 EAP&lt;/strong&gt; (version commerciale de JBoss AS).
Pour rappel, WAS 6.1 implémente J2EE 1.4 et s’exécute donc sur Java 5. Quant à JBoss 5.1 EAP, il implémente la norme Java EE 5, embarque donc de nombreuses implémentations des standards tels que JPA 1, JSF 1.2 et JAX-WS 1, et tourne sur Java 6.&lt;/p&gt;
&lt;p&gt;Pour illustration, prenons une application s’appuyant sur Hibernate 3.6 pour sa couche de persistance et JAXB 2.2 pour le marshalling lors d’appel de web services. Ces 2 librairies sont embarquées dans le répertoire lib de son EAR et ne posent pas de problèmes particuliers à WAS 6.1.
Par contre, sur JBoss 5.1 EAP, c’est un tout autre problème. En effet, son implémentation JPA repose sur la version 3.3 d&amp;rsquo;Hibernate. Qui plus est, JAXB 2.1 a été intégrée dans Java 6.
Si vous tentez de déployer une telle application sur un JBoss installé avec la configuration par défaut, il y’a de fortes chances que vous tombiez sur l’une ou l’autre des exceptions suivantes : &lt;em&gt;ClassCastException&lt;/em&gt;, &lt;em&gt;NoSuchMethodException, IllegalAccessErrors&lt;/em&gt;, &lt;em&gt;VerifyError.&lt;/em&gt;
A ce que j’ai compris en parcourant la documentation mais également déduis de mes tests, différents mécanismes permettent d’expliquer ces comportements :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Par défaut, lors du chargement d’une classe, le classloader de l’EAR va commencer par demander à son classloader parent (en l’occurrence celui de JBoss) de trouver la classe. Ainsi, c’est par exemple la classe Session d’Hibernate 3.3 qui sera chargée et non celle de la version 3.6 comme attendu. Il s’agit du comportement standard d’un classloader. Et c’est ce qu’on appelle communément le « j2se classloading compliance ». Sous WAS, cette stratégie de chargement peut être changée en paramétrant le classloader en PARENT_LAST.&lt;/li&gt;
&lt;li&gt;Les classes chargées par d’autres applications déployées sur la même instance de JBoss peuvent être partagées par votre application. Par exemple, la console d’admin JBoss admin-console.war embarque sa propre version de Richfaces et de Seam et peut, malgré elle, vous en faire bénéficier.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="solutions-étudiées"&gt;&lt;em&gt;Solutions étudiées&lt;/em&gt;&lt;/h2&gt;
&lt;p&gt;Pour mener à bien la migration, plusieurs pistes ont été étudiées :
&lt;strong&gt;Solutions&lt;strong&gt;&lt;strong&gt;Inconvénients&lt;/strong&gt;&lt;/strong&gt;Avantages&lt;/strong&gt;1Downgrader les versions des frameworks pour utiliser celles embarquées dans JBoss 5.1Important travail de refactoring pour combler les fonctionnalités manquantes.
Bugs existants récupérés.Respect de la norme Java EE 5.
Support éditeur maximal.2Configurer sur mesure le répertoire d’installation de JBoss (ex : supprimer le support des EJB 3 et de JPA)Mutualisation du répertoire d’installation rendue caduque.
Main sur la production _._Un JBoss qui démarre plus vite.
Pas d’impact sur le code.3Isoler le déploiement de l’applicationLire la documentation JBoss.
Augmentation possible de la PermGen.Risque nul.
Simple configuration.
Configuration embarquée dans l’EAR.&lt;/p&gt;
&lt;h2 id="configurer-le-classloader-de-lapplication"&gt;Configurer le classloader de l’application&lt;/h2&gt;
&lt;p&gt;&lt;figure&gt;
&lt;picture&gt;
&lt;img
loading="lazy"
decoding="async"
alt="@Copyright JBoss - Classe chargée en priorité depuis l&amp;amp;amp;rsquo;EAR:right"
class="image_figure image_internal image_unprocessed"
src="https://javaetmoi.com/wp-content/uploads/2013/01/JBoss-ClassLoading-Scoped-Java2ParentDelegationOff-300x202.png"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Pour mettre en œuvre la solution n°3 concernant à « scoper » l’application, il est nécessaire de configurer le chargement des classes de JBoss . Une description détaillée de son fonctionnement est disponible sur la page &lt;a href="https://community.jboss.org/wiki/JBossClassLoadingUseCases"&gt;JBossClassLoadingUseCases&lt;/a&gt; du wiki de JBoss.
Dans notre cas, La configuration des classes loaders nécessaire est &lt;strong&gt;deployment scoped&lt;/strong&gt; et &lt;strong&gt;Java2ParentDelegation&lt;/strong&gt; &lt;strong&gt;désactivé&lt;/strong&gt;. Cette configuration est représentée par la figure ci-contre.&lt;/p&gt;
&lt;p&gt;Cette configuration présente les 2 avantages suivants :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Les JARs embarqués dans l&amp;rsquo;EAR priment sur celles fournies par JBoss 5.1 et le JRE.&lt;/li&gt;
&lt;li&gt;Chaque application déployée sur le même serveur possède son propre UnifiedLoaderRepository (ULR). Le chargement des classes est isolé et n&amp;rsquo;interfère pas. Elles sont également isolées du chargement des applications tierces (ex: jmx-console et admin-console).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;La configuration du fichier &lt;code&gt;jboss-app.xml&lt;/code&gt; à déposer dans le répertoire META-INF de l’EAR est décrite sur la page &lt;a href="https://community.jboss.org/wiki/ClassLoadingConfiguration"&gt;ClassLoadingConfiguration&lt;/a&gt; du wiki JBoss. En voici un exemple :
Lors de la &lt;strong&gt;migration&lt;/strong&gt; d’une application d’un &lt;strong&gt;serveur d’application&lt;/strong&gt; vers un autre, il est fréquent d’être confronté à des problématiques de &lt;strong&gt;conflits de librairies&lt;/strong&gt;. C’est par exemple le cas lorsqu’une application initialement déployée sur un Websphere Application Server 6.1 doit migrer sur &lt;strong&gt;JBoss 5.1 EAP&lt;/strong&gt; (version commerciale de JBoss AS).
Pour rappel, WAS 6.1 implémente J2EE 1.4 et s’exécute donc sur Java 5. Quant à JBoss 5.1 EAP, il implémente la norme Java EE 5, embarque donc de nombreuses implémentations des standards tels que JPA 1, JSF 1.2 et JAX-WS 1, et tourne sur Java 6.&lt;/p&gt;</description></item></channel></rss>