网站流量怎么算的,网站建设和技术支持,网站开发招投标书,汕头网站建设哪家好最近接手一个厂商移交的项目#xff0c;发现后管子系统不打印日志。
项目使用的logback
本地断点调试发现logback-classic jar冲突导致 打出的war中没有 相关的jar
解决方法#xff1a;
去除pom 文件中多余的 logback-classic 应用#xff0c;只保留最新版本的。 重新打…最近接手一个厂商移交的项目发现后管子系统不打印日志。
项目使用的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;
}getLoggerpublic 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 SetURL findPossibleStaticLoggerBinderPathSet() {// use Set instead of list in order to deal with bug #138// LinkedHashSet appropriate here because it preserves insertion order// during iterationSetURL staticLoggerBinderPathSet new LinkedHashSetURL();try {ClassLoader loggerFactoryClassLoader LoggerFactory.class.getClassLoader();EnumerationURL 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.jarslf4j-log4j.jar这样的jar包下实现的。 搜索logback相关jar发现在这个jar下有这个路径类
然后继续看bind方法后面
如果你的项目中只有logback-classic这一个Jar没有其它日志框架那么直接点到这个方法中就到logback方法中如下
这个类中静态方法就会执行
看下init方法
autoConfig()中findURLOfDefaultConfigurationFile方法
再继续看autoConfig方法
后面就不在细说明可以直接到源码里面看看。 这里整个logback自动注入的过程就完结了 具体排查过程待补充
最终原因 jar包冲突
表现 war包中没有 logback-classic.jar 这个文件 解决冲突后 logback-classic.jar 出现了 问题解决。