如何在保留SLF4J的同时从库的依赖项中删除logback?

Lah*_*ima 12 java logging dependencies slf4j maven

在我的Vaadin项目中,我依赖于某个库.该库使用slf4j进行日志记录.在库pom中,logback slf4j绑定被添加为运行时依赖项.

    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>${logback.version}</version>
        <scope>runtime</scope>
    </dependency>
Run Code Online (Sandbox Code Playgroud)

在我的应用程序中,我直接使用log4j进行日志记录.我希望库添加的日志进入我的log4j日志.

为此,我在我的pom中添加了以下内容,包括slf4j log4j绑定

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.12</version>
    </dependency>
Run Code Online (Sandbox Code Playgroud)

然而,slf4j抱怨它发现了多个绑定.

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/D:/program_files/apache-tomcat-8.0.24/temp/0-ROOT/WEB-INF/lib/logback-classic-1.0.13.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/D:/program_files/apache-tomcat-8.0.24/temp/0-ROOT/WEB-INF/lib/slf4j-log4j12-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
Run Code Online (Sandbox Code Playgroud)

我检查了我的应用程序的依赖树,它依赖于logback.(以下是对logback的唯一依赖)

[INFO] |  +- com.mycompany.mylib:libname:jar:1.1.0-SNAPSHOT:compile
[INFO] |  |  +- org.slf4j:jcl-over-slf4j:jar:1.7.5:runtime
[INFO] |  |  +- ch.qos.logback:logback-classic:jar:1.0.13:runtime
[INFO] |  |  |  \- ch.qos.logback:logback-core:jar:1.0.13:runtime
[INFO] |  |  +- ch.qos.logback:logback-access:jar:1.0.13:runtime
Run Code Online (Sandbox Code Playgroud)

此外,当我WEB-INF\lib在我的war文件中检查内部目录时,我发现了以下jar.

logback-access-1.0.13.jar
logback-classic-1.0.13.jar
logback-core-1.0.13.jar
Run Code Online (Sandbox Code Playgroud)

为什么logback最终出现在我的lib目录中?正如我所听到的,运行时依赖项不应该进入libs目录.

我该如何解决这个问题?该库是在我公司内部开发的,如果需要,我可以要求库开发人员删除logback运行时依赖项.

dur*_*597 17

选项1:他们改变了他们的pom.

解决这个问题的最简单方法是让您自己公司的库开发人员将logback标记为可选,并明确要求SLF4J作为编译依赖项.这是在Maven中进行SLF4J 的正确,规范的方法.换一种说法:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>${slf4j.version}</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>${logback.version}</version>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>
Run Code Online (Sandbox Code Playgroud)

选项2:您修改了它们在pom中的依赖关系.

如果你想自己修复它而不经过它们,那么你可以exclusions在声明它们的依赖时使用标记.换句话说,在你的pom中,做:

<dependency>
    <groupId>your.company</groupId>
    <artifactId>libraryname</artifactId>
    <version>${theirlibrary.version}</version>
    <exclusions>
        <exclusion>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
        </exclusion>
    </exclusions>
</dependency>
Run Code Online (Sandbox Code Playgroud)

你问是否有理由直接依赖Logback; 对于图书馆作者来说,通常没有.他们的pom配置可能只是他们的一个小的疏忽.有一些原因需要专门依赖于logback,但它们与启动有关(用JoranConfigurator或者StatusPrinter那些东西,不应该提供库.其他原因直接调用Logback类包括自定义appender之类的东西,再次,它不应该出现在库中,只应该是已部署的应用程序.

  • 尝试了第二个选项,它可以工作。您能否告诉我,图书馆开发人员是否有正当理由在他们的pom中包含logback依赖项?我检查了他们的代码,他们没有直接使用任何注销功能。 (3认同)