• 20 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 12/12/2019

Décrivez votre projet

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Maintenant que vous avez créé votre premier projet avec Maven, je vais vous faire entrer un peu plus en profondeur dans la définition de votre projet Maven.

Tout se passe – ou presque – dans le fichier pom.xml. Je suis sûr que vous l'aviez deviné ! Ce fichier, au format XML, permet de définir le POM (Project Object Model) utilisé par Maven.

Dans ce chapitre, je vais vous montrer comment décrire votre projet dans ce modèle (POM). Certains éléments vous paraîtront peut-être superflus au premier abord, mais vous verrez qu'ils seront utiles à différentes étapes de la construction du projet par Maven. C'est ce que vous découvrirez tout au long du cours, et notamment dans la deuxième partie « Automatisez la construction de votre projet ».

Ouvrez le fichier pom.xml et on y va !

Les informations de base

Je commence par ajouter quelques informations de base sur le projet. Je découpe cela en plusieurs parties comme ceci :

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- =============================================================== -->
<!-- Informations du projet -->
<!-- =============================================================== -->
<!-- ===== Informations Maven ===== -->
<groupId>org.exemple.demo</groupId>
<artifactId>mon-appli</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<!-- ===== Informations générales ===== -->
<name>Mon Application</name>
<description>
La super application qui sert à faire ceci/cela...
</description>
<url>http://www.exemple.org/mon-appli</url>
<!-- ===== Organisation ===== -->
<organization>
<name>Mon Entreprise</name>
<url>http://www.exemple.org</url>
</organization>
<!-- ===== Licences ===== -->
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
...
</project>

Les coordonnées du projet Maven

<project>
...
<!-- ===== Informations Maven ===== -->
<groupId>org.exemple.demo</groupId>
<artifactId>mon-appli</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
...
</project>

Un premier bloc définit les informations du projet relatives à Maven, avec :

  • groupId : identifiant de l'organisation gérant le projet. Cet identifiant reprend la notation des packages Java. En général, celui-ci correspond au package de base de l'application, mais ce n'est pas obligatoire.

  • artifactId : identifiant du projet

  • version : version du projet.

  • packaging : type de packaging devant être généré par Maven (jar, war, ear...). J'y reviendrai plus tard.

Un projet Maven est identifié par ses coordonnées : groupId:artifactId:version

Dans mon exemple, les coordonnées du projet sont donc org.exemple.demo:mon-appli:1.0-SNAPSHOT.

Les versions du projet

Toujours par convention, Maven donne un statut particulier aux versions ayant pour suffixe -SNAPSHOT.

En effet, cela veut dire que le code de cette version de l'application n'est pas figé. C'est une version en cours de développement.

Par opposition, si la version ne se termine pas par le suffixe -SNAPSHOT, cela signifie qu'il s'agit d'une release de l'application et que son code est figé.

Les versions snapshot font l'objet de traitements particuliers, notamment dans la gestion des dépendances. Je reviendrai sur ce point dans le chapitre traitant des dépendances.

Ainsi, vous l'aurez compris, pendant le développement de votre application, vous devez avoir le suffixe -SNAPSHOT pour en faire une version snapshot. Et une fois la version terminée, prête à être déployée, vous devez enlever ce suffixe pour en faire une version release.

Les informations générales du projet

<project>
...
<!-- ===== Informations générales ===== -->
<name>Mon Application</name>
<description>
La super application qui sert à faire ceci/cela...
</description>
<url>http://www.exemple.org/mon-appli</url>
...
</project>

Ensuite, viennent les informations générales du projet, avec les balises :

  • name : le nom du projet

  • description : la description du projet

  • url : URL du projet ou de l'application en production.

L'organisation gérant le projet

<project>
...
<!-- ===== Organisation ===== -->
<organization>
<name>Mon Entreprise</name>
<url>http://www.exemple.org</url>
</organization>
...
</project>

Vous pouvez préciser des informations concernant l'organisation gérant le projet, avec la balise organization.

Si vous travaillez comme prestataire de service, vous mettrez ici les informations du client pour lequel vous développez le projet.

Les licences du projet

<project>
...
<!-- ===== Licences ===== -->
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
...
</project>

Vous pouvez indiquer la ou les licences du projet grâce à la balise <licenses> et une sous-balise <license> par licence.

Ceci est important si le projet est disponible publiquement ou s'il est sous licence libre.

Les propriétés

Très bien, vous avez vu qu'il était possible de définir tout un tas d'informations pour notre projet. Mais il est possible d'ajouter un peu de généricité dans tout cela grâce aux propriétés.

Celles-ci sont des sortes de constantes. Elles sont remplacées par leur valeur lors de l'exécution de Maven en utilisant la notation ${maPropriete} (qui sera remplacée par la valeur de la propriété maPropriete).

Vous pouvez définir les propriétés directement dans le fichier pom.xml, grâce à la balise <properties> :

<project>
...
<!-- =============================================================== -->
<!-- Properties -->
<!-- =============================================================== -->
<properties>
<maPropriete>la valeur de la propriété</maPropriete>
<uneAutrePropriete>la valeur de la propriété</uneAutrePropriete>
</properties>
...
</project>

Voici un exemple d'utilisation des propriétés : je voudrais utiliser dans mon projet un framework composé de plusieurs bibliothèques mais ne définir qu'une seule fois sa version.

<project>
...
<properties>
<apache.struts.version>2.5.10.1</apache.struts.version>
</properties>
...
<dependencies>
<!-- ===== Apache Struts ===== -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>${apache.struts.version}</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>${apache.struts.version}</version>
</dependency>
</dependencies>
...
</project>

Propriétés pré-définies

En plus des propriétés que vous pouvez définir vous-même grâce à la balise <properties>, il existe également des propriétés pré-définies :

  • project.basedir : donne le chemin vers le répertoire de base du projet, c'est-à-dire la racine de votre projet où se trouve le fichier pom.xml.

  • project.baseUri : donne le chemin vers le répertoire de base du projet, mais sous forme d'URI.

  • maven.build.timestamp : donne l'horodatage du lancement du build Maven.

Propriétés particulières

Vous pouvez aussi accéder à des propriétés particulières grâce aux préfixes suivants :

  • env. : permet de renvoyer la valeur d'une variable d'environnement. Par exemple, ${env.PATH} renvoie la valeur de la variable d'environnement PATH.

  • project. : renvoie la valeur d'une balise dans le fichier pom.xml du projet, en utilisant le point (.) comme séparateur de chemin pour les sous-balises. Par exemple,

    <project>
    <organization>
    <name>1.0</name>
    </organization>
    </project>

    est accessible via ${project.organization.name}.

  • settings. : renvoie la valeur d'une balise dans le(s) fichier(s) settings.xml utilisé(s) par Maven. Utilise la notation pointée comme pour les propriétés de project.

  • java. : renvoie la valeur d'une propriété système de Java. Ces propriétés sont les mêmes que celles accessibles via java.lang.System.getProperties(). Par exemple, ${java.version} renvoie la version de Java. Pour plus de détails, consultez la JavaDoc.

Enfin, sachez que certaines propriétés permettent de définir des configurations par défaut de Maven ou de certains plugins. C'est le cas par exemple de la propriété project.build.sourceEncoding ajoutée par l'archétype quickstart lors du mvn archetype:generate. Je vous en parlerai en temps voulu dans les différents chapitres de ce cours.

Le build

En plus des informations de base et des propriétés, vous pouvez paramétrer les différents éléments du processus de construction de Maven, qu'on appelle le build.

La configuration du build se fait grâce à la balise <build> et ses sous-balises.

Voici un exemple où je définis un chemin de sortie autre que celui par défaut (${project.basedir}/target) :

<project>
...
<!-- =============================================================== -->
<!-- Build -->
<!-- =============================================================== -->
<build>
<directory>${project.basedir}/output</directory>
</build>
...
</project>

Si je reprends le premier projet Maven que nous avons créé dans le chapitre précédant, je peux, par exemple, rendre le JAR généré exécutable en demandant à Maven d'indiquer la classe Main dans le Manifest du JAR :

<project>
...
<!-- =============================================================== -->
<!-- Build -->
<!-- =============================================================== -->
<build>
<!-- Gestion des plugins (version) -->
<pluginManagement>
<plugins>
<!-- Plugin responsable de la génération du fichier JAR -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<!-- Création du Manifest pour la définition de la classe Main -->
<manifest>
<mainClass>org.exemple.demo.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
...
</project>

Après avoir relancé la construction du projet avec mvn package, vous pourrez désormais lancer votre application Java sans indiquer la class main dans la ligne de commande :

java -jar target/mon-appli-1.0-SNAPSHOT.jar

Filtrer des fichiers ressources

Les fichiers ressources sont des fichiers qui n'ont pas à être compilés, mais simplement copiés dans le livrable généré par Maven. Par convention, ces fichiers se trouvent dans le répertoire src/main/resources (répertoire à créer si besoin).

Un peu plus haut, je vous disais qu'il était possible de dire à Maven de remplacer les propriétés par leur valeurs dans des fichiers en filtrant les fichiers ressource.

Voyons tout de suite un exemple. Vous avez un fichier info.properties chargé par votre application et vous voulez mettre dans ce fichier une propriété contenant la version du projet :

  1. Vous mettez ce fichier dans le répertoire src/main/resources.

  2. Dans ce fichier, vous utilisez la même syntaxe que dans le fichier pom.xml :

    # Propriété contenant la version du projet
    org.exemple.demo.version=${project.version}
  3. Ensuite vous indiquez à Maven, dans le fichier pom.xml, de filtrer les fichiers du répertoire src/main/resources avec la balise <filtering> :

    <project>
    ...
    <build>
    <resources>
    <resource>
    <directory>src/main/resources</directory>
    <filtering>true</filtering>
    </resource>
    </resources>
    </build>
    ...
    </project>

Si vous avez des fichiers à ne pas filtrer dans le répertoire src/main/resources, il est possible de faire des sous-répertoires dans ce dernier afin d'organiser vos fichiers.

Voici un exemple où seulement les fichiers du sous-dossier filtered doivent être filtrés :

🗁 src/main/resources
├── 🗁 filtered
│ └── 🗎 info.properties
└── 🗁 raw
└── 🗎 fichierX
<project>
...
<build>
<resources>
<resource>
<directory>src/main/resources/filtered</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources/raw</directory>
<filtering>false</filtering>
</resource>
</resources>
</build>
...
</project>

Si vous voulez aller plus loin sur la configuration du build dans le POM, vous pouvez consulter la documentation.

Les profils

Les profils permettent de créer des options dans le build Maven.

Vous pouvez par exemple envisager deux environnements cibles (un de test, un de production) et embarquer, dans le JAR généré, des fichiers de configurations différents en fonction de la cible. Pour cela, pas besoin de mettre à la main les bons fichiers dans le répertoire src/main/resources avant le build. Il suffit de créer deux profils (test et prod), chacun définissant un répertoire de fichiers ressources différent :

<project>
...
<!-- =============================================================== -->
<!-- Profils -->
<!-- =============================================================== -->
<profiles>
<!-- Profil pour l'environnement de test -->
<profile>
<id>test</id>
<build>
<resources>
<resource>
<directory>src/main/resources/conf-test</directory>
</resource>
</resources>
</build>
</profile>
<!-- Profil pour l'environnement de production -->
<profile>
<id>prod</id>
<build>
<resources>
<resource>
<directory>src/main/resources/conf-prod</directory>
</resource>
</resources>
</build>
</profile>
</profiles>
...
</project>

Il ne vous reste plus qu'à mettre les fichiers de configuration de test et de production dans leur répertoire ressource respectif et d'activer le bon profil lors du lancement du build Maven grâce à l'option -P :

# Pour construire un livrable pour l'environnement de test :
mvn package -P test

# Pour construire un livrable pour l'environnement de production :
mvn package -P prod

Activation automatique des profils

Les profils peuvent également être activés automatiquement en fonction de certains critères définis dans la sous-balise <activation> :

...
<!-- Profil activé automatiquement si la version du JDK est 1.8
et sous-versions mineures (1.8.0_131 par exemple) -->
<profile>
<activation>
<jdk>1.8</jdk>
</activation>
...
</profile>
<!-- Profil activé automatiquement si la propriété système "environnement" vaut "test" -->
<profile>
<activation>
<property>
<name>environnement</name>
<value>test</value>
</property>
</activation>
...
</profile>
...

Dans cet exemple, pour activer le deuxième profil, vous pouvez lancer Maven comme ceci :

mvn package -Denvironnement=test

Vous comprendrez encore mieux l'intéret des profils quand vous aborderez la deuxième partie de ce cours, dans laquelle je vous montrerai comment fonctionne le build Maven et comment l'adapter parfaitement à votre projet.

Conclusion

Dans ce chapitre, je vous ai montré comment décrire votre projet en y ajoutant des informations générales, informations qui serviront à Maven au cours du build et qui seront reprises dans la génération du site de votre projet (nous verrons cela dans la deuxième partie du cours).

Je vous ai également présenté les propriétés qui permettent d'apporter un peu plus de souplesse et d'automatisation dans le build en généralisant des éléments (centralisation de valeurs, filtrage des fichiers ressources...).

Enfin, je vous ai parlé des profils qui servent à créer différentes alternatives dans le build du projet Maven.

Si vous voulez aller plus loin sur le POM, vous pouvez consulter :

Dans le chapitre suivant, nous allons parler d'architecture et voir comment mieux organiser votre projet avec Maven.

Exemple de certificat de réussite
Exemple de certificat de réussite