Le Maven 2 POM démystifié

Construire un projet est une entreprise complexe. En raison des dizaines de tâches requises pour convertir votre méli-mélo de fichiers en un programme de travail, il existe littéralement des centaines d'outils qui font tout, de la génération du code source à la compilation, en passant par les tests, la distribution et la préparation de votre café du matin (si vous en trouvez un, cher lecteur, faites-le moi savoir). Bon nombre de ces programmes sont excellents dans ce qu'ils font. Malheureusement, pour ceux d'entre nous qui gèrent des systèmes de construction à grande échelle pour gagner leur vie, il y a rarement beaucoup de points communs; chaque programme nécessite sa propre installation disparate et sa configuration ésotérique. C'est devenu un fait inévitable de nos vies que la majorité des systèmes de construction sont construits sur mesure en collant à la main ces outils avec plusieurs scripts homebrew (oui, les scripts Ant comptent).

Plus qu'un autre outil de build, Maven est un framework de build . Il sépare proprement votre code des fichiers de configuration, de la documentation et des dépendances. Maven est étonnamment flexible pour permettre aux utilisateurs de configurer la plupart des aspects de leur code, ainsi que pour contrôler le comportement des plug-ins, les objectifs individuels et même le cycle de vie de la construction lui-même. Maven est la structure réelle, et à l'intérieur de ces murs, votre projet réside; il veut être un hôte accommodant.

Mais le problème demeure: gérer le travail de milliers de scripts de construction personnalisés dans un seul cadre est difficile et, pour être fait correctement, nécessite beaucoup d'informations. Heureusement, l'équipe Maven 2 a été assez réussie. Apprenant des erreurs de Maven 1, d'innombrables demandes d'utilisateurs, des ajustements et des mises à jour, Maven 2 est plus puissant que jamais. Malheureusement, une grande puissance s'accompagne d'une excellente configuration. Pour que les artefacts Maven 2 soient des unités facilement portables, cette configuration complexe se trouve dans un seul fichier. Entrez le Maven POM.

Qu'est-ce que le POM?

POM signifie modèle d'objet de projet. Il s'agit d'une représentation XML d'un projet Maven contenu dans un fichier nommé pom.xml. En présence des gens de Maven, parler de projet, c'est parler au sens philosophique, au-delà d'une simple collection de fichiers contenant du code. Un projet contient des fichiers de configuration, ainsi que les développeurs impliqués et les rôles qu'ils jouent, le système de suivi des défauts, l'organisation et les licences, l'URL où se trouve le projet, les dépendances du projet et tous les autres petits éléments qui entrent en jeu pour donner du code la vie. Un projet est un guichet unique pour tout ce qui y est lié. En fait, dans le monde Maven, un projet n'a pas besoin de contenir du tout de code, simplement un pom.xml. Nous rencontrerons quelques types de projets de ce type plus loin dans l'article.

Un aperçu structurel rapide

Le POM est grand et complexe, donc le casser en morceaux facilite la digestion. Pour les besoins de cette discussion, ces éléments sont regroupés en quatre unités logiques, comme le montre la figure 1: relations POM, informations sur le projet, paramètres de construction et environnement de construction. Nous commencerons par discuter des relations POM.

Vous trouverez ci-dessous une liste des éléments directement sous l'élément de projet du POM. Notez que modelVersioncontient 4.0.0. Il s'agit actuellement de la seule version POM prise en charge pour Maven 2 et elle est toujours requise. La définition du schéma XML Maven 4.0.0 se trouve sur //maven.apache.org/maven-v4_0_0.xsd. Ses éléments de premier niveau sont les suivants:

4.0.0

... ... ... ... ... ... ...

... ... ... ... ... ... ... ...

... ... ... ...

... ... ... ...

... ... ... ... ...

Relations POM

Notre premier ordre du jour est d'étudier les relations de projet, représentées dans la figure 2 dans le coin supérieur gauche du graphique de la figure 1.

Les projets doivent être liés les uns aux autres d'une manière ou d'une autre. Depuis la création des premiers assembleurs, les projets logiciels ont eu des dépendances; Maven a introduit plus de formes de relations jusqu'ici inutilisées sous une telle forme pour les projets Java. Ces relations sont les coordonnées Maven, les dépendances basées sur les coordonnées, l'héritage de projet et l'agrégation.

Coordonnées

Chaque projet Maven contient son propre identifiant unique, appelé les coordonnées du projet , qui agit comme l'adresse d'un artefact, lui donnant une place unique dans l'univers Maven. Si les projets n'avaient aucun moyen de communiquer les uns avec les autres, les coordonnées ne seraient pas nécessaires. Autrement dit, si un univers n'avait qu'une seule maison, pourquoi aurait-il besoin d'une adresse comme 315 Cherrywood Lane?

Le code ci-dessous est le POM minimum que Maven 2 autorisera - ,, et sont tous des champs obligatoires. Ils agissent comme un vecteur dans l'espace Maven avec les éléments grouper, identifier et timestamp.

4.0.0org.codehaus.mojoa1

Dans le monde Maven, ces trois éléments principaux (La trinité Maven - voici sa gloire!) Constituent les coordonnées d'un POM. Les coordonnées sont représentées par la figure 3.

Peut-être que ce POM n'est pas si impressionnant en soi. Ça s'ameliore.

Dépendances

L'un des aspects les plus puissants de Maven est sa gestion des dépendances de projet, et dans Maven 2, cela inclut les dépendances transitives. La figure 4 illustre comment nous allons les représenter graphiquement.

La gestion des dépendances a une longue tradition d'être un gâchis compliqué pour tout sauf le plus trivial des projets. «Jarmageddon» s'ensuit rapidement alors que l'arbre de dépendance devient énorme, compliqué et embarrassant pour les architectes qui sont méprisés par les nouveaux diplômés qui «auraient totalement pu faire mieux». "Jar Hell" suit, où les versions des dépendances sur un système ne sont pas tout à fait les mêmes versions que celles utilisées pour le développement; ils ont soit la mauvaise version, soit des versions en conflit entre des JAR portant le même nom. Par conséquent, les choses commencent à se casser et à identifier pourquoi cela s'avère difficile. Maven résout ces deux problèmes en ayant un référentiel local commun à partir duquel établir un lien vers les bons projets, versions et tout.

Héritage

L'une des fonctionnalités que Maven 2 apporte à partir des jours Maven 1 est l'héritage de projet, comme représenté dans la figure 5. Dans les systèmes de construction, tels que Ant, l'héritage peut certainement être simulé, mais Maven a franchi une étape supplémentaire en rendant l'héritage de projet explicite pour le modèle objet du projet.

Le code suivant définit un POM parent dans Maven 2:

4.0.0org.codehaus.mojob2pom

Ce parent ressemble à notre premier POM, avec une petite différence. Notez que nous avons défini le packagingtype comme pom, qui est requis pour les projets parents et agrégateurs (nous en parlerons plus packagingdans la section "Paramètres de construction"). Si nous voulons utiliser le projet ci-dessus en tant que parent, nous pouvons modifier le org.codehaus.mojo:aPOM du projet pour qu'il soit:

4.0.0org.codehaus.mojob2a

It is important to note that all POMs inherit from a parent whether explicitly defined or not. This base POM is known as the "super POM," and contains values inherited by default. An easy way to look at the default configurations of the super POM is by creating a simple pom.xml with nothing but modelVersion, groupId, artifactId, and version, and running the command mvn help:effective-pom.

Beyond simply setting values to inherit, parents also have the power to create default configurations for their children without actually imposing values upon them. Dependency management is an especially powerful instrument for configuring a set of dependencies through a common location (a POM's parent). The dependencyManagement element syntax is similar to that of the dependency section. What it does, however, is allow children to inherit dependency settings, but not the dependency itself. Adding a dependency with the dependencyManagement element does not actually add the dependency to the POM, nor does it add a dependency to the children; it creates a default configuration for any dependency that a child may choose to add within its own dependency section. Settings by dependencyManagement also apply to the current POM's dependency configuration (although configurations overridden inside the dependency element always take precedence).

Aggregation

A project with modules is known as a multimodule project. Modules are projects that a POM lists, executed as a set. Multimodule projects know of their modules, but the reverse is not necessarily true, as represented in Figure 6.

Assuming that the parent POM resides in the parent directory of where POM for project a lives, and that the project a also resides in a directory of the same name, we may alter the parent POM b to aggregate the child a by adding it as a module:

4.0.0org.codehaus.mojob2poma

Now if we ran mvn compile in the base directory, you would see the build start with:

[INFO] Scanning for projects... [INFO] Reactor build order: [INFO] Unnamed – org.codehaus.mojo:b:pom:2 [INFO] Unnamed – org.codehaus.mojo:a:jar:2 

The Maven lifecycle will now execute up to the lifecycle phase specified in correct order; that is, each artifact is built one at a time, and if one artifact requires another to be built first, it will be.

A note on inheritance vs. aggregation

Inheritance and aggregation create a nice dynamic for controlling builds through a single, high-level POM. You will often see projects that are both parents and multimodules, such as the example above. Their complementariness makes them a natural match. Even the Maven 2 project core runs through a single parent/multimodule POM org.apache.maven:maven, so building a Maven 2 project can be executed by a single command: mvn compile. Although used in conjunction, however, a multimodule and a parent are not one in the same, and should not be confused. A POM project (acting as a parent) may be inherited from, but that parent project does not necessarily aggregate any modules. Conversely, a POM project may aggregate projects that do not inherit from it.

Lorsque les quatre éléments de l'équation sont réunis, nous espérons que vous verrez la puissance du mécanisme de relation Maven 2, comme le montre la figure 7.

Maven nous donne un cadre agréable pour relier les projets les uns aux autres, et à travers ces relations, nous pouvons créer des plug-ins réutilisables par n'importe quel projet suivant les conventions de Maven. Mais la capacité à gérer les relations de projet n'est qu'une partie de l'équation globale de Maven. Le reste du POM n'est pas concerné par d'autres projets, mais par ses paramètres de construction, ses informations et son environnement. Avec une compréhension rapide de la façon dont les projets sont liés les uns aux autres, commençons à regarder comment un POM contient des informations sur le projet proprement dit.