ÉTUDE COMPARATIVE DES DIFFÉRENTS OUTILS D’ANALYSE DE QUALITÉ DU CODE EN JAVA POUR LA MAINTENABILITÉ D’UN LOGICIEL

PAR JEAN BEAUDET BEAJ30126503

TRAVAIL PRÉSENTÉ À M. ALAIN APRIL

MONTRÉAL, LE 20 JUIN 2016

Jean Beaudet, 2016 Cette licence Creative Commons signifie qu’il est permis de diffuser, d’imprimer ou de sauvegarder sur un autre support une partie ou la totalité de cette œuvre à condition de mentionner l’auteur, que ces utilisations soient faites à des fins non commerciales et que le contenu de l’œuvre n’ait pas été modifié.

Table des matières Introduction...... 3 Section 1 : Logiciel analysé...... 4 1.1 Présentation du logiciel JExifViewer...... 4 Historique des versions...... 5 Architecture...... 6 Section 2 : Analyse humaine du code...... 7 2.1 Les points à évaluer...... 7 2.2 Données et observations...... 8 2.3 Rapport de l’avis d’expert...... 9 Section 3 : Analyse possible à partir d’un outil de développement (IDE)...... 9 3.1 Outils intégrés de IntelliJ IDEA...... 9 3.2 Sommaire des résultats de cet outil...... 11 3.4 Analyse des résultats de cet outil...... 12 3.3 Capacité de personnalisation...... 12 3.5 Autres considérations...... 15 Section 4 : SonarQube...... 16 4.1 Résultats d'analyse de cet outil...... 16 4.2 Analyse des résultats...... 17 4.3 Possibilités de personnalisation...... 18 4.4 Autres considérations...... 19 Section 5 : Comparaison des outils...... 19 5.1 Tableau comparatif...... 19 CONCLUSION...... 20 Introduction

Nous avons vu en classe un ensemble d'outils servant à l'analyse statique du code source (Checkstyle, PMD). Nous nous sommes demandé s'il existait des alternatives, et si oui, lesquelles? Notre recherche nous a amenés à en identifier deux, soit IntelliJ et SonarQube.

Comment ces deux alternatives se comparent-elles? Sont-elles complémentaires ou simplement compétitrices? Nous avons aussi voulu savoir quels sont les avantages et les inconvénients de chacune.

Pour arriver à nos fins, nous avons voulu confronter ces outils à un logiciel existant, développé en Java et de taille raisonnable, car nous voulons d'abord en faire une analyse manuelle (revue de code).

La section 1 présente le logiciel analysé et décrit la raison du choix. La section 2 présentera une analyse humaine manuelle du code source, analyse qui sera faite après avoir établi les critères de l'analyse. La section 3 présentera l'outil d'analyse de code source de l'environnement de développement IntelliJ et des résultats qu'il nous a fournis. La section 4 présentera les résultats de l'outil SonraQube et finalement, la section 5 présentera une comparaison des outils. Section 1 : Logiciel analysé

1.1 Présentation du logiciel JExifViewer

Le but visé était de trouver un logiciel écrit en Java, contenant entre 20 et 50 classes, afin d'essayer et de comparer les outils d'analyse statiques de code fourni par IntelliJ et SonarQube. Le langage Java s'est imposé à nous, car nous le connaissons bien et que plusieurs logiciels libres ont été écrits dans ce langage. Après beaucoup de recherches infructueuses et de mauvaises pistes, nous sommes tombés sur JExifViewer.

En plus d'être un logiciel libre, écrit en Java et comportant 26 classes, ce logiciel utilise une technologie d'interface (Swing) que nous connaissons bien, tout comme la manipulation de fichier et l'extraction de métadonnées de fichiers d'image. Nous étions donc assez sûrs de pouvoir faire une analyse manuelle pertinente de ce logiciel. Voici quelques statistiques du logiciel trouvé.

Voici une capture d'écran du logiciel en question. On y voit une infobulle (en jaune) contenant plusieurs informations à propos d'un fichier image JPG, soit le nom, la taille et la résolution, de même que plusieurs données EXIF extraites. On y voir aussi un menu contextuel permettant de renommer, copier, déplacer ou supprimer le fichier sélectionné. À gauche on voir l'arborescence des fichiers et enfin, en bas à gauche, on voit un aperçu du fichier image.

Description JExifViewer est un programme Java utilisé pour l'affichage et la comparaison des informations Exif stockées dans des fichiers JPEG créés par les appareils photo numériques . JExifViewer est un projet Open Source sous licence GPL .

JExifViewer possède une visionneuse d' image dans laquelle vous pouvez faire pivoter et/ou retourner une image, zoom avant / arrière de l'image sélectionnée . Vous pouvez également imprimer une image .

Les images peuvent être affichées dans un diaporama ( haut, bas, aléatoire , en boucle, etc.). Vous pouvez également renommer, copier , déplacer et supprimer des images. À l'heure actuelle JExifViewer est disponible en anglais et en allemand . Extrait du site Web ( http:// exifviewer.sourceforge.net) et traduit librement.

Statistiques du logiciel JExifViewer Année (v. 1.8) 2010

Nombre de lignes 10701

Énoncés 4659

Fonctions 295

Classes 26

Fichiers 19

Répertoires/Package 1

Historique des versions source-1.8 2010-07-29 source-1.7 2009-04-03 source-1.6 2008-11-23 source-1.5 2007-09-29 source-1.4 2007-01-17 source-1.3 2006-11-12 source-1.2 2006-07-05 source-1.1 2006-05-28 source-1.0 2006-05-21

Architecture

Voici un diagramme de classe du logiciel JExifViewer. Il représente chacune des 26 classes du système. Nous avons mis des couleurs différentes aux différentes catégories de classes :

En jaune : la classe principale (Main) qui est aussi la classe d'entrée

En vert : les classes de présentation (Swing)

En blanc : les classes de données

En rouge : les classes de traitement, transformation ou d'extraction des données Exif.

Les classes restantes sont des classes utilitaires. Section 2 : Analyse humaine du code

2.1 Les points à évaluer

Pour analyser du code, il faut d'abord spécifier des points à analyser. Avec quelques références obtenues sur internet1 et notre expérience, nous avons trouvé 9 points à évaluer.

Point Description Simplicité et Le code est-il facile à comprendre et à modifier. Les identificateurs sont-ils clarté du code « parlant ». Il y a des commentaires là où 'est nécessaire.

1 dzone.com/articles/java-code-review-checklist et javarevisited.blogspot.com/2011/09/code-review-checklist-best-practice. Code formaté Le code est bien formaté? Documentation Le code est-il documenté Gestion des Le code gère-t-il bien les exceptions? Le code à risque lance-t-il des exceptions? exceptions Pas d'exception non gérée. Éviter les printStrackTrace() ou les System.err.println(e.toString()) Modularité Les méthodes sont courtes et bien définies. Les classes font une chose spécifique et le font bien. Éviter la Ne pas se répéter. Ce qui peut être factorisé l'est. Utiliser une superclasse au duplication (DRI) besoin. Restreindre les Toujours attribuer le privilège nécessaire à une classe ou à un membre et pas privilèges plus. Éviter les null Utiliser des collections vides ou le type Optional (Java8) Code mort Éviter le code mort, commenté ou jamais appelé. (dead code)

2.2 Données et observations

Voici ce que nous avons trouvé suite à notre analyse manuelle du code source.

Point Résultat Documentation Seules deux classes ont des commentaires (PngEncoder et PngEncoderB). Aucune JavaDoc. Un manuel utilisateur existe en Anglais et en Allemand. Simplicité et clarté Les classes PngEncoder et PngEncoderB sont aussi les 2 plus claires. En du code général, on comprend le rôle des classes par leur nom, mais quelqu'un qui ne connaît pas Swing sera vite mélangé avec des termes comme JXxxxFrame ou JXxxxPanel. Le nom « PngEncoderB » ne parle pas de lui-même, il faut regarder dans le code pour comprendre que le « B » est pour « BufferedImage » Code formaté Oui, le code est généralement bien formaté. Cependant, on devrait ajouter des accolades à plusieurs blocs de code. La norme d'utilisation des accolades ouvrantes n'est pas constante : parfois l'accolade ouvrante est sur la même ligne que la structure de contrôle, parfois elle est sur la ligne suivante. Gestion des Il y a environ 40 try catch dont le catch ne contient rien ou fait simplement exceptions un « printStackTrace ». Modularité Il y a un seul package. Étant donné les rôles et la nature très distincts des Éviter la duplication Difficile à évaluer de façon manuelle. (DRI) Restreindre les À peu près tout (classes, méthodes) est déclaré public, même si de fait, tout privilèges est dans le même package. On pourrait laisser Éviter les null 9 instances de « return null » Code mort Environ 25 lignes de code en commentaire, donc certaines conditions pour des blocs de code. Difficile de détecter les méthodes inutilisées sans faire un « findUsage » sur chacune d'elles. Affectations et Des comparaisons inutiles == true. comparaisons

2.3 Rapport de l’avis d’expert

• Code peu documenté, mais relativement bien structuré : le programme est compréhensible pour quelqu'un qui connaît le langage et les technologies. • Certains choix surprenants ne sont pas du tout expliqués, par exemple, pourquoi JSettingsDialog n'est pas appelé par JMainFrame comme toutes les autres classes de présentation. C'est en fait parce qu'il est dans un Thread différent, mais ceci échapperait à un junior ou à quelqu'un qui n'est pas familier avec Swing. • La gestion d'exception fait grandement défaut, mais ce n'est pas une application qu'on peut qualifier de « mission critical ». Il conviendrait quand même de l'améliorer ou au moins de journaliser les erreurs. • Il y a trop de lignes de code en commentaire. On n'a aucune explication à savoir pourquoi elles le sont. • Aucun test (unitaires, intégration). Donc, pas de filet de sécurité pour faire la réingénierie du code.

Actions prioritaires • Redocumenter le code (minimalement) • Enlever les lignes commentées • Créer des tests de régression (unitaires et d'intégration). Section 3 : Analyse possible à partir d’un outil de développement (IDE)

3.1 Outils intégrés de IntelliJ IDEA

L'environnement de développement IntelliJ IDEA est un IDE bien réputé. C'est le seul outil commercial pour le développement Java qui a survécu aux côtés d’Éclipse et de Netbeans. Plusieurs autres sont tombés au champ de bataille depuis les débuts de Java (JBuilder, JDevelopper, etc.). Il possède plusieurs fonctionnalités qui en font un outil de développement unique et bien réputé.

Cet IDE possède donc des outils d'analyse statique de code assez élaborés. Ces fonctionnalités sont bien décrites sur le site Web de l'entreprise : https://www.jetbrains.com/help/idea/2016.1/code-analysis.html. Voici un aperçu du processus d'inspection de code.

Pour analyser un projet, sélectionner celui-ci dans l'explorateur de projets, choisir « Analyze » dans le menu, puis le sous-menu « Inspect Code... ». Ensuite, spécifier la portée (scope) de l'inspection (tout le projet, un package ou un fichier), choisir d'inclure ou non les tests et enfin, choisir le profil d'inspection. Nous verrons les profils d'inspections dans la section « Capacité de personnalisation ». Plusieurs tris, filtres et regroupements sont disponibles pour l'affichage des résultats. Dans l'image de gauche qui suit, les erreurs sont regroupées par gravité (sévérité) et à droite par dossier (il n'y en a qu'un ici).

3.2 Sommaire des résultats de cet outil

Voici quelques exemples de résultats obtenus :

Catégorie Trouvés 49 « Erreurs » 34 erreurs html dans le manuel en ligne, comme par exemple une balise (aucune erreur grave html fermée mais jamais ouverte : selon moi.)

1 erreur Javadoc 6 erreurs de « ressource bundle » 1693 Warnings 1050 Propriétés inutilisées (fichier properties) 199 redondances de déclarations (méthodes toujours appelées avec la même valeur). 128 problèmes d'affectations 70 bugs probables (essentiellement des structures de contrôles inutiles, car le résultat est toujours le même) 31 gestions d'exception déficientes 27 problèmes reliés à la compilation (tous le même problème d'ajout d'une valeur avec les JComboBox non typés → ils ne l'étaient pas en Java 6) 8 mesures de classes dont 7 classes trop complexes → complexité cyclomatique entre 104 et 232 pour ces 7 classes.

3.4 Analyse des résultats de cet outil

Les éléments dans la catégorie Erreur sont des erreurs sans conséquence dans le cas présent. Certains éléments de la catégorie Warning devraient être priorisés et constituent des menaces sérieuses au fonctionnement et à la maintenabilité (celles que j'ai mises en rouge). Dans tous les cas, il s'agit d'une « dette technique ».

L'outil ne nous permet pas de juger de ce qui est le plus important ou prioritaire ni de comprendre certaines erreurs.

En revanche, il permet d'accéder facilement au code source à partir du problème, d'avoir une explication du problème identifié et de corriger certaines erreurs en un clic (à partir des suggestions).

Dans l'image qui précède, on voit bien l'option pour aller au code source (F4 - Jump to Source) ou encore l'option « quickfix » pour corriger le problème en sélectionnant la solution proposée, c'est- à-dire de convertir le champ en variable locale.

3.3 Capacité de personnalisation Les profils d'inspections Il est possible de créer différents profils d'inspections pour différentes fins. Par exemple, une équipe ou une sous-division de l'entreprise pourrait avoir un ensemble de règles et une autre un autre ensemble.

Quand on installe IntelliJ IDEA, il y a deux profils, « Default » et « Project Default ». Le premier contient les règles globales, pour tous les projets tandis que le second contient les règles spécifiques à un projet.

La personnalisation des règles Pour chaque règle, on peut faire ce qui suit :

• L'activer ou la désactiver

• La description

• Le niveau de gravité (« severity »)

• La portée (« scope »)

• Une ou plusieurs valeurs Il est aussi possible de créer ses propres règles d'inspection, mais nous ne l'avons pas essayé.

Les inspections sont regroupées en catégories, et on peut activer ou désactive toutes les inspections d'une catégorie. La plupart des vérifications ne sont pas cochées par défaut.

Il y a 29 catégories principales et 47 sous-catégories seulement en Java :

Abstraction issues Code maturity issues Declaration redundancy

Assignment issues Code style issues Dependency issues

Bitwise opération issues Compiler issues Encapsulation issues

Class metrics Concurrency annotation issues Error handling

Class structure Control flow issues Finalization issues

Cloning issues Data flow issues General Imports Concurrency annotation issues Inheritance issues

Inheritance issues Control flow issues Security issues

Assignment issues Data flow issues Serialization issues

Bitwise operation issues Declaration redundancy TestNG

Class metrics Dependency issues Threading issues

Class structure Encapsulation issues toString issues

Cloning issues Error handling Verbose or redundant code construct Code maturity issues Finalization issues Visibility issues Code style issues General

Compiler issues Imports

3.5 Autres considérations

Vérification d'une classe On peut vérifier une seule classe, directement avec le bouton de droite de la souris (Analyse → Inspect Code). On obtient tous les problèmes potentiels identifiés par le profil d'inspection courant. Un aperçu nous permet de parcourir rapidement toutes les occurrences, à partir de la marge de droite (juste en survolant avec la souris) :

Les problèmes identifiés laissent une marque jaune dans la marge et en survolant on voit la description des problèmes aussi en jaune.

Plugins Des plug-ins sont disponibles pour ajouter des outils de vérifications externes, dont certains sont bien connus : • SonarQube • CheckStyle • PMD • FindBug • etc. Voici un lien : https://plugins.jetbrains.com/category/?idea&category_id=all Section 4 : SonarQube

SonarQube, anciennement appelé tout simplement « Sonar » est un outil d'analyse de code tout à fait incontournable. C'est un outil de gestion de la qualité du logiciel libre de droits. Comme d'autres étudiants se sont concentrés sur la présentation et l'évaluation de cet outil, nous allons sauter directement aux résultats d'analyse.

4.1 Résultats d'analyse de cet outil

Le panneau de contrôle (Dashboard) présente un sommaire de l'analyse du code source de notre logiciel JExifViewer. Nous avons mis en évidence (surlignage jaune) certaines mesures que nous avons jugé intéressantes.

Les défauts trouvés du type « blocker » sont au nombre de 6. Si on regarde le genre de problèmes soulevés, on voit qu'il s'agit vraiment de menaces sérieuses à la stabilité du programme, concernant à ce que nous avions trouvé au niveau le plus élevé avec IntelliJ IDEA.

Nous avons fait la même chose pour la catégorie « Critical » et nous en tirons la même conclusion.

4.2 Analyse des résultats

Les éléments présentés dans le dashboard présentent une bonne vue d'ensemble du logiciel analysé ainsi que des problèmes identifiés. Les problèmes identifiés « blocker » et « critical » le sont vraiment. Il est facile de bien comprendre l'erreur et d'avoir accès à des suggestions de changement. Il est aussi facile de visualiser le code source afin de mettre le problème en contexte et de réfléchir à une solution possible. Un effort (en minutes ou heures) est présenté par l'outil, qui nous donne une idée (ordre de grandeur) du temps nécessaire à la résolution. Il est possible d'affecter le problème à un individu et aussi d'ajouter des commentaires (liens possibles avec Jira, Trac, etc.). En revanche, il est plus difficile de comptabiliser les problèmes par catégorie comme nous l'avons fait avec IntelliJ IDEA. Il n'y a pas une vue arborescente par défaut avec un dénombrement du nombre de problèmes par catégorie.

4.3 Possibilités de personnalisation

Il faut avoir un compte et que ce compte ait les droits appropriés pour pouvoir éditer les règles, c'est-à-dire en ajouter, en supprimer, en activer/désactiver ou les modifier. Les « règles » sont classées selon plusieurs axes (langage, type, etc.) et peuvent avoir plusieurs étiquettes (tags). Si c'est un peu déroutant au début, on s'y retrouve assez bien par la suite. Comme pour la présentation des résultats d'analyse, il n'y a pas de vue arborescente tel qu'on en a vue une dans IntelliJ IDEA. Il faut utiliser les filtres ou la recherche afin de localiser une règle spécifique.

Personnalisation d'une règle. Les valeurs (ex : ici le Threshold pour la complexité cyclomatique) sont paramétrables par profil de qualité. Chaque analyse peut se faire selon un profil de qualité spécifique. Il est possible de créer différents profils d'inspections pour différentes fins. Par exemple, une équipe ou une sous-division de l'entreprise utiliser un profil de qualité et une autre un autre profil.

4.4 Autres considérations

Cet outil a beaucoup de possibilités d'extensions. Plusieurs plug-ins sont disponibles tant pour effectuer des vérifications supplémentaires que pour visualiser les résultats, s'intégrer à un annulaire, à un processus de build et de mise en production ou autre chose.

Section 5 : Comparaison des outils

5.1 Tableau comparatif Inspection manuelle IntelliJ SonarQube Avan- Donne une vue Intégré. Bonne vue d'ensemble. tages d'ensemble assez Rapide. Les résultats sont pertinents. rapidement. Possible de le faire pour Historique des résultats. une seule classe. Estimation de l'effort (chaque Suggestions (quick fix) problème). Dette technique (globale). Explications : permet d'apprendre à mieux . Incon- Demande une expertise. Pas de vue d'ensemble Plus compliqué à mettre en place. vé- Demande d'avoir établi (dashboard). Plus laborieux à gérer et nients des critères objectifs. Priorisation des paramétrer des règles. Processus généralement problèmes plus difficile. Pas de correction automatique. subjectif et laborieux. N'encourage pas Impossible pour des nécessairement les projets plus gros. bonnes pratiques (les 10 étapes de la maintenance).

Quand Petit projet. Avant de maintenir une En développement. Pour avoir une vue classe. En maintenance. d’ensemble. Pour corriger toutes les Dans un processus de rétro- Revues de code occurrences d’un ingénierie et de réingénierie formelles. problème. Pour corriger automatiquement certains problèmes. Extensio Plug-ins pour Sonar, Des centaines de plug-ins pour bien ns Chekstyle, PMD, FindBug, intégrer Sonar avec d’autres outils etc. utilisés dans le processus de développement et de maintenance.

CONCLUSION

Nous avons découvert des produits à très grande valeur ajoutée. Ils ne remplacement complètement l'analyse par un programmeur d'expérience, mais ils peuvent l’accompagner et l’enrichir. Les revues de codes ont donc toujours leur place, mais elles peuvent être « assistées » par la technologie.

IntelliJ IDEA est un outil intéressant, et peut être utile surtout avant d'entreprendre la modification d'une classe spécifique. SonarQube est un outil incontournable très riche en fonctionnalités. Il permet aussi de suivre l’évolution du code source d’une journée à l’autre ou d’une phase de livraison à un autre.