En ajoutant un nouveau composant à une application J2EE, j’ai vu le temps de déploiement se multiplier par plus que 3. Bien que cela n’aie pas beaucoups d’importance sur un environnement de production, cela est critique dans un environnement de développement :
- Perte de temps : si on déploie 5 fois par heure et avec 2 minutes par déploiement, c’est plus d’une heure de travail perdue par jour.
- Perte de perfomance : La Rupture du Flux mental due au déploiement lent réduit d’autant l’efficacité du développeur.
- Perte de qualité : La tendance qu’on aura alors à déployer moins va faire qu’on réalisera moins de test, qu’on auras moins tendance à améliorer ou optimiser le code …
Mais que se passe-t-il donc ? Le threaddump nous dira
En regardant les logs, je voyais bien qu’au déploiement l’ancienne version d’application était “dé-déployée” en quelques secondes puis le JBoss marquait une pause de plusieurs secondes avant de commencer le déploiement de la nouvelle version, sans aucune ligne de log. Que faisait-il donc pendant cette période ?
Pour diagnostiquer cela, la JVM nous permet de faire des ThreadDump, il s’agit d’une photo instantanée de ce qu’est en train de faire la VM.
Il existe pour cela plusieurs outils, j’ai utilisé VisualVM mais il existe d’autres moyens (kill -3 <PID>
sous unix, jstack, Outil IBM …)
Dans les différents ThreadDump réalisés pendant cette pause de JBoss, j’ai remarqué qu’il y avait un point commun : l’AnnotationScanningPlugin. En effet, depuis J2EE 5 la configuration en XML a été allégée voir rendue optionnelle en faveur d’annotation dans le code. Plutôt propre et pratique comme approche. Seulement voila : cela oblige le serveur d’application à parcourir l’ensemble des classes pour rechercher d’éventuelles annotations.
Optimiser le scan d’annotation sur JBoss
Je vous passe le gros défaut de JBoss : la documentation, toujours difficile de trouver de la documentation de référence à jour. Après quelques recherches, j’ai en effet trouvé que depuis le AS5, un fichier jboss-scanning.xml
permet d’optimiser cette étape voir Wiki JBoss ici. Dans mon cas c’était un war
, j’ai donc crée jboss-scanning.xml dans le WEB-INF.
Avec le contenu suivant par exemple, JBoss limite le scan au package com.acme.foo
mais sans parcourir les classes de com.acme.foo.bar
:
<scanning xmlns="urn:jboss:scanning:1.0">
<path name="WEB-INF/classes">
<include name="com.acme.foo"/>
<exclude name="com.acme.foo.bar"/>
</path>
</scanning>
Et pour empêcher totalement le scan on peut utiliser :
<scanning xmlns="urn:jboss:scanning:1.0">
<path name="WEB-INF" excluded="true"/>
</scanning>
Pour comprendre le format de ce fichier, la seule documentation que j’ai trouvée est le code source annoté en JAX-B
Résultat : 2/3 de gain de temps au déploiement
Le temps de déploiement a été réduit de 2/3 et un gain en ergonomie et en temps considérable pour l’équipe de développement.