Javanalyser cartographie vos programmes Java pour une maintenance simplifiée
La maintenabilité des logiciels, difficile à mesurer pèse lourd sur les budgets et la performance des équipes. Javanalyser promet de changer la donne en cartographiant le code pour mieux l’analyser.
Le coût élevé de la maintenance des logiciels exige de travailler sur leur maintenabilité. Bien qu’émergente de la structure du code source, son évaluation est subjective, car elle dépend des développeurs et du contexte. Or les méthodes et les modèles de maintenabilité actuels tendent à réduire la maintenabilité à un score unidimensionnel. De plus, ce score est basé sur des métriques souvent mal définies et représente parcellairement la structure du code.
Dans le cadre de son doctorat en partenariat entre Onepoint et l’université de Bordeaux, Sébastien Bertrand, chercheur en informatique et cognitique, a étudié cette problématique. En se concentrant sur la modélisation de la structure des programmes pour analyser leur maintenabilité, il a développé un outil libre appelé Javanalyser. Cet outil permet de générer automatiquement le graphe de code d’un programme Java.
Ces travaux ouvrent la voie à une compréhension plus approfondie de la maintenabilité. De plus, il prend en compte la variabilité entre développeurs grâce à une représentation multidimensionnelle de la maintenabilité.
Le coût prohibitif de la mauvaise structure des programmes
La maintenabilité est un enjeu central en programmation informatique. Dès 1968, Dijkstra publie un article emblématique de cette préoccupation : « Go To Statement Considered Harmful[1] ». Selon l’auteur, la qualité du code est une fonction décroissante de la densité d’instructions GOTO. Cette dernière réalise un saut inconditionnel à n’importe quel autre endroit du programme. L’argument de l’auteur implique deux prémisses :
- L’objet principal d’un programme réside dans son processus dynamique de traitement de l’information ;
- Les capacités cognitives des programmeurs sont orientées vers la maîtrise des relations statiques plutôt que la visualisation des processus dynamiques.
Dijkstra conclut que le « programmeur avisé » tend à « réduire l’écart conceptuel entre le programme statique et le processus dynamique, pour rendre la correspondance […] aussi triviale que possible. »
En ingénierie logicielle, il est généralement admis que la maintenance logicielle a un coût important. Martin matérialise ce coût sous la forme d’une chute de productivité[2]. Ainsi, l’ajout de nouvelles fonctionnalités devient de plus en plus difficile au fur et à mesure du développement, jusqu’à un blocage complet rendant prohibitif l’évolution du programme.

Un état des lieux mené par deux chercheurs de la maintenance logicielle synthétisent plusieurs études et détaillent les principaux postes de dépenses[3]. La maintenance logicielle s’articule autour de trois points saillants : la compréhension du programme, l’analyse d’impact et les tests de régression. La compréhension de programme constitue évidemment une étape nécessaire à sa modification. Avant toute modification, il faut comprendre la structure et le comportement du programme cible. La maintenance logicielle consomme entre 60% et 80% du coût total d’un programme et la compréhension de programme engloutir de 50% à 90% du temps de maintenance total. Afin d’approfondir la question, il faut s’intéresser à la modélisation de la maintenabilité.
De la modélisation de la maintenabilité aux métriques
Les modèles de maintenabilité s’inscrivent dans le cadre plus général des modèles de qualité logicielle. Un modèle de qualité logicielle a pour objectif de fournir un cadre à l’analyse d’un programme vis-à-vis d’un ensemble de qualités définies par le modèle. Il est possible de classer les modèles de qualité logicielle en trois catégories de modèles : théoriques, concrets et empiriques[4].
Les modèles théoriques comme taxonomie de la maintenabilité
Les modèles théoriques se présentent sous la forme d’une hiérarchie de qualité logicielle. Ainsi, ils définissent la maintenabilité en la découpant en sous-caractéristiques. Ce processus peut être récursif, mais en pratique les modèles se limitent à deux ou trois niveaux.
Les relations entre les niveaux hiérarchiques de qualité peuvent être de type plusieurs-à-plusieurs ou un-à-plusieurs. Dans ce deuxième cas, un modèle théorique de maintenabilité définit alors un arbre de qualités logicielles dont la racine est la maintenabilité.
Les sous-caractéristiques de bas niveau, « feuilles », sont parfois associées à une ou plusieurs métriques. Pour rappel, une métrique est une mesure quantitative effectuée sur un programme ou son processus de développement. Les modèles théoriques ne définissent pas de méthode d’évaluation de la maintenabilité à partir des scores des sous-caractéristiques.

Les modèles concrets pour opérationnaliser l’évaluation de la maintenabilité
Les modèles concrets de maintenabilité sont apparus dans les années 2000. Ils reprennent avec plus ou moins de fidélité un modèle théorique qui sert alors de base à la construction du modèle concret.
Ils se distinguent des modèles théoriques par leur proposition d’une méthode opérationnelle d’évaluation de la maintenabilité. En particulier, ils définissent une mécanique d’agrégation des scores « feuilles » qui permet d’obtenir une note globale de maintenabilité. L’objectif de ces modèles est d’être plus détaillés que les modèle théoriques et plus explicables que les modèles empiriques.

Les modèles empiriques pour une prédiction centrée sur les données
Les modèles empiriques s’appuient sur des jeux de données expérimentaux pour entrainer des algorithmes de prédiction de la maintenabilité logicielle.
Le principe général des modèles empiriques consiste à construire une formule pour représenter la maintenabilité sous la forme d’une combinaison de métriques.
Ainsi, la maintenabilité est « apprise » à partir des métriques puis « prédite » sur la base de cet apprentissage.
En d’autres termes, on utilise des mesures pour estimer à quel point un logiciel sera facile à maintenir. En 1992, les chercheurs Paul Oman et Jack Hagemeister ont introduit l’« index de maintenabilité[5] » qui introduit cette approche. Le développement des méthodes d’apprentissage automatiques et des réseaux de neurones a rendu omniprésent ce type de modélisation dans les études modernes de la maintenabilité logicielle.

Les métriques comme tête de lecture des modèles
Les métriques contribuent à représenter le code source afin d’évaluer la maintenabilité. Les métriques statiques de code sont basiquement des compteurs. Elles décomptent des éléments spécifiques du code source en agrégeant les résultats à une granularité donnée. Les règles de décompte sont souvent très simples. À partir de ces métriques « compteur », il est possible de définir des métriques dérivées qui seront par exemple la moyenne ou le maximum d’une métrique de base.
Il est possible de classifier les métriques statiques en quatre catégories :
- Les métriques de taille quantifient le code source en termes de « volume », comme le nombre de lignes de code.
- Les métriques de contrôle s’intéressent aux flux de contrôle des fonctions.
- Les métriques d’invocations analysent les dépendances entre fonctions.
- Les métriques objet sont spécifiquement conçues pour les langages orientés objet.
Les métriques fonctionnent comme la tête de lecture des modèles de maintenabilité. Elles offrent ainsi aux modèles le moyen de « voir » le code source. Ces derniers demeurent par ailleurs totalement ignorants du code.
La fiabilité des métriques en question
Malheureusement, les métriques souffrent de plusieurs limites. Il existe de nombreux outils de calcul des métriques. Mais la sélection des métriques implémentées varie grandement entre les outils. Et par ailleurs, les résultats pour une métrique donnée montrent peu de concordance, même pour une métrique aussi simple que le nombre de lignes de code.
De plus, il existe un effet confondant du nombre de lignes de code sur les autres métriques logicielles, ce qui jette le doute sur leur utilité. Enfin, dans de nombreux cas, l’utilisation opérationnelle des métriques pose des problèmes théoriques vis-à-vis des fondements scientifiques de la mesure. Ce qui tend à suggérer une simple corrélation entre les métriques et la maintenabilité, sans relation de causalité.
Il existe une complexité structurelle au-delà de la taille d’un programme ou de ses composants. Étant donné que les métriques incarnent le programme auprès des modèles de maintenabilité, il est indispensable de prendre en compte leurs limites pour construire un modèle de maintenabilité.
Javanalyser pour analyser le code à l’aide de graphes
Comment modéliser opérationnellement la structure du code source d’un programme ?
L’objectif est ici de modéliser structurellement la maintenabilité logicielle, c’est-à-dire en ignorant la présentation et le nommage des éléments de programme.
En termes de représentation, le code source d’un logiciel constitue une structure rigide qui obéit à des règles strictes. Il peut donc être représenté sous forme de graphe de code. Ces derniers sont une représentation idéale, complète et encore peu exploitée pour l’analyse statique de la maintenabilité de la structure du code source.
Dans ce cadre, un outil appelé Javanalyser a été développé afin de générer automatiquement des graphes de code à partir de l’arbre syntaxique abstrait d’un programme Java[6]. Il est publié sous la licence libre MIT. Son principe de fonctionnement est relativement simple. Il analyse le code d’un programme Java en trois étapes :
- Construction de l’arbre syntaxique de code ;
- Repliement de l’arbre en graphe ;
- Chargement du graphe dans une base de données orientée graphe (Neo4j).
Javanalyser facilite le traitement de grands ensembles de données dans un pipeline d’analyse automatique. Il dispose d’une interface en ligne de commande qui autorise le traitement par lots. Et l’outil atteint des performances satisfaisantes pour l’analyse de programmes industriels volumineux.
Pour illustrer concrètement comment fonctionne Javanalyser, prenons l’exemple du « patron décorateur » montré dans le listing ci-dessous. Un décorateur est une structure qui permet d’ajouter des responsabilités dynamiquement et en série à un composant décoré sans passer par l’héritage.

Cette implémentation produit le graphe de code ci-dessous. Chaque nœud représente un élément de programme, comme une variable, une méthode, ou une invocation de méthode. Les relations entre ces nœuds représentent les relations entre ces éléments de programme. Pour plus de visibilité, les éléments de programme à l’intérieur des blocs de code n’ont pas été représentés sur cette figure.

Graphe de code du patron décorateur
Sur un tel graphe de code, il est possible de calculer les métriques statiques de code. Pratiquement, ce calcul a été implémenté au sein de Javanalyser, afin de pouvoir automatiser au maximum l’analyse des métriques. Un ensemble de 33 métriques a ainsi été formalisé à l’aide du langage déclaratif Cypher, au niveau des classes Java. Le listing ci-dessous montre un exemple typique de requête qui calcule la complexité cyclomatique des classes du graphe de code. La complexité cyclomatique indique à quel point un programme est difficile à comprendre ou à tester. La requête est structurée en trois parties :
- la sélection des éléments de programme appartenant à une classe (lignes 2 à 4) ;
- le filtrage des éléments à prendre en compte dans le calcul (lignes 7 à 19) ;
- le décompte final de la métrique (ligne 20).

La formulation avec succès des métriques statiques de code montre que les graphes de code sont une représentation complète et opérationnelle pour l’analyse de la maintenabilité des programmes. De plus, elle pallie les limites des métriques concernant l’outillage, car elle clarifie le calcul des métriques et offre un canevas général à la définition des métriques statiques.
La prédiction de maintenabilité par apprentissage automatique
Les métriques logicielles ainsi formalisées, il devient possible de prédire la maintenabilité logicielle grâce aux méthodes d’apprentissage automatique. Cette approche représente les graphes du code sous la forme de vecteurs de métriques. Ces vecteurs de variables sont ensuite utilisés pour entrainer des classifieurs statistiques.
Dans le prolongement des avancées récentes, des chercheurs de l’Université Technique de Munich ont constitué un jeu de données de référence reposant sur près de 2000 évaluations de maintenabilité fournies par 70 professionnels issus de divers secteurs industriels. Ce corpus repose sur des jugements experts portant sur des classes Java, en intégrant plusieurs sous-dimensions de la maintenabilité (comme la lisibilité, la complexité ou la taille) et en tenant compte de l’importance relative accordée à chacune[7]. Ce jeu de données a ensuite été utilisé pour entraîner des modèles capables de prédire automatiquement la maintenabilité perçue, avec des performances comparables à celles d’un évaluateur humain moyen[8].
La figure suivante illustre ce jeu de données, chaque point représentant une classe positionnée selon sa taille et son niveau de maintenabilité. Comme évoqué précédemment, la taille des classes Java est un facteur confondant important pour l’ensemble de métriques et a fortiori pour la prédiction de maintenabilité.

Pour approfondir les résultats de l’équipe munichoise, l’influence de la représentation de la maintenabilité sur sa prédiction a été explorée, ainsi que le pouvoir de prédiction des métriques et l’influence de la taille sur le problème de prédiction[9].
Pour illustrer ces résultats, la figure ci-dessous présente un diagramme en boîtes. Ce dernier compare les performances des algorithmes selon les métriques utilisées en entrée. Trois jeux de métriques sont pris en compte :
- Seulement la taille,
- Seulement la complexité cognitive
- Et l’ensemble des 33 métriques formalisées.

Cette figure illustre une comparaison du pouvoir prédictif des différentes métriques. En entraînant les mêmes algorithmes de classification (les classifieurs) avec une seule métrique à la fois, il est possible d’évaluer directement la performance de chaque métrique de manière isolée.
Les résultats révèlent que la précision et la stabilité des prédictions s’améliorent progressivement selon les métriques utilisées : d’abord avec la taille seule, puis avec la complexité cognitive, et enfin avec l’ensemble complet des métriques.
Bien que l’utilisation de taille seule permette d’obtenir de bons résultats, cette figure montre l’importance de ne pas se limiter à une seule métrique. En effet, la combinaison de toutes les métriques contribue à prendre en compte des aspects variés et complémentaires de la maintenabilité. Leur combinaison permet de capturer des aspects complémentaires de la maintenabilité, permettant ainsi une analyse plus complète et nuancée.
Javanalyser : une meilleure compréhension et gestion de la maintenabilité logicielle
L’évaluation de la maintenabilité est une construction humaine qui est propre à chaque développeur et à chaque contexte. L’objectif de ces travaux est d’identifier les quantités structurelles fondamentales qui caractérisent la maintenabilité du graphe de code d’un programme, mais l’évaluation de cette maintenabilité finale est dépendante du contexte.
Les perspectives de recherches futures s’articulent principalement autour de deux axes :
- La généralisation des métriques statiques de code ;
- La construction d’un modèle structurel de maintenabilité.
Les métriques classiques ne reflètent que partiellement la structure du code. Elles se concentrent de manière arbitraire sur le comptage de certains éléments, comme les conditions (prédicats) ou les appels entre fonctions (invocations), en ignorant les autres éléments de programme. De plus, cette spécialisation aboutit à des métriques aux définitions complexes, qui, paradoxalement, ne reflètent pas bien la complexité réelle du programme.
Il est donc nécessaire de repenser la façon de définir les métriques logicielles. Leur généralisation pourrait s’appuyer sur les graphes de code pour mesurer des caractéristiques globales, indépendantes des types d’éléments du programme ou des liens qui les unissent.
Un modèle structurel de la maintenabilité logicielle se différencie des modèles théoriques et concrets. Il privilégie une approche ascendante (bottom-up), plutôt qu’une description descendante (top-down) de la maintenabilité. En cela, il propose une vision émergente de la maintenabilité à partir de la structure des programmes. Il se démarque par ailleurs des modèles concrets et empiriques en refusant de réduire la maintenabilité à une simple note (évaluation unidimensionnelle). À la place, il adopte une approche multi-dimensionnelle pour s’adapter à la variabilité des développeurs.
En conclusion, les perspectives de recherche présentées ici ouvrent la voie à une meilleure compréhension et gestion de la maintenabilité logicielle. Elles reposent sur les graphes de code et les métriques généralisées. L’exploration de ces perspectives favorisera la création d’outils et de méthodes plus fiables et efficaces, et plus adaptés aux besoins des développeurs.
[1] Edgard Dijkstra, « Go To statement considered harmful », Commun. ACM, vol. 11, no 3, p. 147‑148, doi: 10.1145/362929.362947, mars 1968.
[2] R. C. Martin, « Clean code: a handbook of agile software craftmanship », 464 pages, Prentice Hall International, 2008.
[3] G. Canfora et A. Cimitile, « Software maintenance, in Handbook of Software Engineering and Knowledge Engineering », 2 vol., World Scientific Publishing Company, p. 91‑120. doi: 10.1142/9789812389718_0005, 2001.
[4] R. Ferenc, P. Hegedüs, et T. Gyimóthy, « Software product quality models », in Evolving software systems, T. Mens, A. Serebrenik, et A. Cleve, Éd., Berlin Heidelberg: Springer-Verlag, p. 65‑100. doi: 10.1007/978-3-642-45398-4, 2014.
[5] P. Oman et J. Hagemeister, « Construction and testing of polynomials predicting software maintainability », J. Syst. Softw., vol. 24, no 3, p. 251‑266, mars 1994, doi: 10.1016/0164-1212(94)90067-1.
[6] S. Bertrand, P.-A. Favier, et J.-M. André, « Building an operable graph representation of a Java program as a basis for automatic software maintainability analysis », in EASE ’22: Proceedings of the International Conference on Evaluation and Assessment in Software Engineering 2022, in EASE 2022. Gothenburg, Sweden: Association for Computing Machinery, juin 2022, p. 243‑248. doi: 10.1145/3530019.3534081.
[7] M. Schnappinger, A. Fietzke, et A. Pretschner, « Defining a software maintainability dataset: collecting, aggregating and analysing expert evaluations of software maintainability », in 2020 IEEE International Conference on Software Maintenance and Evolution (ICSME), Adelaide, Australia: IEEE, sept. 2020, p. 278‑289. doi: 10.1109/ICSME46990.2020.00035.
[8] M. Schnappinger, A. Fietzke, et A. Pretschner, « Human-level ordinal maintainability prediction based on static code metrics », in EASE 2021: Evaluation and Assessment in Software Engineering, Trondheim, Norway: ACM, juin 2021, p. 160‑169. doi: 10.1145/3463274.3463315.
[9] S. Bertrand, S. Ciappelloni, P.-A. Favier, et J.-M. André, « Replication and extension of Schnappinger’s study on human-level ordinal maintainability prediction based on static code metrics », in Proceedings of the 27th International Conference on Evaluation and Assessment in Software Engineering, in EASE ’23. Oulu, Finland: Association for Computing Machinery, juin 2023, p. 241‑246. doi: 10.1145/3593434.3593488.