Shade plugin Maven

De EjnTricks

Les projets Maven focntionnent avec des dépendances et permettent de générer des fichier JAR qui contiennent le code compilé. Les programmes peuvent être assemblés à l'aide du plugin [Assembly plugin Maven|maven-assembly-plugin]. Cependant, le plugin maven-shade-plugin permet de changer ce mode de fonctionnement en générant un fichier JAR contenant l'ensemble des classes.

Cet article présente différents cas d'utilisation de ce plugin.

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


Hand-icon.png Votre avis

Nobody voted on this yet

 You need to enable JavaScript to vote


Multiples-icon.png Création patch

Il peut arriver qu'une dépendance comporte un bug ou qu'il soit nécessaire de la modifier le comportement d'une classe. Dans ce cas, il est difficile de réaliser une extension et de la déployer, car il faudra s'assurer que la modification soit prise en compte en priorité par le ClassLoader.

Le plugin va donc permettre de mettre un place un projet, avec les classes à modifier, et d'injecter la compilation de celle-ci avec les classes de la librairie modifiée.

Pour cet article, la librairie log4j-over-slf4j est prise pour exemple. L'objectif de celleci est de remplacer la dépendance Log4J dans les projets afin que le code écrit pour ce logger soit dirigé vers la librairie Slf4J. Pour un projet, les classes Category / ConsoleAppender / Logger, du paquet org.apache.log4j, ont été modifiées afin d'injecter du code standard de Log4J manquant.

Afin de faciliter la compilation et la génération du paquet, le projet Maven est construit comme celui patché, à savoir que une définition du projet sur org.slf4j.slf4j-parent.

  <parent>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-parent</artifactId>
    <version>1.7.25</version>
  </parent>

Les classes sont récupérées, étant OpenSource, et modifiées comme souhaités dans le projet. Il reste à utiliser le plugin pour générer un paquet JAR qui contient les classes du projet initial avec remplacement de celles modifiées.

La configuration est mise en place dans un profile replaceClasses.

L'élément artifactSet dans la section configuration permet de spécifier quelle dépendance est prise en compte dans le paquet généré. Comme le projet dépend de la librairie log4j-over-slf4j, la dépendance slf4-api est automatiquement prise en compte. Or cette dernière ne doit pas être intégrée. IL est donc nécessaire de spécifier que seuls le projet et la librairie log4j-over-slf4j doivent être pris en compte.

                  <artifactSet>
                    <includes>
                      <include>${project.groupId}:${project.artifactId}</include>
                      <include>org.slf4j:log4j-over-slf4j</include>
                    </includes>
                  </artifactSet>

Afin de spécialiser la génération, des filtres sont également mis en place à l'aide de l'élément filters dans lequel ssible de spécifier les éléments à prendre en compte pour chacune des intégrations. Pour cet exemple, les classes modifiées sont exclues de la librairie log4j-over-slf4j et toutes les classes du projet sont prises en compte.

                  <filters>
                    <filter>
                      <artifact>org.slf4j:log4j-over-slf4j</artifact>
                      <excludes>
                        <exclude>org/apache/log4j/Category.class</exclude>
                        <exclude>org/apache/log4j/ConsoleAppender.class</exclude>
                        <exclude>org/apache/log4j/Logger.class</exclude>
                      </excludes>
                    </filter>
                    <filter>
                      <artifact>${project.groupId}:${project.artifactId}</artifact>
                      <includes>
                        <include>**</include>
                      </includes>
                    </filter>
                  </filters>

Le profile complet est le suivant.

    <profile>
      <id>replaceClasses</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.2.1</version>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>shade</goal>
                </goals>
                <configuration>
                  <artifactSet>
                    <includes>
                      <include>${project.groupId}:${project.artifactId}</include>
                      <include>org.slf4j:log4j-over-slf4j</include>
                    </includes>
                  </artifactSet>
                  <filters>
                    <filter>
                      <artifact>org.slf4j:log4j-over-slf4j</artifact>
                      <excludes>
                        <exclude>org/apache/log4j/Category.class</exclude>
                        <exclude>org/apache/log4j/ConsoleAppender.class</exclude>
                        <exclude>org/apache/log4j/Logger.class</exclude>
                      </excludes>
                    </filter>
                    <filter>
                      <artifact>${project.groupId}:${project.artifactId}</artifact>
                      <includes>
                        <include>**</include>
                      </includes>
                    </filter>
                  </filters>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </profile>

Examples-icon.png A noter qu'il serait possible de s'affranchir de la configuration des includes et excludes. En effet, l'ordre des filtres fait que les classes du projet viennent écraser celle de la dépendance modifiée.

La génération s'effectue avec la commande suivante.

#mvn -P replaceClasses clean package

Deux JARs seront alors créés dans le répertoire target.

  • original-maven-shade-plugin-1.7.25.jar qui contient le code compilé du projet;
  • maven-shade-plugin-1.7.25.jar qui contient le paquet complet avec les classes de la dépendance et celles modifiées du projet.

Dans le cadre de cet article, le paquet maven-shade-plugin-1.7.25-sources.jar est également créé avec le code source. Cela provient de la configuration Maven du projet parent.


Viewer icon.png Voir aussi

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