Il semble y avoir plusieurs façons de structurer les poms parent dans une construction multiprojet et je me demande si quelqu'un a des réflexions sur les avantages / inconvénients de chaque manière.
La méthode la plus simple pour avoir un pom parent serait de le mettre à la racine d'un projet, c'est-à-dire
myproject/
myproject-core/
myproject-api/
myproject-app/
pom.xml
où le 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 ../myproject-core
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 où myproject / pom.xml contient la liste des modules.
L'intention est d'être évolutive à une construction à grande échelle, donc devrait être évolutive à un grand nombre de projets et d'artefacts.
Quelques questions bonus:
- Où est le meilleur endroit pour définir les différentes configurations partagées comme dans le contrôle de code source, les répertoires de déploiement, les plugins communs, etc. (je suppose que 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 plug-in Maven, Hudson et Nexus traitent-ils la façon dont vous configurez vos multi-projets (peut-être une question géante, c'est plus si quelqu'un a été rattrapé par la façon dont une construction multi-projets a été configurée)?
Edit: Chacun des sous-projets a son propre pom.xml, je l'ai laissé de côté pour le garder concis.
la source
Réponses:
À mon avis, pour répondre à cette question, vous devez penser en termes de cycle de vie du 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 qu'il peut ê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 qui ont été mentionnés dans la question ou dans les commentaires), alors le parent pom a besoin de son propre module d'un VCS et d'un point de vue Maven et vous finirez avec quelque chose comme ça au niveau VCS:
Cela rend la vérification un peu douloureuse et une façon courante de gérer cela est d'utiliser
svn:externals
. Par exemple, ajoutez untrunks
répertoire:Avec la définition externe suivante:
Une extraction
trunks
entraînerait alors la structure locale suivante (modèle # 2):En option, vous pouvez même ajouter un
pom.xml
dans letrunks
répertoire:C'est
pom.xml
une sorte de "faux" pom: il n'est jamais sorti, il ne contient pas de vraie version puisque ce fichier n'est jamais sorti, il ne contient qu'une liste de modules. Avec ce fichier, une extraction entraînerait cette structure (modèle # 3):Ce "hack" permet de lancer une construction de réacteur depuis la racine après un checkout et de rendre les choses encore plus pratiques. En fait, c'est comme ça que j'aime configurer des projets maven et un référentiel VCS pour les grands builds : ça marche, ça évolue bien, ça 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 modèle # 1 (faire la chose la plus simple qui pourrait éventuellement fonctionner).
Maintenant, sur les questions bonus:
Honnêtement, je ne sais pas comment ne pas donner de réponse générale ici (comme "utiliser le niveau auquel vous pensez qu'il est logique de mutualiser les choses"). Et de toute façon, les pompons enfants peuvent toujours remplacer les paramètres hérités.
La configuration que j'utilise fonctionne bien, rien de particulier à mentionner.
En fait, je me demande comment le plug-in maven-release traite le modèle # 1 (en particulier avec la
<parent>
section car vous ne pouvez pas avoir de dépendances SNAPSHOT au moment de la sortie). Cela ressemble à un problème de poulet ou d'oeuf mais je ne me souviens juste pas si cela fonctionne et était trop paresseux pour le tester.la source
D'après mon expérience et les meilleures pratiques Maven, il existe deux types de "poms parent"
pom parent "entreprise" - ce pom contient les informations et la configuration spécifiques à votre entreprise qui héritent de chaque pom et n'ont pas besoin d'être copiées. Ces informations sont:
La préparation de ce pom parent doit être effectuée avec prudence, car tous les poms de votre entreprise en hériteront, donc ce pom doit être mature et stable (la publication d'une version de pom parent ne devrait pas affecter la publication de tous vos projets d'entreprise!)
Les projets multiples ont une structure d'arbres - vous n'êtes donc pas limité à un seul niveau de pom parent. Essayez de trouver une structure de projet adaptée à vos besoins - un exemple classique est de savoir comment distribuer des projets mutimodules
Cette configuration doit être judicieusement divisée en un pom parent «entreprise» et un ou plusieurs pom parents. Les choses liées à tout ce que vous projetez vont au parent «entreprise» et celles liées au projet en cours vont au projet.
Le pom parent de l'entreprise doit être libéré en premier. Pour les multiprojets, des règles standard s'appliquent. Le serveur CI doit tout savoir pour construire correctement le projet.
la source
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 parent pom pour partager les mentions légales et certaines options d'emballage courantes.
Si votre projet de niveau supérieur contient un réel travail, comme l'agrégation de javadoc ou l'empaquetage d'une version, vous aurez alors des conflits entre les paramètres nécessaires pour effectuer ce travail et les paramètres que vous souhaitez partager via le parent. Un projet parent uniquement évite cela.
Un modèle courant (ignorant # 1 pour le moment) est que les projets avec code utilisent un projet parent comme parent et qu'ils utilisent le niveau supérieur comme parent. Cela permet aux choses essentielles d'être partagées par tous, mais évite le problème décrit dans # 2.
Le plugin du site deviendra très confus si la structure parente n'est pas la même que la structure du répertoire. Si vous souhaitez créer un site agrégé, vous devrez faire quelques manipulations pour contourner ce problème.
Apache CXF est un exemple du modèle dans # 2.
la source
Il y a un petit hic avec la troisième approche. Étant donné que les POM agrégés (myproject / pom.xml) n'ont généralement pas de parent du tout, 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 n'utilisez que des plugins de Central, mais 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 deorg.example
fournir un objectifgenerate-foo
. Si vous essayez de l'exécuter à partir de la racine du projet à l'aide de la commande likemvn org.example:foo-maven-plugin:generate-foo
, il ne fonctionnera pas sur les modules d'agrégation (voir la note de compatibilité ).Plusieurs solutions sont possibles:
la source