【问题标题】:SLF4J Custom Binding Not WorkingSLF4J 自定义绑定不起作用
【发布时间】:2012-01-14 16:57:10
【问题描述】:

我们花了很多时间来开发我们自己的自定义日志系统(对与错,这是高层决定的!)并且我被要求编写一个自定义 SLF4J 绑定(API 实现),以便我们的许多使用 SLF4J 的组件(例如 Apache Camel)将开始记录到我们新的本土系统。

我已按照 SLF4J 网站上的说明操作到“T”,创建:

  • 一个StaticLoggerBinder,SLF4J 在运行时使用它来绑定LoggersLoggerFactory
  • 将用于“转发”org.slf4j.Logger 调用的记录器适配器
  • 记录器工厂(由静态记录器绑定器使用)

一切都编译得很好。我把它和slf4j-api-1.6.2.jar(他们希望我使用的版本)一起打包并添加到测试项目的lib 目录中。我将两个 JAR 添加到 Eclipse 的构建路径中。

我为测试项目创建了一个新的运行配置,在运行配置的Classpath 选项卡式窗格下,我看到它有User Entries >> TestBinding >> Slf4jBinding.jar and slf4j-api-1.6.2.jar

所以,两个 JAR 似乎都在运行配置的类路径中。

在项目中运行如下所示的驱动程序:

public static void main(String[] args) {
    Logger logger = LoggerFactory.getLogger(TestDriver.class);
    logger.error("Test");
}

我收到以下运行时错误:

SLF4J:无法加载类“org.slf4j.impl.StaticLoggerBinder”。 SLF4J:默认为无操作(NOP)记录器实现 SLF4J:详情请见http://www.slf4j.org/codes.html#StaticLoggerBinder

转到那个引用的站点,SLF4J 似乎在 Slf4jBinding.jar 内的类路径上找不到我的 StaticLoggerBinder,尽管不在 JAR 的根级别。

我查看了 SLF4J 的LoggerFactory.java 源文件,发现抛出这种错误的代码:

private final static void bind() {
    try {
        // the next line does the binding
        StaticLoggerBinder.getSingleton();
        INITIALIZATION_STATE = SUCCESSFUL_INITILIZATION;
        emitSubstituteLoggerWarning();
    } catch (NoClassDefFoundError ncde) {
        String msg = ncde.getMessage();
        if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
            INITIALIZATION_STATE = NOP_FALLBACK_INITILIZATION;
            Util
            .report("Failed to load class \"org.slf4j.impl.StaticLoggerBinder\".");
            Util.report("Defaulting to no-operation (NOP) logger implementation");
            Util.report("See " + NO_STATICLOGGERBINDER_URL
            + " for further details.");
        } // ...

显然,try 块顶部的调用 (StaticLoggerBinder.getSingleton()) 正在抛出 NoClassDefFoundError。我只是不明白为什么。

我选择不在这里粘贴我的代码,因为我认为这只是一个类路径问题。我的代码是否正确遵守 SLF4J 的绑定策略仍然未知,直到我能通过这个问题。

我需要在 Eclipse 中执行一个额外的步骤来配置类路径吗?出于某种原因,我的Slf4jBinding.jar 是否需要在其根目录中使用StaticLoggerBinder?我在这里没有想法。提前致谢!

【问题讨论】:

  • 你的StaticLoggerBinder是org.slf4j.impl.StaticLoggerBinder?
  • although not at the root level of the JAR,这是什么意思?为了找到您的课程,您的课程必须在 jar 内的 /org/slf4j/impl/StaticLoggerBinder.class,如果它在子文件夹中,则找不到。

标签: java eclipse classpath slf4j


【解决方案1】:

您的 jar 需要 org.slf4j.impl.StaticLoggerBinder 的自定义实现,并且该实现的完全限定类名必须完全是 org.slf4j.impl.StaticLoggerBinder。静态绑定将 SLF4J API 针对org.slf4j.impl.StaticLoggerBinder 的存根版本进行编译,然后在运行时类加载器将从 SLF4J 绑定加载真实版本。 SLF4J 的每个绑定都有一个适用于该特定绑定的类 org.slf4j.impl.StaticLoggerBinder 的不同版本。

【讨论】:

    【解决方案2】:

    与其完全从头开始,不如直接适应,例如slf4j-simple.jar 满足您的需求。所有的绑定代码都在那里,您只需要修改代码来执行实际的日志记录。

    【讨论】:

      【解决方案3】:

      您可以在您的项目中创建一个 org.slf4j.impl 包并在该包中实现一个名为 StaticLoggerBinder 的类,就像在 http://javaeenotes.blogspot.com/2011/12/custom-slf4j-logger-adapter.html 中解释的那样(我刚刚这样做了,它对我来说很好用)。

      请注意,您不需要为此构建 jar 文件,您只需要在类路径中访问 org.slf4j.impl.StaticLoggerBinder 类(它可以在 jar 中,但这不是强制性的)。

      【讨论】:

        猜你喜欢
        • 2023-04-01
        • 2019-12-08
        • 2016-12-29
        • 2017-06-13
        • 1970-01-01
        • 1970-01-01
        • 2021-02-18
        • 2020-02-06
        • 2018-12-20
        相关资源
        最近更新 更多