SLF4J自定义绑定不工作



我们花了很多时间开发我们自己的自定义日志记录系统(对与错,这是上级决定的!),我被要求编写一个自定义SLF4J绑定(API实现),这样我们的许多使用SLF4J的组件(如Apache Camel)将开始记录到我们新的国产系统。

我已经按照SLF4J网站上的说明创建了一个"T",创建:

  • SLF4J在运行时用于绑定到LoggersLoggerFactory类的StaticLoggerBinder
  • 将用于将org.slf4j.Logger调用"转发"到的记录器适配器
  • 记录器工厂(由静态记录器绑定器使用)

一切都很好。我将其jar起来,并将其与slf4j-api-1.6.2.jar(他们希望我使用的版本)一起添加到测试项目的lib目录中。我在Eclipse中将这两个JAR都添加到了构建路径中。

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

因此,这两个JAR似乎都在Run Configuration的类路径中。

在项目内部运行一个驱动程序时,它看起来像这样:

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似乎在类路径上找不到我的StaticLoggerBinder,该类路径位于Slf4jBinding.jar内部,尽管不在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吗?我在这里没有主意。提前感谢!

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

与其完全从头开始,不如根据您的需要调整例如slf4j-simple.jar。所有的绑定代码都在那里,您只需要调整代码来进行实际的日志记录。

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

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

最新更新