由jar包冲突导致的logback日志不输出

最近接手一个厂商移交的项目,发现后管子系统不打印日志。

项目使用的logback

本地断点调试发现logback-classic jar冲突导致 打出的war中没有 相关的jar

解决方法:

去除pom 文件中多余的 logback-classic 应用,只保留最新版本的。 重新打包环境后,日志可正常输出。

java是如何加载logback
我们都知道,当我们需要引入logback时,是不是需添加任何配置 来引入logback.xml文件的,只需要将logback.xml配置文件定义到resources目录即可,那么框架会自动加载这个日志配置文件,并按照配置帮我自己生成日志到指定的目录下,那么它是如何自动加载的。
很显然第一个想到就是通过spi。
在说明如何加载的一个前提是,你需要知道sl4j、log4j、logback之间的关系。
可以看这篇 SLF4J和Logback和Log4j和Logging的区别与联系

这里我还是贴一张图来说明一下:

slf4j是一个门面,而logback、log4j都是这个门面的实现。
所以logback肯定是在sl4j.jar中加载的。

3.1、回顾下我们获取日志对象是如何获取的
上面方法会加 //加载org/slf4j/impl/StaticLoggerBinder.class这个类这个类,那么我们先看下slf4j下有没有这个类:

//通过LoggerFactory获取一个logger对象
final static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);

//通过LoggerFactory获取一个logger对象,那么我们看下这个方法如下:

它果然是在slf4j这个门面中定义的。

public static Logger getLogger(Class<?> clazz) {
   //看下是如何获取logger 的
   Logger logger = getLogger(clazz.getName());
   if (DETECT_LOGGER_NAME_MISMATCH) {
       Class<?> autoComputedCallingClass = Util.getCallingClass();
       if (autoComputedCallingClass != null && nonMatchingClasses(clazz, autoComputedCallingClass)) {
           Util.report(String.format("Detected logger name mismatch. Given name: \"%s\"; computed name: \"%s\".", logger.getName(),
                           autoComputedCallingClass.getName()));
           Util.report("See " + LOGGER_NAME_MISMATCH_URL + " for an explanation");
       }
   }
   return logger;
}
 

getLogger

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();
             }
         }
     }
     ......
}     
 

查看performInitialization 的bind方法

  private final static void performInitialization() {
     //绑定
     bind();
     if (INITIALIZATION_STATE == SUCCESSFUL_INITIALIZATION) {
         versionSanityCheck();
     }
 }

private final static void bind() {
    ....
    staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
    .....
}
 
 private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";

static Set<URL> findPossibleStaticLoggerBinderPathSet() {
     // use Set instead of list in order to deal with bug #138
     // LinkedHashSet appropriate here because it preserves insertion order
     // during iteration
     Set<URL> staticLoggerBinderPathSet = new LinkedHashSet<URL>();
     try {
         ClassLoader loggerFactoryClassLoader = LoggerFactory.class.getClassLoader();
         Enumeration<URL> paths;
         if (loggerFactoryClassLoader == null) {
         //加载org/slf4j/impl/StaticLoggerBinder.class这个类
             paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);
         } else {
             paths = loggerFactoryClassLoader.getResources(STATIC_LOGGER_BINDER_PATH);
         }
         while (paths.hasMoreElements()) {
             URL path = paths.nextElement();
             staticLoggerBinderPathSet.add(path);
         }
     } catch (IOException ioe) {
         Util.report("Error getting resources from path", ioe);
     }
     return staticLoggerBinderPathSet;
 }

这个jar下没有这个路径,那么肯定是在slf4j-logback.jar,slf4j-log4j.jar这样的jar包下实现的。
搜索logback相关jar,发现在这个jar下有这个路径类

然后继续,看bind方法后面

如果你的项目中只有logback-classic这一个Jar,没有其它日志框架,那么直接点到这个方法中就到logback方法中,如下:

这个类中静态方法就会执行

看下init方法

autoConfig()中findURLOfDefaultConfigurationFile方法

再继续看autoConfig()方法

后面就不在细说明,可以直接到源码里面看看。
这里整个logback自动注入的过程就完结了
 

具体排查过程待补充

最终原因 jar包冲突 

表现 war包中没有 logback-classic.jar 这个文件,  解决冲突后 ,logback-classic.jar 出现了 问题解决。

相关推荐

  1. jar冲突导致logback输出

    2024-01-14 02:24:02       59 阅读
  2. Android|记一个导致 logback 无法输出问题

    2024-01-14 02:24:02       34 阅读
  3. logback排除指定类方法

    2024-01-14 02:24:02       54 阅读
  4. 【日志】log4net 输出

    2024-01-14 02:24:02       34 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-14 02:24:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-14 02:24:02       101 阅读
  3. 在Django里面运行非项目文件

    2024-01-14 02:24:02       82 阅读
  4. Python语言-面向对象

    2024-01-14 02:24:02       91 阅读

热门阅读

  1. SQL概述及SQL分类

    2024-01-14 02:24:02       60 阅读
  2. 原创 | 一文读懂ChatGPT中的强化学习

    2024-01-14 02:24:02       78 阅读
  3. SpringBoot整合MyBatis-Plus

    2024-01-14 02:24:02       59 阅读
  4. xtu-c语言考试复习-2

    2024-01-14 02:24:02       65 阅读
  5. 蓝桥杯基础知识4 swap()、reverse()

    2024-01-14 02:24:02       65 阅读
  6. 20. 完整的蒙特卡洛强化学习算法

    2024-01-14 02:24:02       59 阅读
  7. 关于git-lfs删除历史版本

    2024-01-14 02:24:02       51 阅读
  8. 超级计算集群

    2024-01-14 02:24:02       60 阅读
  9. metartc5_jz源码阅读-yang_rtcpush_on_rtcp_ps_feedback

    2024-01-14 02:24:02       63 阅读
  10. VCG 网格面片法向量平滑

    2024-01-14 02:24:02       64 阅读
  11. Git 的基本概念和使用方式

    2024-01-14 02:24:02       50 阅读
  12. Ubuntu下git提示:终止提交因为提交说明为空。

    2024-01-14 02:24:02       68 阅读
  13. 【洛谷】P2709 小B的询问——莫队问题

    2024-01-14 02:24:02       68 阅读