slf4j Failed to load class “org.slf4j.impl.StaticLoggerBinder“ 错误 源码解析

2023-05-16

基本描述

slf4j 是日志的api 门面模式,引入slf4j-api就行,但是打印不出日志的,因为没有具体的实现类。

logback实现包 :

       <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.6</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.6</version>
        </dependency>

log4j 实现包 :


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

slf4j是怎么找到实现类的

  • 通过StaticLoggerBinder 来获取ILoggerFactory
  • StaticLoggerBinder类是sf4j-api没有的,需要实现类的jar包提供,并且包名是org.slf4j.impl
  • 如果没有实现包,就找不到StaticLoggerBinder类了,就报slf4j Failed to load class “org.slf4j.impl.StaticLoggerBinder”
  • 如果有多个实现包,pom依赖谁在前面,就先找到谁的。

相关源码

Logger logger = LoggerFactory.getLogger("aa");
// 获取Logger
public static Logger getLogger(String name) {
        ILoggerFactory iLoggerFactory = getILoggerFactory();
        return iLoggerFactory.getLogger(name);
    }
    
//获取工厂类
 public static ILoggerFactory getILoggerFactory() {
        if (INITIALIZATION_STATE == UNINITIALIZED) {
            synchronized (LoggerFactory.class) {
                if (INITIALIZATION_STATE == UNINITIALIZED) {
                    INITIALIZATION_STATE = ONGOING_INITIALIZATION;
                    //初始化
                    performInitialization();
                }
            }
        }
        switch (INITIALIZATION_STATE) {
        case SUCCESSFUL_INITIALIZATION:
            return StaticLoggerBinder.getSingleton().getLoggerFactory();
        case NOP_FALLBACK_INITIALIZATION:
            return NOP_FALLBACK_FACTORY;
        case FAILED_INITIALIZATION:
            throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);
        case ONGOING_INITIALIZATION:
            // support re-entrant behavior.
            // See also http://jira.qos.ch/browse/SLF4J-97
            //默认的工厂,实际上是走不到这逻辑
            return SUBST_FACTORY;
        }
        throw new IllegalStateException("Unreachable code");
    }

//平台初始化
private final static void performInitialization() {
        bind();
        if (INITIALIZATION_STATE == SUCCESSFUL_INITIALIZATION) {
            versionSanityCheck();
        }
    }
    
//绑定具体的slf4j的实现
private final static void bind() {
        try {
            Set<URL> staticLoggerBinderPathSet = null;
            // skip check under android, see also
            // http://jira.qos.ch/browse/SLF4J-328
            if (!isAndroid()) {
                staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
                reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
            }
            // the next line does the binding
            //StaticLoggerBinder类是sf4j-api没有的,需要实现类的jar包提供,并且包名是org.slf4j.impl
            StaticLoggerBinder.getSingleton();
            INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
            reportActualBinding(staticLoggerBinderPathSet);
            fixSubstituteLoggers();
            replayEvents();
            // release all resources in SUBST_FACTORY
            SUBST_FACTORY.clear();
        } catch (NoClassDefFoundError ncde) {
            String msg = ncde.getMessage();
            if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
                INITIALIZATION_STATE = NOP_FALLBACK_INITIALIZATION;
                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.");
            } else {
                failedBinding(ncde);
                throw ncde;
            }
        } catch (java.lang.NoSuchMethodError nsme) {
            String msg = nsme.getMessage();
            if (msg != null && msg.contains("org.slf4j.impl.StaticLoggerBinder.getSingleton()")) {
                INITIALIZATION_STATE = FAILED_INITIALIZATION;
                Util.report("slf4j-api 1.6.x (or later) is incompatible with this binding.");
                Util.report("Your binding is version 1.5.5 or earlier.");
                Util.report("Upgrade your binding to version 1.6.x.");
            }
            throw nsme;
        } catch (Exception e) {
            failedBinding(e);
            throw new IllegalStateException("Unexpected initialization failure", e);
        }
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

slf4j Failed to load class “org.slf4j.impl.StaticLoggerBinder“ 错误 源码解析 的相关文章

随机推荐

  • nginx(二十七)长连接和短连接

    一 长连接和短连接 概念 1 39 HTTP 39 的长连接和短连接 39 本质 39 上是 39 TCP 39 长连接和短连接 2 在 39 HTTP 1 0 39 中默认使用 39 短 39 连接 解读 xff1a 客户端和服务器 39
  • nginx(七十四)nginx与跨域细节探究

    一 nginx配置跨域 知识铺垫 强调 xff1a 跨域是 39 浏览器 39 行为 39 不是 39 服务器行为 43 43 43 43 43 43 43 43 43 43 43 43 43 43 34 跨域的两种解决手段 34 43 4
  • HTTP1.1(一)HTTP协议

    一 HTTP协议定义 RFC7230定义 说明 xff1a 关注 39 红色关键字 39 无状态 解读 xff1a 连续的 39 两个 39 请求 后续的请求 39 不能依赖 39 前一个请求 各个请求是 39 相互独立 39 基于请求 相
  • nginx(七十五)nginx与Vary响应头细节探讨

    一 Vary nginx与Vary有关联的地方 nginx源码分析处理Vary响应头的逻辑 CORS和缓存 gzip vary 1 gzip vary on 如果设置为 39 开启 39 2 服务器 39 返回数据 39 时会在头部带上 3
  • JDK1.8之Lambada表达式一

    一 lambada表达式简介 我们知道对于Java变量可以赋给其一个值 而如果想将 34 一块代码 一个完整的方法 34 赋给一个Java变量 如下所示 xff0c 怎么做呢 xff1f 你可能认为 就是下面的方式来实现 很显然 xff0c
  • Oracle(三)

    一 概述 1 DML xff08 data manipulation language 数据操作语言 xff09 insert update delete 2 DDL data definition language 数据定义语言 crea
  • 项目中权限控制系统的设计

    RBAC 权限 xff1a 权利 能做的 和限制 不能做的 xff0c 在权限范围内做好自己的事情 xff0c 不该看的不看 机密 xff0c 不该做的不做 xff01 最开始真正有权限的概念是在Linux上关于文件和目录的权限 xff0c
  • 每天一个Linux命令之(read)

    一 概述 read命令特点 xff1a 1 接收 39 标准输入 键盘 39 的输入 或其它 39 文件 描述符 39 的输入 2 得到输入后 然后将数据 39 保存 39 一个 39 变量 39 中 核心点 xff1a 39 数据源 39
  • LInux shell之(for in 用法总结)

    一 语法 for 变量名 in 列表 do 程序段 command done 注意1 xff1a 是变量名 而不是 变量 xff01 注意2 xff1a 列表 可以做文章 xff01 二 应用 第一类 xff1a 数字性循环 gt seq
  • 一次性将所有变成 long long

    include lt bits stdc 43 43 h gt using namespace std const int N 61 100000 43 100 define int long long define fir i a b f
  • Linux基础命令(二十一)Linux中的磁盘管理(终)

    一 逻辑卷管理器 Logical Volume Manager 需求引入 xff1a 最初规划主机的时候 xff0c 只给了 home 100G的 xff0c 但是随着业务量的增大 xff0c 导致用户的增多 xff0c 这个文件系统不够
  • 【机器学习】DBSCAN聚类算法(含Python实现)

    文章目录 一 算法介绍二 例子三 Python实现3 1 例13 2 算法参数详解3 3 鸢尾花数据集 一 算法介绍 DBSCAN xff08 Density Based Spatial Clustering of Applications
  • Zookeeper深度解析(概念、原理机制、应用场景)

    1 Zookeeper是什么 xff1f 分布 开源的应用程序协调服务 它是集群的管理者 监视着集群中各个节点的状态 xff0c 根据节点的反馈进行下一步合理操作 主要解决分布式应用经常遇到的数据管理问题 如 xff1a 统一命名服务 状态
  • 计算机操作系统知识梳理

    1 进程和线程以及它们的区别 xff08 1 xff09 进程是对 运行时程序的封装 是系统进行资源 调度和分配的 基本单位 实现操作系统 的 并发 xff08 2 xff09 线程是进程的 子任务 是CPU调度和分派的基本单位 用于保证程
  • 数据库知识梳理

    概述 xff1a 对数据库索引 数据库锁 数据库事务 MySql优化等基础知识梳理 1 数据库范式 xff08 1 xff09 第一范式 xff1a 列不可分 eg 联系人 xff08 姓名 xff0c 性别 xff0c 电话 xff09
  • JAVA重要知识点梳理(一)

    1 Struts2和SpringMVC的区别 xff08 1 xff09 设计理念 xff1a 前者为 有状态的 Action 均为多例 xff0c Action对象属性字段 承载请求 响应 xff0c 后者一般为无状态的 Controll
  • Shell脚本中:#!/bin/bash和#!/bin/sh是什么意思以及区别?

    意思 xff1a bin sh是指此脚本使用 bin sh来解释执行 xff0c 是特殊的表示符 xff0c 其后面跟的是解释此脚本的shell的路径 其实第一句的 是对脚本的解释器程序路径 xff0c 脚本的内容是由解释器解释的 xff0
  • Jar包与war包文件区别?

    Jar文件 xff1a xff08 Java Archive xff0c Java 归档文件 xff09 JAR 文件格式以流行的 ZIP 文件格式为基础 与 ZIP 文件不同的是 xff0c JAR 文件不仅用于压缩和发布 xff0c 而
  • SpringCloud开发框架入门知识

    1 分布式开发简介 分布式开发的思考点 xff1a 如何可以让代码更安全 xff1b 如何有效的通讯 xff1b 在进行分布式处理的时候如何进行程序功能划分 xff1b web集群 xff1a 考虑多用户并发访问的处理速度 业务中心 xff
  • slf4j Failed to load class “org.slf4j.impl.StaticLoggerBinder“ 错误 源码解析

    基本描述 slf4j 是日志的api 门面模式 xff0c 引入slf4j api就行 xff0c 但是打印不出日志的 xff0c 因为没有具体的实现类 logback实现包 span class token tag span class