Introduction

Maintenant que vous avez créé votre premier projet Maven, vous vous voyez confronté à un scénario un peu différent. Deux de vos amis ont développé une application capable de gérer des agendas et de les synchroniser avec Google Calendar. Vous trouvez leur application géniale, mais vous ne savez pas comment l’intégrer à votre projet. En effet, bien que sympathiques, vos amis sont fainéants: ils ne vous ont laissé que le code source et un fichier README succinct.

Deux options se présentent à vous: (i) copier leur code à votre projet ou (ii) le gérer comme un projet indépendant et utiliser Maven pour le transformer en un artéfact réutilisable. Comme vous faites souvent de bons choix (et accessoirement, vous avez remarqué que ceci est un tutoriel sur Maven et non sur la copie de fichiers), vous avez opté pour la deuxième option. Vous allez élitiser 1 leur projet.

Avant de commencer, créez une copie locale du projet:

git clone https://gitlab.univ-nantes.fr/sunye-g/dates.git
cd dates

Configuration du projet

Notre première étape sera de créer le modèle objet du projet, le fichier pom.xml. Cette fois, nous n’allons pas utiliser un archétype pour créer le squelette du projet, car le projet existe déjà, nous allons tout simplement créer le fichier manuellement. Bien évidemment, vous pouvez copier le modèle d’un autre projet et modifier ensuite les identifiants de groupe et d’artéfact.

Créez un fichier appelé pom.xml à la racine du projet Dates et ajoutez-y les balises XML suivantes:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://maven.apache.org/POM/4.0.0"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>fr.univnantes.student</groupId>
    <artifactId>dates</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>
</project>

Vous pouvez désormais compiler le projet avec Maven:

mvn compile

Comme vous pouvez constater, la compilation est un succès. Cela n’est pas dû à la qualité du code de vos amis, mais tout simplement parce que le compilateur Java n’a pas trouvé de code à compiler.

Réorganisation des dossiers

Il ne s’agit pas d’une erreur, dans le cadre d’un projet Maven, le compilateur Java cherche le code source dans le dossier src/main/java, exclusivement. Il est bien sûr possible de dire à Maven de chercher le code source ailleurs, mais ce choix va à l’encontre d’un des principes de base de Maven: la convention plutôt que la configuration.

Nous allons donc respecter ce principe et déplacer le code source à sa place appropriée. Utilisez les commandes shell suivantes pour réorganiser le projet:

mkdir -p src/main/java
mv src/univ src/main/java

Compilez à nouveau le projet avec Maven:

mvn compile

Cette fois, le compilateur trouve plusieurs erreurs, ce qui est normal. Il a trouvé le code source, mais n’arrive pas à trouver les artéfacts logiciels utilisés par ce code.

Configuration des dépendances

Le fichier README.adoc nous donne une piste importante: le code source utilise les artéfacts MiG Layout et Google Data. La bonne nouvelle c’est que ces deux artéfacts sont disponibles sur Maven Central. Cependant, pour les retrouver Maven aura besoin de 2 choses: leurs identifiants (groupe et artéfact id) et leurs versions. Utilisez le site MVNRepository pour retrouver les dépendances et ajoutez-les au fichier pom.xml.

ASTUCE: Pour gagner du temps, utilisez les mots-clés com.google.gdata et miglayout.

A la fin, vous devez avoir une balise appelée <dependencies>, qui a comme mère directe la balise <project> et comme filles, deux balises <dependency>:

<project>
    <!-- ... -->
    <dependencies>
        <dependency>
            <groupId>com.google.gdata</groupId>
            <artifactId>core</artifactId>
            <version>1.47.1</version>
        </dependency>
        <dependency>
            <groupId>com.miglayout</groupId>
            <artifactId>miglayout</artifactId>
            <version>3.7.4</version>
        </dependency>
    </dependencies>
    <!-- ... -->
</project>

Recompilez le projet à l’aide de Maven avec mvn compile. Cette fois, la compilation réussit avec quelques avertissements: le code utilise des méthodes qui ont été dépréciées. Ces avertissements sont importants, car ils aideront les développeurs à mettre à jour le code pour garder la compatibilité avec les versions futures des artéfacts utilisés. Nous allons exploiter cette information plus tard.

Documentation du projet

Maintenant que le projet compile (presque) correctement, nous allons générer un site web contenant la documentation technique du projet. Par défaut, Maven produit un rapport assez riche, que nous allons améliorer par la suite. Nous allons commencer par configurer le plugin responsable de la phase site de la construction.

Ajoutez la balise suivante au fichier pom.xml:

<project>
    <!-- (...) --> 
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-site-plugin</artifactId>
                <version>3.9.1</version>
            </plugin>
        </plugins>
    </build>
</project>

En réalité, on ne configure pas vraiment le plug-in maven-site-plugin ici, on se contente de préciser à Maven qu’il doit utiliser une version récente du plug-in: en occurrence, la 3.9.1. Cette précision est nécessaire, car elle empêche Maven d’utiliser une version plus ancienne de ce plug-in, qui peut s’avérer avec le JDK utilisé. Exécutez maintenant la phase site grâce à la commande suivante:

mvn site

Le plug-in génère les pages HTML dans le dossier target/site/. Utilisez un navigateur pour ouvrir le fichier target/site/index.html et découvrir le rapport généré. Parmi d’autres informations, vous trouverez les plug-ins utilisés par Maven, ainsi que les dépendances (directes et transitives) du projet.

Génération de la Javadoc

Vous avez probablement remarqué qu’à la racine du projet, il y a un dossier appelé javadoc qui contient la Javadoc générée par vos amis. Ils ont pensé que c’était une bonne idée d’ajouter tous les fichiers générés au gestionnaire de versions, plutôt qu’un simple script capable de les générer. Ce n’est pas le cas. L’idée est mauvaise, mais vous pouvez les remercier: comme vous n’aurez pas le temps de faire toutes les erreurs du monde, vous pouvez apprendre des erreurs des autres. Ou, pour citer Confucius:

L’homme sage apprend de ses erreurs, l’homme plus sage apprend des erreurs des autres.

Confucius

Vous avez compris, vous pouvez utiliser Maven pour générer automatiquement la Javadoc pendant le processus de build. En effet, Maven est capable d’intégrer d’autres rapports au site généré et c’est ce que nous allons faire avec la Javadoc.

Ajoutez les balises suivante au fichier pom.xml:

<project>
    <!-- (...) -->
    <reporting>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <version>3.3.1</version>
                <configuration>
                    <additionalJOption>-Xdoclint:none</additionalJOption>
                </configuration>
            </plugin>
        </plugins>
    </reporting>
</project>

La balise reporting nous permet de configurer les rapports qu’apparaitront dans le site web généré et plus précisément dans la section Project Reports. Le plug-in maven-javadoc-plugin permet plusieurs options. Ici, on lui dit de ne pas arrêter la génération lorsqu’il rencontre des erreurs de syntaxe dans les commentaires. Bien évidemment, il n’est pas nécessaire de dire que vos amis apprécient particulièrement ce type d’erreur.

Exécutez à nouveau la commande mvn site et rechargez la page index.html. Le site généré contient désormais la Javadoc. Remarquez que la Javadoc générée contient des liens hypertexte vers les classes de la JDK, comme Object ou ActionListener.

Évaluation de la qualité du coude source

La Javadoc est certes une bonne source d’informations pour ceux qui souhaitent utiliser le code fait par vos amis, mais ne donne aucune information sur la qualité de ce code. En effet, toujours fainéants, vos amis n’ont écrit aucun test, ni unitaire, ni d’intégration. Vous ne savez ni si le code est fiable ni s’il est maintenable.

Heureusement pour vous, plusieurs outils d’analyse statique de code Java existent et pourront vous aider à estimer la qualité du code source et à l’améliorer. Par exemple: PMD, Checkstyle, Spotbugs, Error Prone, BlockHound et quelques autres.

Ces outils peuvent s’intégrer aux rapports produits par Maven, grâce à des plug-ins spécifiques. Pour évaluer le code de vos amis, nous allons en utiliser deux, qui permettent à Maven d’utiliser PMD et Spotbugs. Ajoutez les balises suivantes à l’intérieur de la balise <reporting> de votre fichier pom.xml:

<reporting>
    <plugins>
        <!-- (...) -->
        <plugin>
            <groupId>com.github.spotbugs</groupId>
            <artifactId>spotbugs-maven-plugin</artifactId>
            <version>4.4.2.2</version>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-pmd-plugin</artifactId>
            <version>3.15.0</version>
        </plugin>
    </plugins>
</reporting>

Exécutez à nouveau la commande mvn site et rechargez la page index.html. Trois nouveaux rapports s’affichent à côté de celui de la Javadoc: SpotBugs, PMD et CPD. Ce dernier, Copy Paste Detector affiche les morceaux de code dupliqués du projet.

Comme vous pouvez constater, le format des rapports est similaire, il s’agit d’un tableau contenant le nom de la règle (ou bug dans SpotBugs), la classe et les lignes de code où la règle n’a pas été respectée. Un inconvénient de ces rapports c’est qu’il n’est pas possible de les utiliser pour accéder directement au code source.

Un autre plug-in de Maven peut résoudre cet inconvénient: JXR. En effet, JXR permet la création de références croisées entre les rapports et le code source. Son utilisation se fait en deux étapes: (i) ajout du plug-in à la génération du site et (ii) configuration des autres plug-ins. Après ces modifications, la balise <reporting> doit ressembler à:

<reporting>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.3.1</version>
            <configuration>
                <additionalJOption>-Xdoclint:none</additionalJOption>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jxr-plugin</artifactId>
            <version>3.1.1</version>
        </plugin>
        <plugin>
            <groupId>com.github.spotbugs</groupId>
            <artifactId>spotbugs-maven-plugin</artifactId>
            <version>4.4.2.2</version>
            <configuration>
                <linkXref>true</linkXref>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-pmd-plugin</artifactId>
            <version>3.15.0</version>
            <configuration>
                <linkXref>true</linkXref>
            </configuration>
        </plugin>
    </plugins>
</reporting>

Conclusion

Maven n’est pas seulement utile lors de la création d’un nouveau projet, il l’est aussi pour les projets existants. L’adoption des conventions Maven entraine des efforts supplémentaires, mais qui ne présente que des avantages. En effet, elles ne sont pas exclusives aux projets Maven, elles sont aussi respectées par d’autres outils de construction, comme Gradle ou Bazel. Respecter ces conventions c’est rendre le code plus accessible aux autres développeurs.

Les outils d’analyse statique de code fournissent des informations très intéressantes sur le code source. Mais ces informations ne doivent pas être considérées individuellement, mais dans leur globalité et dans le contexte d’un projet. Ces outils sont personnalisables et peuvent s’adapter aux règles de chaque projet.

Notes

  1. Le verbe “maveniser” n’existant pas et “Maven” signifiant “expert” ou “connaisseur”, je me permets cette localisation.