I. Contexte
Maven est généralement associé aux projets Java, mais il peut être utilisé dans divers environnements. Un programme est composé de plusieurs éléments : le code source écrit par vous-même, les dépendances tierces (qui peuvent être des fichiers JAR, des fichiers binaires ou des bibliothèques C++). Dans ce cas, votre programme peut utiliser Maven pour charger automatiquement les dépendances nécessaires dans le répertoire local.
II. Scénario
1. Un programme dépend d'une dépendance tierce stockée dans un fichier ZIP. Actuellement, nous devons importer ce fichier ZIP via Maven et décompresser son contenu dans un répertoire spécifique lors du packaging pour qu'il soit accessible à notre programme.
Voici une exemple simplifié :
(1) Création d'une dépendance tierce au format ZIP
Structure du projet :
Nous utilisons pom.xml et assembly-zip-deploy.xml pour empaqueter le binaire Consul dans un fichier ZIP. Voici la configuration de ces deux fichiers.
pom.xml
<projet 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>
<groupId>com.example</groupId>
<artifactId>exemples-maven</artifactId>
<packaging>pom</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>exemples-maven</name>
<description>Démonstration pour maven-assembly-plugin</description>
<construction>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<exécutions>
<exécution>
<id>assemblage-packaging</id>
<phase>package</phase>
<objectifs>
<objectif>unique</objectif>
</objectifs>
</exécution>
</exécutions>
<configuration>
<descripteurs>
<descripteur>assembly-zip-deploy.xml</descripteur>
</descripteurs>
<outputDirectory>sortie</outputDirectory>
</configuration>
</plugin>
</plugins>
</construction>
<!-- Dépôt interne pour la publication de versions, nécessaire si vous ne configurez pas le dépôt central -->
<distributionManagement>
<dépôt>
<id>maven-releases</id>
<nom>maven-releases</nom>
<url>http://127.0.0.1:8081/repository/maven-releases/</url>
</dépôt>
<snapshotDépôt>
<id>maven-snapshots</id>
<nom>maven-snapshots</nom>
<url>http://127.0.0.1:8081/repository/maven-snapshots/</url>
</snapshotDépôt>
</distributionManagement>
</projet>
assembly-zip-deploy.xml
<?xml version='1.0' encoding='UTF-8'?>
<assemblage xmlns="http://maven.apache.org/ASSEMBLY/2.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
<id>package</id>
<formats>
<format>zip</format>
</formats>
<!-- Si cette valeur est false, le répertoire 'output' ne contiendra pas de sous-répertoire nommé comme artifactId_version. Les fichiers seront placés directement dans le répertoire 'output'. Voir la structure du fichier ZIP maven-assembly-demo-0.0.1-SNAPSHOT-package.zip.
Si elle est true, voir la structure du fichier ZIP maven-assembly-demo-0.0.1-SNAPSHOT-package-includebasedirectory.zip -->
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<répertoire>zipDeploy</répertoire>
<outputDirectory>/</outputDirectory> // Copie les fichiers du répertoire zipDeploy vers le répertoire output configuré par maven-assembly-plugin
</fileSet>
</fileSets>
</assemblage>
La structure du fichier ZIP produit est la suivante :
Remarque :
(a) Le nom du fichier ZIP se compose de finalName spécifié dans maven-assembly-plugin et de l'id spécifié dans assembly-zip-deploy.xml. Si maven-assembly-plugin n'a pas de finalName, celui-ci est défini par défaut comme artifactId-version. Pour éviter que l'id spécifié dans assembly-zip-deploy.xml ne figurent pas dans le nom du fichier ZIP, vous pouvez configurer <appendAssemblyId>false</appendAssemblyId> dans maven-assembly-plugin.
(b) L'id spécifié dans assembly-zip-deploy.xml sera inclus dans le nom du fichier ZIP et peut être utilisé comme classifier.
(2) Un autre projet dépendant du fichier ZIP créé précédemment.
Ce projet utilise également maven-assembly-plugin pour créer un artefact. Notre objectif est que le répertoire bin contienne le binaire Consul extrait du fichier ZIP précédemment créé.
pom.xml
<projet 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>
<groupId>com.example</groupId>
<artifactId>exemples-maven-dependance</artifactId>
<packaging>pom</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>exemples-maven-dependance</name>
<description>Démonstration pour maven-dependency-plugin</description>
<dépendances>
<dépendance>
<groupId>com.example</groupId>
<artifactId>exemples-maven</artifactId>
<version>0.0.1-SNAPSHOT</version>
<classifier>package</classifier>
<type>zip</type> // Dépendance sur un fichier ZIP
</dépendance>
</dépendances>
<construction>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<exécutions>
<exécution>
<id>décompression</id>
<phase>package</phase>
<objectifs>
<objectif>décompresser</objectif>
</objectifs></strong>
<configuration> <strong>// Pendant le phase de package, décompresse le fichier ZIP dépendant dans le répertoire bin</strong>
<artifactsItems>
<artifactItem>
<groupId>com.example</groupId>
<artifactId>exemples-maven</artifactId>
<version>0.0.1-SNAPSHOT</version>
<classifier>package</classifier>
<type>zip</type>
<outputDirectory>${project.basedir}/bin</outputDirectory>
</artifactItem>
</artifactsItems>
</configuration>
</exécution>
</exécutions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<exécutions>
<exécution>
<id>assemblage-packaging</id>
<phase>package</phase>
<objectifs>
<objectif>unique</objectif>
</objectifs>
</exécution>
</exécutions>
<configuration>
<descripteurs>
<descripteur>assembly-unpack-zip-deploy.xml</descripteur>
</descripteurs>
<outputDirectory>sortie</outputDirectory>
</configuration>
</plugin>
</plugins>
</construction>
<!-- Dépôt interne pour la publication de versions, nécessaire si vous ne configurez pas le dépôt central -->
<distributionManagement>
<dépôt>
<id>maven-releases</id>
<nom>maven-releases</nom>
<url>http://127.0.0.1:8081/repository/maven-releases/</url>
</dépôt>
<snapshotDépôt>
<id>maven-snapshots</id>
<nom>maven-snapshots</nom>
<url>http://127.0.0.1:8081/repository/maven-snapshots/</url>
</snapshotDépôt>
</distributionManagement>
</projet>
assembly-unpack-zip-deploy.xml
<?xml version='1.0' encoding='UTF-8'?>
<assemblage xmlns="http://maven.apache.org/ASSEMBLY/2.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
<id>package</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<répertoire>${project.basedir}</répertoire>
<outputDirectory>/</outputDirectory>
<inclus>
<inclure>bin/**</inclure>
<inclure>config/**</inclure>
</inclus>
</fileSet>
</fileSets>
</assemblage>
La structure du fichier ZIP produit est la suivante :
III. Explications sur les connaissances acquises
Site officiel : http://maven.apache.org/ref/3.6.3/maven-model/maven.html#class_dependency
1. Exactement cibler une dépendance à un certain élément (peut-être généré à partir d'un seul pom, comme log4j-to-slf4j-2.11.2.jar, log4j-to-slf4j-2.11.2-javadoc.jar, log4j-to-slf4j-2.11.2-sources.jar)
La balise <dependancy> indique une dépendance à un élément. En utilisant les propriétés multiples de <dependency>, nous pouvons préciser exactement quel élément dépendre. Une structure d'un élément est : artifactid-version-classifier.type, comme dans l'exemple ci-dessus où le fichier ZIP généré est maven-assembly-demo-0.0.1-SNAPSHOT-package.zip, alors artifactid est assembly-demo, version est 0.0.1-SNAPSHOT, classifier est package, et type est zip. Généralement, lorsque vous avez plusieurs artefacts générés à partir d'un même pom, vous utilisez classifier pour les différencier.
Par défaut, les dépendances sont définies comme suit :
<dependency>
<groupId>com.example</groupId>
<artifactId>exemples-maven</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
Le classifier est null et le type est jar. Ceci signifie que nous dépendons du fichier maven-assembly-demo-0.0.1-SNAPSHOT.jar. Le site officiel fournit un ensemble de types supportés, mais, après avoir examiné l'exemple ci-dessus, il semble que le type ne soit pas obligatoire et puisse être tout autre, comme zip. Le site officiel explique ces propriétés comme suit :
2. Les jar dépendants directs peuvent choisir s'ils doivent être transmis aux programmes qui dépendent de votre programme
Par exemple : A dépend directement de B (la dépendance est spécifiée dans le pom de A avec la balise <dependency>), maintenant C dépend directement de A. Si A décide s'il faut que B soit dépendance indirecte pour C, vous pouvez utiliser optional.
A.pom
<dependency>
<groupId>xxx</groupId>
<artifactId>B</artifactId>
<version>0.0.1-SNAPSHOT</version>
<optional>true</optional> // Indique que le programme dépendant d'A doit déclarer explicitement sa dépendance à B pour que B soit inclus dans les dépendances indirectes
</dependency>
C.pom
<dependency>
<groupId>xxx</groupId>
<artifactId>A</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
À ce stade, la liste des dépendances de C ne comprend pas B.
<dependency>
<groupId>xxx</groupId>
<artifactId>A</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>xxx</groupId>
<artifactId>B</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
À ce stade, la liste des dépendances de C comprend à la fois A et B.
Note :
Cette pratique doit être utilisée avec prudence. En général, si A dépend de B, cela signifie que la fonctionnalité de A nécessite B. C peut également avoir besoin de cette fonctionnalité. Cette pratique est souvent utilisée dans Spring avec l'annotation @ConditionOnClass(xxx.class) pour déterminer si une classe doit être exécutée ou non.