web-dev-qa-db-fra.com

Maven parent pom vs modules pom

Il semble y avoir plusieurs façons de structurer les parents parent dans une construction multiprojet et je me demande si quelqu'un a réellement réfléchi aux avantages/inconvénients de chaque manière.

La méthode la plus simple d’avoir un pom parent serait de le mettre à la racine d’un projet, c.-à-d.

myproject/
  myproject-core/
  myproject-api/
  myproject-app/
  pom.xml

où pom.xml est à la fois le projet parent et décrit les modules -core -api et -app

La méthode suivante consiste à séparer le parent dans son propre sous-répertoire comme dans

myproject/
  mypoject-parent/
    pom.xml
  myproject-core/
  myproject-api/
  myproject-app/

Où le pom parent contient toujours les modules mais ils sont relatifs, par exemple. ../monprojet

Enfin, il y a l'option où la définition du module et le parent sont séparés comme dans

myproject/
  mypoject-parent/
    pom.xml
  myproject-core/
  myproject-api/
  myproject-app/
  pom.xml

Où le pom parent contient une configuration "partagée" (dependencyManagement, propriétés, etc.) et myproject/pom.xml contient la liste des modules.

L'intention est d'être évolutif pour une construction à grande échelle et doit donc l'être pour un grand nombre de projets et d'artefacts.

Quelques questions supplémentaires:

  • Où est le meilleur endroit pour définir les différentes configurations partagées comme dans le contrôle de source, les répertoires de déploiement, les plugins communs, etc. (je suppose le parent mais j'ai souvent été mordu par cela et ils se sont retrouvés dans chaque projet plutôt que un commun).
  • Comment le plugin maven-release, hudson et nexus gèrent-ils la configuration de vos multi-projets (peut-être une question gigantesque, mais davantage si quelqu'un a été surpris alors que la construction d'une multi-projet a été configurée)?

Edit: Chaque sous-projet a son propre pom.xml, je l’ai laissé de côté pour le garder concis.

277
Jamie McCrindle

À mon avis, pour répondre à cette question, vous devez penser en termes de cycle de vie de projet et de contrôle de version. En d’autres termes, le pom parent a-t-il son propre cycle de vie, c’est-à-dire peut-il être libéré séparément des autres modules ou non?

Si la réponse est oui (et c'est le cas de la plupart des projets mentionnés dans la question ou dans les commentaires), alors le pom parent a besoin de son propre module à partir d'un VCS et d'un point Maven. voir et vous vous retrouverez avec quelque chose comme ça au niveau VCS:

root
|-- parent-pom
|   |-- branches
|   |-- tags
|   `-- trunk
|       `-- pom.xml
`-- projectA
    |-- branches
    |-- tags
    `-- trunk
        |-- module1
        |   `-- pom.xml
        |-- moduleN
        |   `-- pom.xml
        `-- pom.xml

Cela rend la commande un peu pénible et une façon courante de gérer cela consiste à utiliser svn:externals. Par exemple, ajoutez un répertoire trunks:

root
|-- parent-pom
|   |-- branches
|   |-- tags
|   `-- trunk
|       `-- pom.xml
|-- projectA
|   |-- branches
|   |-- tags
|   `-- trunk
|       |-- module1
|       |   `-- pom.xml
|       |-- moduleN
|       |   `-- pom.xml
|       `-- pom.xml
`-- trunks

Avec la définition suivante des externes:

parent-pom http://Host/svn/parent-pom/trunk
projectA http://Host/svn/projectA/trunk

Une extraction de trunks donnerait alors la structure locale suivante (motif n ° 2):

root/
  parent-pom/
    pom.xml
  projectA/

Facultativement, vous pouvez même ajouter un pom.xml dans le répertoire trunks:

root
|-- parent-pom
|   |-- branches
|   |-- tags
|   `-- trunk
|       `-- pom.xml
|-- projectA
|   |-- branches
|   |-- tags
|   `-- trunk
|       |-- module1
|       |   `-- pom.xml
|       |-- moduleN
|       |   `-- pom.xml
|       `-- pom.xml
`-- trunks
    `-- pom.xml

Ce pom.xml est une sorte de "faux" pom: il n'est jamais publié, il ne contient pas de version réelle car ce fichier n'est jamais publié, il ne contient qu'une liste de modules. Avec ce fichier, une extraction aboutirait à cette structure (motif n ° 3):

root/
  parent-pom/
    pom.xml
  projectA/
  pom.xml

Ce "bidouillage" permet de lancer une construction de réacteur à partir de la racine après une vérification et de rendre les choses encore plus pratiques. En fait, c’est comme cela que j’aime installer des projets maven et un référentiel VCS pour grandes versions: cela fonctionne, cela s’adapte bien, cela donne toute la flexibilité dont vous pourriez avoir besoin.

Si la réponse est non (retour à la question initiale), alors je pense que vous pouvez vivre avec le motif n ° 1 (faire la chose la plus simple qui puisse fonctionner).

Maintenant, à propos des questions bonus:

  • Où est le meilleur endroit pour définir les différentes configurations partagées comme dans le contrôle de source, les répertoires de déploiement, les plugins communs, etc. (je suppose le parent mais j'ai souvent été mordu par cela et ils se sont retrouvés dans chaque projet plutôt que un commun).

Honnêtement, je ne sais pas comment ne pas donner de réponse générale (comme "utilisez le niveau auquel vous pensez qu'il est logique de mutualiser les choses"). Et de toute façon, les enfants poms peuvent toujours remplacer les paramètres hérités.

  • Comment le plugin maven-release, hudson et nexus gèrent-ils la configuration de vos multi-projets (peut-être une question gigantesque, mais davantage si quelqu'un a été surpris alors que la construction d'une multi-projet a été configurée)?

La configuration que j’utilise fonctionne bien, rien de particulier à mentionner.

En fait, je me demande comment le plug-in maven-release-plugin traite le motif n ° 1 (en particulier avec la section <parent>, car vous ne pouvez pas avoir de dépendances SNAPSHOT au moment de la publication). Cela ressemble à un problème de poulet ou d’œuf, mais je ne me souviens tout simplement pas si cela fonctionne et était trop paresseux pour le tester.

163
Pascal Thivent

D'après mon expérience et les meilleures pratiques Maven, il existe deux types de "poms parents"

  • "company" parent pom - ce pom contient des informations et une configuration spécifiques à votre société qui héritent de chaque pom et ne doivent pas être copiées. Ces informations sont:

    • les dépôts
    • sections de gestion de la distribution
    • configurations communes de plugins (comme les versions source et cible de maven-compiler-plugin)
    • organisation, développeurs, etc.

    La préparation de ce pom parent doit être faite avec prudence, car tous les poms de votre entreprise en hériteront. Ce pom doit donc être mature et stable (la publication d’une version du pom parent ne devrait pas affecter la sortie de tous vos projets d’entreprise!).

  • deuxième type de parent pom est un parent multimodule. Je préfère votre première solution - il s'agit d'une convention Maven par défaut pour les projets multi-modules, représentant très souvent la structure de code VCS.

L'intention est d'être évolutif pour une construction à grande échelle et doit donc l'être pour un grand nombre de projets et d'artefacts.

Les projets multiples ont une structure d’arbres - vous n’êtes donc pas arrosé à un niveau de pom parent. Essayez de trouver une structure de projet adaptée à vos besoins - un exemple classique est de savoir comment décomposer des projets multimodules

distibution/
documentation/
myproject/
  myproject-core/
  myproject-api/
  myproject-app/
  pom.xml
pom.xml

Quelques questions supplémentaires:

  • Où est le meilleur endroit pour définir les différentes configurations partagées comme dans le contrôle de source, les répertoires de déploiement, les plugins communs, etc. (je suppose le parent mais j'ai souvent été mordu par cela et ils se sont retrouvés dans chaque projet plutôt que un commun).

Cette configuration doit être judicieusement divisée en un pom parent "société" et un ou plusieurs pom parents du projet. Les choses liées à tout ce que vous projetez vont à "société" parent et cela lié au projet actuel va à projeter.

  • Comment le plugin maven-release, hudson et nexus gèrent-ils la configuration de vos multi-projets (peut-être une question gigantesque, mais davantage si quelqu'un a été surpris alors que la construction d'une multi-projet a été configurée)?

Pom parent de la société doivent être libérés en premier. Pour les multiprojets, les règles standard s'appliquent. Le serveur CI doit tout savoir pour construire le projet correctement.

33
cetnar
  1. Un parent indépendant est la meilleure pratique pour partager la configuration et les options entre des composants autrement non couplés. Apache a un projet de pom parent qui partage les avis juridiques et certaines options de packaging communes.

  2. Si votre projet de niveau supérieur nécessite un travail réel, tel que l’agrégation de javadoc ou le conditionnement d’une version, vous aurez des conflits entre les paramètres nécessaires pour effectuer ce travail et les paramètres que vous souhaitez partager via parent. Un projet réservé aux parents évite cela.

  3. Un schéma courant (en ignorant # 1 pour le moment) consiste à faire en sorte que les projets avec code utilisent un projet parent en tant que parent et qu'ils utilisent le niveau supérieur en tant que parent. Cela permet à tous de partager des éléments essentiels, tout en évitant le problème décrit au point 2.

  4. Le plugin de site deviendra très confus si la structure parente n'est pas la même que la structure par répertoire. Si vous souhaitez créer un site global, vous devrez vous amuser un peu pour résoudre ce problème.

  5. Apache CXF est un exemple du motif de # 2.

22
bmargulies

Il y a une petite prise avec la troisième approche. Comme les POM agrégés (myproject/pom.xml) n’ont généralement pas de parent, ils ne partagent pas la configuration. Cela signifie que tous ces POM agrégés n'auront que des référentiels par défaut.

Ce n'est pas un problème si vous utilisez uniquement des plugins de Central, cependant, cela échouera si vous exécutez le plugin en utilisant le format plugin: goal de votre référentiel interne. Par exemple, vous pouvez avoir foo-maven-plugin avec le groupId de org.example fournissant l'objectif generate-foo. Si vous essayez de l'exécuter à partir de la racine du projet à l'aide de la commande telle que mvn org.example:foo-maven-plugin:generate-foo, l'exécution de celui-ci échouera sur les modules d'agrégat (voir note de compatibilité ).

Plusieurs solutions sont possibles:

  1. Déployer le plugin sur le Maven Central (pas toujours possible).
  2. Spécifiez la section du référentiel dans tous vos POM agrégés (pauses SEC principe).
  3. Configurez ce référentiel interne dans le fichier settings.xml (dans les paramètres locaux, sous ~/.m2/settings.xml ou dans les paramètres globaux, sous /conf/settings.xml). Make build échouera sans ce fichier settings.xml (cela pourrait convenir pour les grands projets internes qui ne sont jamais supposés être construits en dehors de l'entreprise).
  4. Utilisez les paramètres parent avec référentiels dans vos POM agrégés (peut-être trop de POM parent?).
9
Ivan Dubrov