Skip to content

Maven

Bienvenue dans le Jour 2 de votre formation Java.

Dans le jour précédent, nous avons vu comment créer un projet à partir de zéro. Cette méthode fonctionne pour les petits projets ou les exemples, mais elle présente certaines limites à plus grande échelle. Par exemple, si vous souhaitez utiliser une bibliothèque externe dans votre code, vous devez :

  • Rechercher la bibliothèque sur le web et télécharger le fichier .jar correspondant.
  • Placer ce fichier .jar dans le dossier lib/.
  • Configurer le $PATH ou le --classpath pour inclure cette bibliothèque.
  • Oublier tout cela et ne plus jamais toucher à ce fichier.

Inutile de dire que cette méthode est loin d'être pratique et qu'elle n'encourage pas les mises à jour fréquentes des dépendances.

Dans ce chapitre, nous allons introduire l'utilisation d'un gestionnaire de paquets. Laissez-moi vous présenter Maven !

Gestionnaire de paquets

  • Il s'agit d'un outil permettant de télécharger et d'installer les dépendances requises (c'est-à-dire les bibliothèques externes).
  • Les paquets sont connectés à un dépôt d'artefacts : un serveur externe à partir duquel les paquets sont téléchargés.
  • Le dépôt par défaut de Maven est Maven Repository.
  • Les organisations configurent généralement leurs propres dépôts hébergés (par exemple : Jfrog's Artifactory, Sonatype Nexus, Gitlab Package Registry) afin de pouvoir publier leurs propres paquets.
  • Java dispose de deux gestionnaires de paquets que vous pouvez utiliser :
    • Maven : le standard de facto
    • Gradle : un gestionnaire de paquets relativement récent, qui fonctionne avec les mêmes dépôts que Maven. Il est principalement adopté par la communauté Android et Kotlin.

Générez un nouveau projet Maven

Un projet Java qui utilise Maven est appelé artifact. En tant que tel, il doit suivre une structure de fichier spécifique :

├── pom.xml       # project descriptor.
├── src           # sources root
   ├── main
      └── java  # main sources
          └── com.my-package.my-project
              └── App.java
   └── test
       └── java  # test sources
           └── com
               └── com.my-package.my-project
                   └── AppTest.java # Tests are suffixed with `Test`
└── target        # compiled classes & artifacts
    ├── classes
    └── my-project-1.0-SNAPSHOT.jar

En plus de la gestion des dépendances, Maven vous aide également à créer une structure de projet générique.

À vous de jouer

  • Lancez cette commande mvn archetype:generate pour générer un projet qui suit les conventions des projets Maven. Nommez le projet takima-agency et définissez io.takima.agencymanagement pour le group id.
  mvn -B archetype:generate \
    -DarchetypeVersion=1.4 \
    -DgroupId=io.takima.agencymanagement \
    -DartifactId=takima-agencymanagement

Info

  • Un artifact est un morceau de code, généralement compilé, qui peut être utilisé comme dépendance par d'autres artifacts. Par conséquent, la combinaison du name et du groupId d'un artifact doit être unique.
  • La commande mvn archetype:generate est utilisée pour créer un nouveau projet, basé sur un archetype (un modèle). Sans spécifier d'archetype, il utilisera maven-archetype-quickstart, qui est un Hello World.

Quand on crée la structure du projet, Maven génère aussi un fichier de configuration appelé pom.xml, pour Project Object Model.
Gardez-le propre, bien structuré et commenté. Référez-vous à la documentation officielle pour plus de détails.

Le fichier pom.xml est utilisé pour lister toutes les dépendances dont le projet a besoin.

Pour l'instant, le projet est livré avec une seule dépendance (très ancienne) JUnit. Il s'agit d'un framework Java populaire permettant d'écrire des tests automatiques.

pom.xml
<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/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <groupId>io.takima.agencymanagement</groupId>
  <artifactId>takima-agency</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>takima-agency</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

</project>

Maven scopes

  • scope est utilisé pour définir la visibilité d'une dépendance dans un projet Maven. Il y a 4 scopes importants que vous devez connaître : compile, runtime, provided et test.
  • <scope>test</scope> indique que cette dépendance est disponible seulement pendant la phase de test et pas au runtime.

Retirez JUnit 4

Comme nous n'allons pas faire de test vous pouvez retirer la dépendance JUnit ainsi que le fichier src/test.

Définissez la version de Java

Maven gère également la compilation de votre projet. Cela signifie qu'au lieu d'appeler la commande javac vous-même, vous pouvez appeler mvn compile et Maven appellera la commande javac pour vous.

La version de Java à utiliser est configurée par quelques propriétés :

  • maven.compiler.source: Utiliser les fonctionnalités de cette version de Java.

    • Cette propriété indique quelle valeur doit être définie pour l'option javac -source. Elle spécifie la version de Java que nous utilisons pour développer.
  • maven.compiler.target: Compiler un binaire en bytecode compatible avec cette version.

    • Cette propriété indique quelle valeur doit être définie pour l'option javac -target. Elle spécifie la version minimale de la JVM avec laquelle le bytecode généré doit être compatible.

À vous de jouer

  • Définissez une property appelée java.version et mettez la dernière version de Java LTS (eg: 21).
  • Utilisez maven.compiler.source et maven.compiler.target pour définir cette version.
<!-- ... -->
<properties>
    <java.version>17</java.version>
    <maven.compiler.source>${java.version}</maven.compiler.source>
    <maven.compiler.target>${java.version}</maven.compiler.target>
</properties>
<!-- ... -->

Compilez un jar avec Maven

Maven definit un cycle de vie de construction{:target="blank"} pour accomplir différentes tâches pour le projet :
_compile
, package, test, deploy, ...

  • Lancez la commande clean package pour builder et packager le projet :
    mvn clean package
    
    Cette commande compile l'artifact dans le répertoire target/. Il doit contenir des fichiers .class , ainsi qu'un fichier .jar qui les packages tous.

jar

  • Un fichier .jar est comme un zip contenant les fichiers Java compilés. Il contient également un fichier exécutable.
  • Rappelez-vous de mettre le target/ dans votre .gitignore car il contient des fichiers binaires générés, qui ne doivent pas être commit.
  • Essayez de lancer le jar avec la commande suivante :
    java -jar target/takima-agencymanagement-1.0-SNAPSHOT.jar
    

Failure

No main manifest attribute in target/takima-agencymanagement-1.0-SNAPSHOT.jar

Cette erreur montre que Java ne sait pas quel fichier est exécutable dans le jar. En fait il vous demande de lui indiquer quelle classe définit la méthode public void main().

Fichier exécutable .jar

  • Modifiez le pom.xml et ajoutez ces quelques lignes :
<build>
  <plugins>
    ...  
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-jar-plugin</artifactId>
      <configuration>
        <archive>
          <manifest>
            <mainClass>io.takima.agencymanagement.App</mainClass>
          </manifest>
        </archive>
      </configuration>
    </plugin>
  </plugins>
</build>
  • Packagez le jar à nouveau et décompressez l'archive avec un gestionnaire d'archives pour voir les fichiers qu'elle contient.
mvn clean package
cd target/
unzip takima-agencymanagement-1.0-SNAPSHOT.jar

Assurez-vous que l'archive contienne un MANIFEST.MF qui pointe vers votre Main.class.

Archive:  takima-agencymanagement-1.0-SNAPSHOT.jar
creating: META-INF/
inflating: META-INF/MANIFEST.MF
- Lancez le jar à nouveau, ça devrait fonctionner !

java -jar takima-agencymanagement-1.0-SNAPSHOT.jar

Fichiers modifiés

pom.xml
src/
.gitignore

N'oubliez pas de Commit votre travail !