【问题标题】:How can I remove logback from a library's dependency while keeping SLF4J?如何在保留 SLF4J 的同时从库的依赖项中删除 logback?
【发布时间】:2015-11-20 19:10:59
【问题描述】:

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

    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>${logback.version}</version>
        <scope>runtime</scope>
    </dependency>

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

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

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.12</version>
    </dependency>

但是,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]

我检查了我的应用程序的依赖关系树,它对 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

另外,当我在我的 war 文件中检查 WEB-INF\lib 目录时,我发现了以下 jars。

logback-access-1.0.13.jar
logback-classic-1.0.13.jar
logback-core-1.0.13.jar

为什么 logback 会出现在我的 lib 目录中?正如我所听说的,运行时依赖项不应进入 libs 目录。

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

【问题讨论】:

    标签: java maven logging dependencies slf4j


    【解决方案1】:

    选项 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>
    

    选项 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>
    

    您问是否有理由直接依赖 Logback;对于图书馆作者来说,通常没有。他们的 pom 配置可能只是他们的一个小疏忽。有一些原因需要特别依赖 logback,但它们与启动有关(JoranConfiguratorStatusPrinter 之类的东西,不应该提供库。直接调用 Logback 类的其他原因包括 custom appenders 之类的东西,同样,它不应该出现在库中,只能出现在已部署的应用程序中。

    【讨论】:

    • 尝试了第二个选项,它可以工作。你能告诉我图书馆开发人员是否有正当理由在他们的 pom 中包含 logback 依赖项?我检查了他们的代码,他们没有直接使用任何 logback 功能。
    • 不幸的是,logback 本身作为“记录器”和“slf4j 绑定”合二为一,因此有时图书馆制造商将其包含在其中而没有意识到他们应该将其设为可选:|
    猜你喜欢
    • 2022-01-22
    • 2016-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-03
    相关资源
    最近更新 更多