Troisième et dernière journée au Devoxx. C’est avec une certaine nostalgie que nous avons fait notre dernier tour sur les stands et assisté aux derniers talks. Mais avant de vous donner nos impressions sur les conférences, un bref retour sur la Keynote.

La Keynote : Accessibilité, bien être et HumanOps au programme

Comme précisé lors des débriefs des précédentes journées, le thème central de cette édition était le bien être au travail. Aujourd’hui nos emplois occupent une place très importante de notre vie. Se sentir bien et épanouie sur notre lieu de travail est donc essentiel a notre rayonnement personnel. Malheureusement il existe bien des écueils sur l’océan de sérénité sur lequel on souhaiterait voguer. C’est en partant de ce prédicat que trois speakers nous ont parlé d’accessibilité, de bien être et de bienveillance au travail.

Accessibilité

Speaker(s) : Valérie Haccart

Créatrice chez Alphasens (une auto-entreprise qui sensibilise à la déficience visuelle, Valérie Haccart nous a expliqué l’importance de l’accessibilité au travail. On pourrait penser qu’il s’agit uniquement de la mise en place d’infrastructures facilitant l’accès aux personnes handicapées, mais nous apprenons que même nous, développeurs, pouvons favoriser l’accessibilité notamment aux personnes non voyantes. En effet, après avoir fait tester plusieurs paires de lunettes simulant différentes pathologies de mal voyance à quelques volontaires, Valérie nous a sensibilisé à la nécessité de respecter certaines bonnes pratiques de développement afin que des outils de type « lecteurs d’écrans » (utilisés par les personnes non voyantes) puissent interpréter correctement le HTML des pages que nous créons.

A titre d’exemple :

  • toujours renseigner l’attribut alt des balises d’images -> les personnes non voyantes ne verront pas une image de chat, c’est le lecteur d’écrans qui lui donnera des indications via interprétation de l’attribut alt
  • respecter l’ordre des balises titres (h1, h2, h3, …)
  • indiquer la langue du contenu de la page HTML avec l’attribut lang

Une nouvelle fois bravo pour ce talk.

Le refactoring le plus difficile de ma carrière

Speaker(s) : Jérôme Petazzoni

Il s’agissait ici d’un retour d’expérience, mais pas n’importe lequel. Jérôme Petazzoni ne nous a pas parlé de la migration d’un bon gros monolithe vers une architecture microservices, ni du passage d’une application en Java 6 vers Java 11 … mais du refactoring de sa propre vie. Il nous a présenté la différence entre dépression et burn out, trop souvent considéré comme « un manque de volonté » ou un « petit coup de fatigue », et pas suffisamment comme une vraie maladie. Il nous a parlé de sa propre expérience, et du fait que même si il est passionné par son travail, une surcharge d’activité engendre la sensation de ne plus avoir de temps pour soi et de passer à côté de beaucoup de choses importantes. Et l’accumulation conduit au burn out, comme lui-même l’a vécu.
Il terminera sa présentation en donnant ce qui lui a permis de s’en sortir et de retrouver un certain équilibre, sans pour autant donner de « recette miracle » car « ce qui fonctionne pour moi ne fonctionnera peut-être pas pour quelqu’un d’autre ».

Il faut cependant souligner une chose essentielle qui, elle, aura une importance capitale pour toute personne en baisse de régime : l’entourage est vital, et sur le lieu de travail un bon manager sera toujours d’un grand secours.

Le talk disponible ici.

Philosophy of HumanOps

Speaker : David Mytton

 

Comprendre les pics de stress, comment détecter les baisses de motivations, anticiper l’impact des problèmes « humains » sur le business… c’est ce que nous a proposé d’explorer David Mytton au cours de sa conférence en parcourant les tenants et aboutissant du courant « HumanOps ».

L’idée ici est de rappeler que les personnes chargées du bon fonctionnement des systèmes, les Ops, sont humains et que leur état de santé peut être influencé par une trop forte sollicitation ou un mauvais management. Et qui dit impact humain dit forcément impact sur le système complet à court terme. L’importance de la santé des équipes a donc été re-soulignée, rappelant qu’elle est aussi importante que la santé des systèmes eux mêmes. L’objectif était de redonner quelques astuces pour prendre soin d’une équipe, en prônant le dialogue avec les membres qui la compose ou en respectant les temps de repos nécessaire à tout être humain.

Les dernières conférences de cette édition 2019

 

L’intégration continue comme partenaire pour des suggestions d’amélioration des tests

Speakeuse : Caroline Landry

Vous connaissez peut-être le mutation testing, cette technique qui permet de déterminer la qualité d’une base de code de test. Le principe n’est pas très compliqué :

  • on fait muter le code de production (en inversant une condition dans un if par exemple)
  • on exécute l’ensemble des tests
  • on confirme que le code muté est bien « tué » par les tests unitaires (ce qui prouve que les tests ne laissent pas passer de défauts).

Dans l’écosystème Java, c’est PIT qui est majoritairement utilisé.

Les cast codeurs, ont largement parlé de cet outil, et d’une initiative de partenariat entre des chercheurs et des entreprises de « l’industrie » pour expérimenter des nouvelles méthodes de test , je vous encourage à écouter l’épisode 189 si vous souhaitez en savoir plus sur le sujet !

C’est justement une membre de cette initiative, le STAMP, qui était présente à Devoxx pour présenter ce sujet d’étude, et plus particulièrement l’Extreme Mutation et les Test Amplifiés.

Un des problèmes que l’on rencontre avec le mutation testing est la lenteur d’exécution de ces analyses. Chaque instruction pouvait faire l’objet d’une mutation fait l’objet d’une exécution de l’ensemble du jeu de test afin de déterminer si les mutants sont tués ou non.

Extreme Mutation

Une piste d’amélioration (en terme de rapidité d’exécution) consiste alors à supprimer totalement le corps de la méthode mutée, à lui faire retourner une constante (s’il s’agit d’une fonction) et à vérifier si les tests échouent. Ainsi, plutôt que d’avoir n mutations dans une méthode, nous n’en aurons plus qu’une, ce qui réduira grandement la durée d’exécution.

L’Extreme Mutation permet alors de trouver des méthodes pseudo-testées, qui sont « couvertes » par les tests, car elles sont exécutées, mais dont on ne valide pas le bon fonctionnement.

L’équipe de STAMP a développé Descartes, un plugin de PIT, qui implémente cette stratégie de mutation testing, qui vient du monde de la recherche.

Tests amplifiés

Les tests amplifiés quand à eux consistent à faire muter la base de code de test, afin de proposer automatiquement des nouveaux cas de tests, qui pourront être ajouté si le développeur considère que cet ajout est pertinent.

Cette technique expérimentale fait l’objet d’un autre outil, développé par STAMP également : DSpot.

Les slides du talk, qui permettent d’illustrer les différents concepts sont disponibles ici : https://www.slideshare.net/CarolineLandry/the-ci-as-a-partner-for-test-improvement-suggestions

Clean code : Le nommage

Speakeuse : Michelle Avomo

Michelle, co-animatrice de la communauté Craft chez SOAT, a relevé le challenge de parler de clean code, et plus particulièrement du nommage en 15 minutes.

En partant d’un code totalement illisible, elle a donné quelques techniques de refactoring pour réussir à comprendre du code, exprimer son intention par le code (plutôt que par des commentaires obsolètes), …

Malheureusement le temps dédié à la présentation n’a pas permis d’arriver au résultat qu’elle a publié sur Github, mais ce talk est une très bonne introduction au clean code et au craft de manière générale !

Métriques, Traces : instrumenter votre code Java, Node.js, Python, Go … avec Opencensus

Speakers : François Samin et Benjamin Coenen

Les métriques et traces tiennent une place importante dans la vie de nos applications. C’est en partant de ce constat que François Samin et Benjamin Coenen nous on fait découvrir Opencensus.

Le talk a tout d’abord débuté par un rappel sur :

  • les logs qui reprennent l’historique des événements ayant affectés notre application
  • les métriques qui sont très utiles pour visualiser en temps réel, via des dashboards, les défaillances du système sans pour autant en donner l’origine.
  • les traces qui permettent d’établir le diagnostic d’une défaillance.

S’en est suivie une rapide présentation de solutions comme Jaegger (pour représenter des traces sur une échelle de temps) et Prometheus / Grafana (pour la collecte et l’affichage de métriques).

Le but de cette introduction était de nous faire remarquer que même si cela est très utile, l’ajout de traces et métriques engendrait de l’ajout de code (ce qui est long et fastidieux, sans parler des duplications potentielles).

Cette remarque sera le point de départ de la présentation a proprement parlé d’Opencensus.

Il s’agit d’un framework Opensource disponible pour de nombreux langages et permettant d’exposer facilement des traces et metriques uniformes à destination d’un large panel de backends. Parmis ces backends nous avons déjà cité Jaegger mais il y en a bien d’autres (Prometheus, Datadog, Zipkin, …). L’autre point fort d’Opencensus est qu’il permet de faire du monitoring distribué via ID de corrélation, idéal pour sur des architectures à base de microservices.

Le talk s’est terminé avec la traditionnelle démo, durant laquelle les speakers nous ont montré comment exposer les informations avec Opencensus et les traiter avec Prometheus, Grafana et Jaegger.

L’exposition de traces et métriques avec Opencensus devient moins contraignante !

Gradle, je t’aime: moi non plus.

Speakers : David Wursteisen et Jeremie Martinez

Récemment, on m’a demandé « pourquoi on a pas utilisé Gradle sur notre nouveau projet ? », et j’ai été forcé d’admettre que la seule raison était « Bah … j’utilise Maven depuis 10 ans, donc : par habitude ».

Oui, Maven marche très bien, et son écosystème est énorme, mais il peine à mobiliser la communauté pour évoluer, et quand on compare le rythme de release des deux outils, on constate très vite que Gradle est bien plus vivant.

Pour les plus curieux, les cast codeurs parlent de l’historique de Maven et du manque de dynamisme de sa communauté dans l’épisode 180, alors qu’il est toujours très largement majoritaire dans l’écosystème Java.

Comme pour JUnit 5 : lançons nous !

David et Jeremie, de Margo Bank, ont eu la tâche de mettre en place un Core Banking System from scratch. La question du build s’est vite posée. Entre Maven, Bazel, Buck et Gradle, leur choix s’est porté vers Gradle.

Ils ont pu mettre en place un système de build complet, en utilisant le système de plugin pour diffuser les standards de leur société facilement sur tous les projets, et utiliser une approche plus déclarative grace au langage Kotlin (qu’ils avaient justement choisi pour le développement de leurs applications).

La JVM et Docker, vers une symbiose parfaite !

Speakers : David Delabassee

Les containeurs sont désormais très utilisés pour le déploiement de nos applications. Dans cette présentation, nous découvrons comment optimiser l’utilisation de Java et de la JVM. David travaille au sein d’une équipe de développeur dédiée au Serverless chez Oracle et contribue au projet Fn qui est une plate-forme de conteneurs native serverless basée sur Docker.

Tout commence par une rapide explication de ce que sont les containeurs et leur écosystème :

  • les outils (docker-maven-plugin, Testcontainer,…),
  • les frameworks (Helidon, Quarkus,…)
  • les Faas (Fn Project, OpenFaas,…)

Ensuite les attentes quand on utilise une JVM dans un container :

  • pas de latence (performance : démarrage rapide du container et de l’application)
  • un comportement correct

David passe rapidement sur les problématiques liées au réseau en conseillant de co-localiser la registry (archives) des images, d’utiliser un cache pour faciliter le temps de chargements en utilisant par exemple Kraken d’Uber.

Pour réduire la taille de l’image, on peut intervenir sur 3 axes :

  • l’applicatif et ses dépendances
  • le runtime Java
  • le système d’exploitation

Au niveau applicatif en Java, faire attention aux dépendances embarquées et celles qui sont transitives, utiliser le cache Docker pour tout ce qui est statique permet d’alléger l’image.

Une première démonstration nous fait rentrer dans le vif du sujet en s’appuyant sur Docker et une petite application en Java qui retourne juste quelques informations sur le container en fonctionnement, le fil conducteur est la taille de l’image qui est générée.
En utilisant un Dockerfile, une première image de 815 Mo est produite avec une distribution « openjdk:11 », ce qui est énorme au vue de la simplicité de l’application, en passant à « openjdk:11-slim » un gain de 300 Mo est obtenu. En conlusion embarquer le JDK est inutile, pour fonctionner le JRE est suffisant (openjdk:11-jre-slim) ce qui permet d’obtenir une image de 273 Mo.

Concernant l’OS, il est possible d’utiliser « Alpine » qui est une distribution Linux optimisée d’environ 4 Mo, le soucis est qu’OpenJDK utilise la librairie « libc » pour faire le lien entre Linux et la JVM et Alpine la librairie « musl », le projet Portola permet de résoudre ce problème qui utilise « musl » pour pouvoir builder OpenJDK.

Un gros travail peut être fait sur le runtime en utilisant la modularité mise en place depuis la version 9 de Java. Pour cela il faut utiliser « jlink » qui permet de gérer et optimiser les modules qui seront assemblés dans un JRE customisé. On peut par exemple, ne pas embarquer les man pages, les fichiers de header, etc et une compression est possible mais qui est a utiliser avec parcimonie. David donne comme exemple pour une fonction serverless en embarquant uniquement les modules necessaires, il peut obtenir un JRE de 32 Mo, la où le JDK pèse plus de 300 Mo basé sur la version 12 de Java. Une rapide démonstration de tout cela est faite en s’appuyant sur « Alpine », « Fn » et « jlink » et une inspection de l’image générée avec « Dive » pour vérifier les différents parties (layer) qui constitue l’image.

Il est aussi possible d’intervenir sur le temps de démarrage des applications avec CDS (Class Data Sharing) disponible depuis Java 6.5. Pour cela les classes sont chargées en mémoire, cette représentation en mémoire est sérialisée et sauvegardée sur disque et c’est cet enregistrement qui sera rappelé en mémoire au prochain démarrage. Un test est réalisée en live sur une application de type HelloWord est montre un gain de temps de l’ordre de 70 %. Un parallèle est fait avec GraalVM en utilisant la fonctionnalité « native-image » qui permet de générer un binaire exécutable natif de l’application précédente, l’opération, qui peut être longue, est a réalisée lors du build, mais le temps de démarrage n’est plus que de quelques milliseconde ! Mais avec certaines limitations, comme par exemple la réflexion qui peut poser problème.

Le fonctionnement correct de la JVM est le dernier point abordé au travers de la relation entre les containers et la JVM, cohabitation qui sera amélioré dans les prochaines releases de d’OpenJDK. « Ergonomics » présent dans la plateforme Java permet à la JVM de s’adapter à des contraintes de performances et de latences. Des flags (il en existe plus de 650 dans la JVM ?!) autorisent la customisation de la configuration mais ne fonctionne que sur les versions récentes de Java. Une démonstration est réalisée montrant comment optimiser l’allocation et le nombre de CPUs alloués a un containeur Docker.

Pour terminer, David fait un bilan des différentes solutions qu’il nous a proposé et en profite pour parler de la sécurité et des vulnérabilités, qu’il est possible de limiter en fonction du choix de la version de Java qui doit être activement supportée et faire attention aux sources des images Docker que l’on utilise.

Cette conférence était très enrichissante, elle a permit de découvrir des outils et des concepts que l’on ne connaît pas forcement sur les liens entre la JVM, Java et Docker et ouvre la voie à des réflexions à avoir sur l’utilisation des conteneurs qui accueillent les applications que l’on développe.

À la découverte de Bazel

Speakers : Paul Boutes

Un outil de build de plus dans la multitude de ceux qui existent pour le backend ou le frontend comme Maven Gradle, sbt, webpack, grunt, etc. C’est sur cette constatation que commence la présentation de Paul qui travaille comme ingénieur chez Elastic. Bazel est open source dont le contributeur principal est Google, cette solution est rapide, reproductible pour le build ou les tests.

Bazel veut proposer :

  • du build incrémental (temps de rebuild dépendant de changement dans le code)
  • une herméticité (autorise un parallélisme des builds)
  • un déterminisme (qui permet la mise en place de cache sur les paramètres d’entrée)
  • une extensibilité (pour pouvoir ajouter des comportements spécifiques)
  • un agnosticisme (permettant de builder ce que l’on veut)

La liste des langages utilisables est conséquente : C/C++, Go, Kotlin, Java, Typescript et bien d’autres.
Le fonctionnement de Bazel est une succession d’actions (builder, linter, tester) qui ont comme entrants des outils, du code, des fichiers de conf, etc et comme sortant un fichier jar ou tout autre artifact. Le chaînage de ces actions permet de composer un « graphe » de build. Lors de ces opérations un hash (SHA1) est calculé sur les entrants des actions, ce qui permet de détecter des changements engendrant une recompilation uniquement de ce qui est nécessaire et c’est aussi grâce à cela qu’une gestion de cache est possible. C’est ainsi que l’outil optimise le build lors des lancements suivants.

L’organisation de Bazel est la suivante :

  • un workspace est définit à la racine du projet par un fichier du même nom (WORKSPACE), qui contiendra des liens symboliques qui pointeront vers les artifacts générés par l’outil.
  • les packages avec le code source et dans lesquels doit apparaître un fichier BUILD.bazel qui permet de savoir qu’il a des sources a utiliser
  • dans le fichier BUILD.bazel sont définis les targets qui sont les tâches à réaliser (compiler, tester, générer un binaire, etc), définies avec le langage Starlak (sous-ensemble de python) qui est très limité

Il existe 3 phases lors du build :

  • phase de chargement : permet la création du graphe de dépendances du build, duquel on peut extraire des informations
  • phase d’analyse : qui configure le graphe, qui permet par exemple de connaître la plateforme qui sera utilisée
  • phase d’exécution : opération réalisée a partir du graphe précédemment configuré

Bazel est utilisé en ligne de commande ce qui peut autoriser une intégration dans la chaîne CI/CD.
Paul fait une démonstration basée sur une application basique développé avec Java Springboot et Scala, cela permet de découvrir comment gérer les dépendances,  produire un binaire et fournir un containeur sans Docker car Bazel dispose de son implémentation pour cette opération.

Cette présentation permet de découvrir un outil de build récent (né en 2015) et multi-langage. Bazel est donc une solution intéressante mais qui demande un certain temps d’apprentissage car il faut intégrer de nouveaux concepts.

En conclusion, une édition 2019 réussie

Au delà des quelques aléas rencontrés durant l’heure du déjeuné et l’absence de tshirt dans les traditionnels sacs du conférencier distribués chaque année, le reste de l’événement est un sans faute. Nous avons assisté à des talks de qualité, observé une tendance très Cloud dans les sujets abordés, et avons pu échanger avec des personnes très abordables sur les stands, qui au demeurant étaient tous très bien animés : beaucoup de goodies et de tshirts disponibles mais aussi des Nintendo Switch, enceintes connectées et Toblerones géants à gagner !

Nous rentrons chez nous avec la tête pleine de nouvelles idées, et la valise pleine de stickers et de livres blancs 🙂

 

Vivement la prochaine édition !

Liens utiles