Organisation et dépendances des projets
La gestion des dépendances
1. Définition et problématiques de la gestion des dépendances
La gestion de dépendances est essentielle dans l’univers d’Apache Maven. C’est une notion qui paraît simple au départ mais qui peut générer des problèmes et des incompréhensions lors de la construction ou de l’exécution des projets si elle n’est pas correctement maîtrisée.
Pour appréhender au mieux cette gestion des bibliothèques logicielles internes ou externes au projet, il était nécessaire de comprendre la philosophie d’Apache Maven autour des cycles de vie des projets et des plugins. Les deux premiers chapitres ont été réalisés dans ce sens.
Le principe général des dépendances dans Apache Maven est le suivant : les classes du projet ont besoin d’autres classes dans leur processus de fonctionnement (compilation, exécution), il faut donc identifier et importer des référentiels distants vers le référentiel local la ou les bibliothèques logicielles qui contiennent ces classes. Le projet possède alors des dépendances vers ces bibliothèques qui seront au final ajoutées au chemin de génération (Class-Path) du projet.
Ce fonctionnement est schématisé pour le cas du projet de persistance.
a. Les éléments du POM concernés
Les exemples du projet banque-persistance ont mis en évidence dans les premiers chapitres quelques éléments au niveau du POM. Les éléments centraux impliqués dans la gestion des dépendances sont les suivants :
<project>
...
<dependencyManagement/>
<dependencies/>
<repositories/>
...
<profiles/>
</project>
À noter que les éléments déterminants <dependencyManagement>, <dependencies> et <repositories> peuvent aussi être déclarés dans les profils (élément <profiles>) du POM. La notion de profil est détaillée ultérieurement dans le livre.
b. Illustration des dépendances
Le plugin officiel de la fondation Apache centré sur la notion de dépendances...
La résolution des dépendances
1. Comment sont identifiées les dépendances ?
a. La transitivité
Au début de ce chapitre, alors que seulement quatre dépendances sont déclarées dans le POM du projet banque-persistance, l’affichage complet de l’arborescence des dépendances du projet présente sept dépendances.
Ce phénomène s’explique par la notion de transitivité utilisée par Apache Maven pour résoudre le graphe des dépendances d’un projet. Le principe général de la transitivité repose sur le fait que lorsqu’un projet A possède une dépendance vers un projet B et que ce projet B dépend du projet C, alors le projet A dispose d’une dépendance transitive vers le projet C.
Ainsi, dans le projet de persistance, avec l’ajout des dépendances pour la mise en place de JPA 2 et de Spring Framework, le POM du projet contient désormais neuf dépendances directes, comme le montre le schéma suivant :
L’affichage du graphe complet des dépendances identifiées par Apache Maven présente alors 36 dépendances, c’est-à-dire 27 dépendances transitives. Les dépendances sont résolues dans l’ordre de leur déclaration dans le POM. Une valeur a été ajoutée en début de ligne de chaque dépendance pour identifier le niveau de la dépendance par rapport au projet, à savoir :
-
[1] pour une dépendance directe.
-
[2] pour une dépendance transitive de premier niveau.
-
[3] pour une dépendance transitive de deuxième niveau.
-
Et ainsi de suite.
fr.eni.mvnbook:banque-persistance:jar:1.0.0-SNAPSHOT
[1] +- junit:junit:jar:4.12:test
[2] | \- org.hamcrest:hamcrest-core:jar:1.3:test
[1] +- org.hibernate:hibernate-core:jar:5.4.2.Final:compile
[2] | +- org.jboss.logging:jboss-logging:jar:3.3.2.Final:compile
[2] | +- javax.persistence:javax.persistence-api:jar:2.2:compile
[2] | +- org.javassist:javassist:jar:3.24.0-GA:compile
[2] | +- net.bytebuddy:byte-buddy:jar:1.9.10:compile
[2] | +- antlr:antlr:jar:2.7.7:compile
[2] | +- org.jboss.spec.javax.transaction:jboss-transaction-api_1.2_spec:jar:1.1.1.Final:compile ...
L’héritage et les projets multimodules
1. Présentation des projets banque-metier et banque-web
Seul le projet de gestion de la persistance a été présenté jusqu’à présent. Le développement de l’application finale, telle qu’elle est présentée au début du livre, nécessite évidemment d’autres projets Apache Maven.
Le projet exemple du livre banque-metier met à disposition les classes Java qui vont permettre d’implémenter les processus métier de l’application bancaire. Ces fonctionnalités seront ensuite utilisées au travers d’une application web banque-web offrant aux utilisateurs une IHM exploitable via un navigateur web.
Le schéma ci-après propose un extrait du diagramme de classes et les relations entre les projets exemples Apache Maven concernés.
Le projet banque-metier génère un artefact de type JAR alors que le projet banque-web crée une archive web (WAR).
2. Héritage d’un POM commun
Avec la mise en place, dans l’application exemple du livre, des projets pour les composants métier et web, plusieurs informations vont être redondantes dans les POM des projets.
Au même titre que tous les POM héritent du Super POM d’Apache Maven, il devient nécessaire de créer un POM parent commun à tous les POM du projet banque. Ce POM, appelé dans le langage Maven le Corporate POM, est souvent identifié par un artifactId défini autour du mot-clé parent plus explicite dans une équipe de développement.
a. Le type POM
Pour créer un POM dont le but unique est de factoriser les informations communes à tous les projets, Apache Maven propose le type de projet pom.
Un projet de type pom est un projet spécifique car il possède uniquement le fichier pom.xml. Du fait de cette structure simplifiée, son cycle de vie est par conséquent minimal et contient uniquement deux phases comme le montre le schéma suivant.
Ainsi, l’artefact de sortie est le fichier pom.xml qui sera déployé dans le référentiel local et le référentiel distant.
b. Mise en place du Corporate POM
La mise en place du Corporate POM est également l’occasion de renseigner...
Les propriétés du POM
1. Définition
Dès la création de la structure du premier projet Apache Maven dans le chapitre Définition et cycle de vie d’un projet, un élément a été ajouté dans le POM pour gérer l’encodage des fichiers, mais n’a pas encore été présenté : il s’agit du concept de propriétés du POM.
Il est donc possible d’utiliser des propriétés existantes ou de déclarer des nouvelles propriétés dans le POM.
a. Les propriétés disponibles
La syntaxe de toutes les propriétés est la même, à savoir : ${nom.de.la.propriété}.
Tous les éléments simples du POM sont accessibles à partir du préfixe ${project.*}. Le super POM, affiché dans le chapitre Présentation d’Apache Maven, utilise cette syntaxe notamment pour préciser le nom de l’artefact de sortie par défaut d’un projet.
<project>
<build>
...
<finalName>${project.artifactId}-${project.version}</finalName>
...
</build>
</project>
La propriété ${project.basedir} permet d’accéder au chemin racine du projet, cette valeur est désormais également accessible via la propriété ${basedir} depuis Apache Maven 3.0.
La propriété ${maven.build.timestamp} a été utilisée dans les exemples précédents, elle est valorisée dans Apache Maven avec la date début de construction du projet et peut être utile dans les fichiers textes des archives.
Il est également possible d’accéder aux variables d’environnement du système grâce au préfixe ${env.*}.
b. Créer une propriété
Pour créer des propriétés dans le POM, il suffit d’utiliser l’élément <properties> disponible à la racine de l’élément <project>. Le nom de la balise XML alors créée est le nom de la propriété en question. Par exemple, dans le POM parent de tous les projets...
En résumé
À travers ce chapitre et avec les chapitres précédents, toutes les notions fondamentales d’Apache Maven pour commencer à travailler sur un poste de développement sont acquises. Le fonctionnement d’un projet au regard des relations qu’il peut avoir avec d’autres bibliothèques logicielles est maîtrisé.
Avec l’organisation et la configuration des POM pour optimiser la gestion des dépendances et des plugins et épurer les POM enfants, quelques bonnes pratiques à mettre en place sur des projets Apache Maven ont été expliquées et mises en exécution.