| Ce site met a disposition le build journalier de la traduction francaise du Maven: The Definitive Guide Consultez : | ![]() |
Il existe une différence entre hériter d'un projet parent et être géré dans un projet multimodule. Un projet parent transfert sa configuration à ses enfants. Un projet multimodule gère un ensemble de sous-projets ou modules. Les relations dans un projet multimodule vont du haut vers le bas. Quand vous configurez un projet multimodule, vous indiquez tout simplement que votre build doit intégrer les modules spécifiés. Les builds multimodules servent à regrouper un ensemble de modules dans un même build. La relation parent-enfant va du noeud feuille vers le haut. La relation parent-enfant concerne plutôt la définition d'un projet particulier. Quand vous associez un projet fils à son parent, vous indiquez à Maven que le POM d'un projet dérive d'un autre.
Pour illustrer la prise de décision entre une approche par héritage et une approche multimodule regardez les deux exemples qui vont suivre : le projet Maven utilisé pour produire ce livre et un projet hypothétique qui contient un ensemble logique de modules.
Tout d'abord, jetons un oeil au projet maven-book. L'héritage et les relations multimodules sont présentées dans la Figure 3.5, « Héritage dans le projet multimodule maven-book ».
Quand nous construisons ce livre sur Maven que vous êtes en train de lire, nous exécutons la commande
mvn package dans un projet multimodule qui s'appelle maven-book. Ce projet
multimodule se compose de deux sous-modules : book-examples et
book-chapters. Aucun de ces projets ne partage le même parent, ils ne sont liés que par le
fait qu'ils sont tous les deux des modules du projet maven-book. Le projet
book-examples construit les archives ZIP et TGZ que
vous avez téléchargées pour obtenir les exemples de ce livre. Quand nous exécutons le build du projet
book-examples depuis le répertoire book-examples/ avec la commande
mvn package, il ne sait pas qu'il n'est qu'une partie du projet
maven-book. Le projet book-examples ne s'intéresse pas au projet
maven-book, tout ce qu'il sait est que son parent est le POM
sonatype de plus haut-niveau et qu'il construit une archive d'exemples. Dans ce cas, le
projet maven-book existe uniquement comme facilitateur en regroupant des modules.
Chacun de ces trois projets : maven-book, book-examples et
book-chapters ont le même parent "d'entreprise" — sonatype. C'est une
pratique courante dans les organisations qui ont adopté Maven. Au lieu d'avoir chaque projet qui étende le Super
POM par défaut, certaines organisations définissent un POM d'entreprise
de haut niveau qui sert de parent par défaut quand un projet n'a aucune raison d'en dépendre d'un autre.
Dans ce livre, par exemple, il n'y a aucune raison pour que les projets book-examples et
book-chapters partagent le même POM parent. Il s'agit de projets
complètement différents avec leurs propres dépendances et configurations. Ils utilisent des plugins très
différents pour construire ce que vous êtres en train de lire. Le POM
sonatype permet à une organisation de personnaliser le comportement par défaut de Maven et de
fournir des informations propres à l'organisation pour le déploiement et les profils.
Regardons un exemple qui fournit une image plus précise de ce que pourrait être un véritable projet où
l'héritage et les relations multimodules existent côte à côte. La Figure 3.6, « Héritage dans un projet multimodule d'entreprise » montre un
ensemble de projets qui ressemblent à ceux que l'on pourrait rencontrer dans une véritable application
d'entreprise. Il y a un POM de haut niveau pour l'entreprise avec un
artifactId ayant pour valeur sonatype. Il y a ensuite un projet
multimodule big-system qui référence les sous-modules server-side et
client-side.
De quoi s'agit-il ? Essayons de donner un sens à toutes ces flèches. Tout d'abord, regardons
big-system. Le projet big-system pourrait être le projet dans lequel vous
exécuteriez la commande mvn package pour construire et tester le système dans son entier. Le
projet big-system référence les sous-modules client-side et
server-side. Chacun de ces projets regroupe le code qui s'exécute côté serveur et côté
client. Concentrons-nous sur le projet server-side. Sous ce projet server-side
se trouve un projet appelé server-lib et un projet multimodule web-apps.
Sous web-apps nous retrouvons deux applications web Java : client-web et
admin-web.
Commençons par les relations parent/enfant de client-web et
admin-web avec web-apps. Puisque ces deux applications web utilisent le
même framework (Wicket par exemple), ces deux projets partagent un même ensemble de dépendances. Les dépendances
vers l'API Servlet, l'API JSP et
Wicket seraient toutes regroupées dans le projet web-apps. Ces deux
projets client-web et admin-web doivent aussi dépendre de
server-lib. Cette dépendance sera définie comme une dépendance de web-apps
vers server-lib. Puisque client-web et admin-web
partagent tous les deux cette configuration en héritant de web-apps, ces
deux projets auront des POMs succincts contenant tout au plus les identifiants, le parent et
le nom de l'artefact final.
Maintenant, concentrons-nous sur la relation parent/enfant de web-apps et
server-lib vers server-side. Dans ce cas-ci, supposons qu'il existe deux
groupes de développeurs séparés, l'un qui travaille sur le code côté serveur et l'autre sur le code côté
client. La liste des développeurs serait configurée dans le POM du projet server-side et
héritée par ses projets fils : web-apps, server-lib,
client-web et admin-web. Nous pourrions aussi imaginer que le projet
server-side soit configuré différemment pour prendre en compte les spécificités du
développement côté serveur. Le projet server-side pourrait utiliser un profil qui n'aurait
de sens que pour tous les projets server-side. Ce profil pourrait contenir les informations
de connexion à la base de données, ou le POM de ce projet server-side
pourrait configurer une version spécifique du plugin Maven Jetty qui serait récupérée par tous les projets
qui hériteraient du POM server-side.
Dans cet exemple, la principale raison d'utiliser les relations parent/enfant est cet ensemble de
dépendances partagées et la configuration commune à un groupe de projets qui sont liés logiquement. Tous les
projets sous big-system sont liés les uns aux autres en tant que sous-modules, cependant tous
les sous-modules ne sont pas obligés de déclarer comme parent le projet qui les a déclarés comme sous-module.
Tout est sous-module pour des raisons de simplification, pour construire le système dans son ensemble allez dans
le répertoire du projet big-system et exécutez la commande mvn package. Si
vous regardez attentivement la figure vous noterez qu'il n'existe pas de relation parent/enfant entre les
projets server-side et big-system. Pourquoi donc ? L'héritage de
POM est très puissant, mais il ne doit pas être utilisé à tort et à travers. Quand le partage de
dépendances et de configuration a du sens, il faut utiliser la relation parent/enfant. Mais elle n'a pas de sens
lorsque les deux projets sont très différents. Ce qui est le cas, par exemple, des projets
server-side et client-side. Il est tout à fait possible de concevoir un
système où client-side et server-side héritent du POM
commun de big-system. Cependant à chaque apparition d'une divergence significative entre ces
deux projets il va falloir trouver des manières subtiles pour factoriser la configuration commune dans
big-system sans perturber tous les projets fils. Même si client-side et
server-side partagent la même dépendance à Log4J, ils peuvent avoir des configurations de
plugins très différentes.
Il existe un certain point, dont la position dépend de votre style et de votre expérience, au-delà duquel
vous estimerez que la duplication de configuration est acceptable pour garder des projets comme
client-side et server-side indépendants . Concevoir un système qui se
compose de dizaines de projets sur plus de cinq niveaux d'héritage de POM n'est pas la meilleure idée qu'on
puisse avoir. Dans une telle configuration, vous n'avez pas dupliqué votre dépendance à Log4J, mais vous devrez
naviguer entre les cinq niveaux de POM pour comprendre comment Maven calcule votre POM effectif. Toute cette
complexité pour éviter d'avoir à dupliquer cinq fois les quelques lignes d'une dépendance. Avec Maven, il y a
toujours "une manière Maven de faire", mais il en existe bien d'autres. Au final, tout est question de
préférences et de style. Dans la plupart des cas vous n'aurez pas de soucis si vos sous-modules déclarent le
même projet comme parent, mais il se peut que votre utilisation de Maven évolue dans temps.