Conflit binding SLF4J

De EjnTricks

Le framework Slf4j permet de s'afranchir de la librairie utilisée pour la génération des logs. Cependant le système de chargement des classes peut engendrer l'affichage d'un message d' erreur suivant.

[ERROR] SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/usr/share/maven/repository/ch/qos/logback/logback-classic/1.0.13/logback-classic-1.0.13.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/usr/share/maven/repository/ch/qos/logback/logback-classic/1.1.3/logback-classic-1.1.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]

Ce message a été observé dans le cadre de l'étude des projets Apache Commons, lors de l'analyse de la couverture de tests. Cet article présente un moyen de s'affranchir de ce message.


Hand-icon.png Votre avis

Nobody voted on this yet

 You need to enable JavaScript to vote


Study icon.png Etude

Lors de l'éxécution du build Jenkins, la trace indique le message suivant.

[INFO] --- cobertura-maven-plugin:2.7:instrument (default-cli) @ apacheCommons ---
[INFO] Cobertura 2.1.1 - GNU GPL License (NO WARRANTY) - See COPYRIGHT file
[INFO] Cobertura: Saved information on 8 classes.
[INFO] Cobertura: Saved information on 8 classes.

[ERROR] SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/usr/share/maven/repository/ch/qos/logback/logback-classic/1.0.13/logback-classic-1.0.13.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/usr/share/maven/repository/ch/qos/logback/logback-classic/1.1.3/logback-classic-1.1.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]

Donc, lors de l'exécution, le plugin de couverture de test dépend d'une version de logback différente de celle qui est embarquée dans le projet.


Configuration-icon.png Configuration

Afin de s'affranchir du message d'erreur, il faut modifier la configuration dans le fichier pom.xml du projet en spécifiant le scope runtime. Celui-ci permet de ne pas charger la librairie lors de la compilation, et donc lors de l'analyse de la couverture de tests, mais quelle est obligatoire pour l'exécution. Ainsi, elle ne sera pas chargée lors de l'analyse.

Le fichier pom.xml contient la définition suivante.

<?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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <artifactId>apacheCommons</artifactId>
    <groupId>fr.ejn.tutorial</groupId>
    <name>Apache Commons Examples</name>
    <packaging>jar</packaging>
    <version>1.0</version>
    <description>Examples using Apache Commons frameworks</description>

    <dependencies>
        <dependency>
            <artifactId>commons-collections4</artifactId>
            <groupId>org.apache.commons</groupId>
            <version>${commons-collections4.version}</version>
        </dependency>
        <dependency>
            <artifactId>commons-io</artifactId>
            <groupId>commons-io</groupId>
            <version>${commons-io.version}</version>
        </dependency>
        <dependency>
            <artifactId>commons-csv</artifactId>
            <groupId>org.apache.commons</groupId>
            <version>${commons-csv.version}</version>
        </dependency>
        <dependency>
            <artifactId>commons-lang3</artifactId>
            <groupId>org.apache.commons</groupId>
            <version>${commons-lang3.version}</version>
        </dependency>
        <!-- For logging -->
        <dependency>
            <artifactId>logback-classic</artifactId>
            <groupId>ch.qos.logback</groupId>
            <version>${logback.version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <artifactId>logback-core</artifactId>
            <groupId>ch.qos.logback</groupId>
            <version>${logback.version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <artifactId>slf4j-api</artifactId>
            <groupId>org.slf4j</groupId>
            <version>${slf4j.version}</version>
        </dependency>
        
        <!-- For tests -->
        <dependency>
            <artifactId>junit</artifactId>
            <groupId>junit</groupId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-eclipse-plugin</artifactId>
                <groupId>org.apache.maven.plugins</groupId>
                <version>2.10</version>
                <configuration>
                    <downloadJavadocs>true</downloadJavadocs>
                    <downloadSources>true</downloadSources>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <groupId>org.apache.maven.plugins</groupId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <properties>
        <!-- Project properties -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compile.source>1.7</maven.compile.source>
        <maven.compile.target>1.7</maven.compile.target>
        
        <!-- Dependency versions -->
        <commons-collections4.version>4.1</commons-collections4.version>
        <commons-csv.version>1.4</commons-csv.version>
        <commons-io.version>2.5</commons-io.version>
        <commons-lang3.version>3.4</commons-lang3.version>
        <junit.version>4.12</junit.version>
        <logback.version>1.1.7</logback.version>
        <slf4j.version>1.7.21</slf4j.version>
    </properties>

</project>

La trace d'exécution est alors propre et présente les messages suivants.

[INFO] --- cobertura-maven-plugin:2.7:instrument (default-cli) @ apacheCommons ---
[INFO] Cobertura 2.1.1 - GNU GPL License (NO WARRANTY) - See COPYRIGHT file
[INFO] Cobertura: Saved information on 8 classes.
[INFO] Cobertura: Saved information on 8 classes.

[INFO] Instrumentation was successful.
[INFO] NOT adding cobertura ser file to attached artifacts list.


Viewer icon.png Voir aussi

Documentation officielle: http://www.slf4j.org/codes.html#multiple_bindings

Configuration Maven : https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope