Jar plugin Maven

De EjnTricks
Révision de 24 décembre 2018 à 10:23 par Etienne (discussion | contributions)

(diff) ← Version précédente | Voir la version courante (diff) | Version suivante → (diff)

Pour les projets Maven de type Jar, le plugin maven-jar-plugin est responsable de la génération du package. Cet article présente quelques utilisations du plugin afin de controler le paquet généré.

Les exemples décrits sont disponibles sous ce lien : http://www.svn.jouvinio.net/study/trunk/maven/maven-jar-plugin


Hand-icon.png Votre avis

Nobody voted on this yet

 You need to enable JavaScript to vote


Mylogs-icon.png Fichier manifest

Le fichier MANIFEST.MF généré par défaut contient trois informations.

Manifest-Version: 1.0
Built-By: user_name
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_144

Ces informations sont complétées en fonction des variables d'environnement. Cependant, il est possible de paramétrer le contenu de ce fichier manifest. Tous les exemples présentés sont contruits sous la forme de profile dans le fichier pom.xml.

Ajout implémentation par défaut

Profile defaultImpl dans le projet exemple. Pour compiler le projet.

#mvn -P defaultImpl clean package

La configuration Maven est la suivante.

    <profile>
      <id>defaultImpl</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
              <archive>
                <manifest>
                  <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                </manifest>
              </archive>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>

En spécifiant la valeur true sur l'élément de configuration addDefaultImplementationEntries, les valeurs suivantes sont ajoutées.

Implementation-Title: ${project.name}
Implementation-Version: ${project.version}
Implementation-Vendor-Id: ${project.groupId}
Implementation-Vendor: ${project.organization.name}
Implementation-URL: ${project.url}

Dans le cadre de cet article, le fichier MANIFEST.MF produit est le suivant.

Manifest-Version: 1.0
Implementation-Title: Study Maven JAR plugin
Implementation-Version: 0.0.1-SNAPSHOT
Built-By: etienne
Implementation-Vendor-Id: fr.ejn.tutorial.maven
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_144

Fichier spécific

Profile specificLocation dans le projet exemple. Pour compiler le projet.

#mvn -P specificLocation clean package

La configuration Maven est la suivante.

    <profile>
      <id>specificLocation</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
              <archive>
                <manifestFile>src/main/specific/META-INF/MANIFEST.MF</manifestFile>
              </archive>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>

Le contenu du fichier src/main/specific/META-INF/MANIFEST.MF est le suivant.

Manifest-Version: 1.0
Implementation-Title: Study Maven JAR plugin
Implementation-Version: 0.0.1-SNAPSHOT
Implementation-Vendor-Id: fr.ejn.tutorial.maven
Source: From specific

Le fichier MANIFEST.MF produit est le suivant.

Manifest-Version: 1.0
Implementation-Title: Study Maven JAR plugin
Implementation-Version: 0.0.1-SNAPSHOT
Built-By: etienne
Implementation-Vendor-Id: fr.ejn.tutorial.maven
Source: From specific
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_144

A noter que le fichier produit ne contient pas que le contnu du fichier pécifié. Des propriétés par défaut sont ajoutées.

  • Built-By
  • Build-Jdk
  • Created-By

Depuis resources

Profile fromResources dans le projet exemple. Pour compiler le projet.

#mvn -P fromResources clean package

La configuration Maven est la suivante.

    <profile>
      <id>fromResources</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
              <archive>
                <manifestFile>${project.build.directory}/classes/META-INF/MANIFEST.MF</manifestFile>
              </archive>
            </configuration>
          </plugin>
        </plugins>
        <resources>
          <resource>
            <directory>src/main/resources</directory>
            <filtering>false</filtering>
          </resource>
          <resource>
            <directory>src/main/addedResources</directory>
            <filtering>false</filtering>
          </resource>
        </resources>
      </build>
    </profile>

A noter, la configuration des resources pour ajouter le répertoire src/main/addedResources dans lequel est placé le fichier META-INF/MANIFEST.MF dont le contenu est le suivant.

Manifest-Version: 1.0
Implementation-Title: Study Maven JAR plugin
Implementation-Version: Dev version
Implementation-Vendor-Id: fr.ejn.tutorial.maven
Source: From resources

La resource étant ajoutée, le fichier est placé dans le répertoire de compilation. Cependant, celui-ci n'est pas pris en compte lors de la génération du paquet, et il faut l'indiquer explicitement, d'où la valeur ${project.build.directory}/classes/META-INF/MANIFEST.MF.


Le fichier MANIFEST.MF produit est le suivant.

Manifest-Version: 1.0
Implementation-Title: Study Maven JAR plugin
Implementation-Version: Dev version
Built-By: etienne
Implementation-Vendor-Id: fr.ejn.tutorial.maven
Source: From resources
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_144

A noter que le fichier produit ne contient pas que le contnu du fichier pécifié. Des propriétés par défaut sont ajoutées.

  • Built-By
  • Build-Jdk
  • Created-By

Depuis resources avec contenu dynamic

Profile specificFilteredLocation dans le projet exemple. Pour compiler le projet.

#mvn -P specificFilteredLocation clean package

La configuration Maven est la suivante.

    <profile>
      <id>specificFilteredLocation</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
              <archive>
                <manifestFile>${project.build.directory}/classes/META-INF/MANIFEST.MF</manifestFile>
              </archive>
            </configuration>
          </plugin>
        </plugins>
        <resources>
          <resource>
            <directory>src/main/resources</directory>
            <filtering>false</filtering>
          </resource>
          <resource>
            <directory>src/main/filterResources</directory>
            <filtering>true</filtering>
          </resource>
        </resources>
      </build>
    </profile>

A noter, la configuration des resources pour ajouter le répertoire src/main/filterResources, avec le paramètre filtering à true dans lequel est placé le fichier META-INF/MANIFEST.MF dont le contenu est le suivant.

Manifest-Version: 1.0
Implementation-Title: ${project.name}
Implementation-Version: ${project.version}
Implementation-Vendor-Id: ${project.groupId}
Source: From filter resources

Ce fichier contient des balises qui vont permettre d'injecter des valeurs, comme le numéro de version du projet.

La resource étant ajoutée, le fichier est placé dans le répertoire de compilation. Cependant, celui-ci n'est pas pris en compte lors de la génération du paquet, et il faut l'indiquer explicitement, d'où la valeur ${project.build.directory}/classes/META-INF/MANIFEST.MF.


Le fichier MANIFEST.MF produit est le suivant.

Manifest-Version: 1.0
Implementation-Title: Study Maven JAR plugin
Implementation-Version: 0.0.1-SNAPSHOT
Built-By: etienne
Implementation-Vendor-Id: fr.ejn.tutorial.maven
Source: From filter resources
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_144

A noter que le fichier produit ne contient pas que le contnu du fichier pécifié. Des propriétés par défaut sont ajoutées.

  • Built-By
  • Build-Jdk
  • Created-By

Specific par configuration

Profile specificByConfiguration dans le projet exemple. Pour compiler le projet.

#mvn -P specificByConfiguration clean package

La configuration Maven est la suivante.

    <profile>
      <id>specificByConfiguration</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
              <archive>
                <manifest>
                  <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                </manifest>
                <manifestEntries>
                  <Built-By></Built-By>
                  <Build-Jdk></Build-Jdk>
                  <Created-By></Created-By>
                  <By-Configuration>new value</By-Configuration>
                </manifestEntries>
              </archive>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>

Pour cette configuration, les entrées du manifeste sont spécifiée explicitement. Les valeurs par défaut (Built-By, Build-Jdk ou Created-By) sont remplacées mais non supprimées.

Le fichier MANIFEST.MF produit est le suivant.

Manifest-Version: 1.0
Implementation-Title: Study Maven JAR plugin
Implementation-Version: 0.0.1-SNAPSHOT
Built-By: 
Implementation-Vendor-Id: fr.ejn.tutorial.maven
By-Configuration: new value
Created-By: 
Build-Jdk:

Suppression entrées défaut

L'objectif initial de cette étude était de supprimer les entrées par défaut dans le manifest. Sur les précédents exemples, il a été démontré q'il était possible de surcharger les valeurs, ou de les spécifier avec des chaînes vides, mais aucune configuration permettait de les supprimer. Un premier test serait d'utiliser la tâche jar de ANT.

Profile byAnt dans le projet exemple. Pour compiler le projet.

#mvn -P byAnt clean package

La configuration Maven est la suivante.

    <profile>
      <id>byAnt</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.8</version>
            <executions>
              <execution>
                <phase>package</phase>
                <configuration>
                  <target>
                    <jar file="${project.build.directory}/${project.build.finalName}.jar"
                      update="true" manifest="src/main/specific/META-INF/MANIFEST.MF"/>
                  </target>
                </configuration>
                <goals>
                  <goal>run</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </profile>

Pour cette tâche ANT, le paquet est mis à jour en spécifiant explicitement l'emplacement du manifest, soit src/main/specific/META-INF/MANIFEST.MF.

Cependant, comme pour les exécutions purement Maven, le manifest ne cotient pas uniquement le contenu du fichier spécifié.

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.4
Created-By: Apache Maven 3.3.9
Built-By: etienne
Build-Jdk: 1.8.0_144
Implementation-Title: Study Maven JAR plugin
Implementation-Version: 0.0.1-SNAPSHOT
Implementation-Vendor-Id: fr.ejn.tutorial.maven
Source: From specific

Cependant, l'utilisation de tâches ANT peut permettre de modifier le paquet généré. Le format Jar n'est autre qu'un fichier Zip. Donc, si il est vraiment souhaité de n'avoir que les entrées spécifiques, il faut décompresser le fichier, modifier le fichier dans le réprtoire de décompression, puis recompresser le contenu. Cette cinématique est configuré dans le profile onlySpecific. Pour compiler le projet.

#mvn -P onlySpecific clean package

La configuration Maven est la suivante.

    <profile>
      <id>onlySpecific</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.8</version>
            <executions>
              <execution>
                <phase>package</phase>
                <configuration>
                  <target>
                    <unzip src="${project.build.directory}/${project.build.finalName}.jar" dest="${project.build.directory}/tmp"/>
                    <delete file="${project.build.directory}/${project.build.finalName}.jar"/>
                    <copyfile src="src/main/specific/META-INF/MANIFEST.MF" dest="${project.build.directory}/tmp/META-INF/MANIFEST.MF" forceoverwrite="yes"/>
                    <zip destfile="${project.build.directory}/${project.build.finalName}.jar" basedir="${project.build.directory}/tmp"/>
                    <delete dir="${project.build.directory}/tmp"/>
                  </target>
                </configuration>
                <goals>
                  <goal>run</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </profile>

Le fichier MANIFEST.MF produit est le suivant.

Manifest-Version: 1.0
Implementation-Title: Study Maven JAR plugin
Implementation-Version: 0.0.1-SNAPSHOT
Implementation-Vendor-Id: fr.ejn.tutorial.maven
Source: From specific

Viewer icon.png Documentations officielles

Exemple (jar plugin) https://maven.apache.org/plugins/maven-jar-plugin/examples/manifest-customization.html

Exemple (archiver plugin) https://maven.apache.org/shared/maven-archiver/examples/manifest.html


Configuration-icon.png Suppression informations projet

Profile noDescriptor dans le projet exemple. Pour compiler le projet.

#mvn -P noDescriptor clean package

Lors de la constitution du paquet, les fichiers pom.properties et pom.xml sont ajoutés dans le répertoire META-INF/maven/${groupId}/${artifactId}, soit META-INF/maven/fr.ejn.tutorial.maven\maven-jar-plugin dans le cadre de cet exemple.

L'option addMavenDescriptor, dont la valeur par défaut est true, permet de valider ou annuler l'ajout. La configuration suivante permet d'annuler l'ajout des deux fichiers.

    <profile>
      <id>noDescriptor</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
              <archive>
                <addMavenDescriptor>false</addMavenDescriptor>
              </archive>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>


Run-icon.png Classe démarrage

Profile withMain dans le projet exemple. Pour compiler le projet.

#mvn -P withMain clean package

Il est possible de créer un paquet jar avec une classe par défaut identifiée dans le fichier MANIFEST.MF. L'exemple combine la référence à la classe par défaut, contenant la méthode main, et l'ajout des dépendances dans un sous répertoires libs.

    <profile>
      <id>withMain</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
              <archive>
                <manifest>
                  <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                  <addClasspath>true</addClasspath>
                  <classpathPrefix>libs</classpathPrefix>
                  <mainClass>fr.ejn.tutorial.maven.mavenJarPlugin.Tutorial</mainClass>
                </manifest>
              </archive>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>

Pour cet exemple, les valeurs par défaut sont ajoutées avec l'option addDefaultImplementationEntries. Les références aux dépendances sont ajoutés à l'aide de l'option addClasspath. A noter, la valeur libs/ de l'option classpathPrefix, permettant de spécifier le sous répertoire libs dans lequel les dépendances doivent être placées. Enfin, l'option mainClass permet d'indiquer la classe par défaut, soit fr.ejn.tutorial.maven.mavenJarPlugin.Tutorial dans le cadre de cet exemple.

Le fichier MANIFEST.MF produit contient les lignes suivantes.

Manifest-Version: 1.0
Implementation-Title: Study JAR plugin
Implementation-Version: 0.0.1-SNAPSHOT
Built-By: etienne
Implementation-Vendor-Id: fr.ejn.tutorial.maven
Class-Path: libs/slf4j-api-1.7.25.jar libs/slf4j-simple-1.7.25.jar
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_144
Main-Class: fr.ejn.tutorial.maven.mavenJarPlugin.Tutorial

Ainsi, il est possible d'exécuter le code à l'aide de la commande java avec l'option jar permettant d'indiquer le paquet a exécuter.

#java -jar maven-jar-plugin-0.0.1-SNAPSHOT.jar
[main] INFO fr.ejn.tutorial.maven.mavenJarPlugin.Tutorial - Simple message from main


Viewer icon.png Voir aussi

Documentation officielle: https://maven.apache.org/plugins/maven-jar-plugin/