Ce site met a disposition le build journalier de la traduction francaise du Maven: The Definitive Guide
Consultez :
  • Les documents de reference sur le projet original
  • Les sources de la traduction fr sur GitHub
  • maven


    3.6.2. Multimodule ou héritage

    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.

    3.6.2.1. Projet simple

    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 ».

    Héritage dans le projet multimodule maven-book

    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.

    3.6.2.2. Projet multimodule d'entreprise

    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.

    Héritage dans un projet multimodule d'entreprise

    Figure 3.6. Héritage dans un projet multimodule d'entreprise


    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.