问题: 新建工程 busr, 采用 pandora boot, 引入了需要的包, 简单写了点代码发布,
spring-boot 启动报错:
Caused by: java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath.
- Either remove Logback or the competing implementation (class org.apache.logging.slf4j.Log4jLoggerFactory loaded from
- jar:file:/opt/**.jar!/BOOT-INF/lib/log4j-slf4j-impl-2.6.2.jar!/). If you are using webLogic you will need to add 'org.slf4j'
- to prefer-application-packages in WEB-INF/weblogic.xml Object of class [org.apache.logging.slf4j.Log4jLoggerFactory]
- must be an instance of class ch.qos.logback.classic.LoggerContext
- at org.springframework.util.Assert.isInstanceOf(Assert.java:346)
- at org.springframework.boot.logging.logback.LogbackLoggingSystem.getLoggerContext(LogbackLoggingSystem.java:231)
- at org.springframework.boot.logging.logback.LogbackLoggingSystem.beforeInitialize(LogbackLoggingSystem.java:97)
- at org.springframework.boot.logging.LoggingApplicationListener.onApplicationStartedEvent(LoggingApplicationListener.java:226)
- at org.springframework.boot.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:205)
- at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:166)
- at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:138)
- at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:121)
- at org.springframework.boot.context.event.EventPublishingRunListener.started(EventPublishingRunListener.java:63)
- at org.springframework.boot.SpringApplicationRunListeners.started(SpringApplicationRunListeners.java:48)
- at org.springframework.boot.SpringApplication.run(SpringApplication.java:304)
- at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186)
- at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175)
看到错误 "LoggerFactory is not a Logback LoggerContext but Logback is on the classpath.
Either remove Logback"
大概意思是 可以 remove 掉 logback 解决问题. 当时直接 Google 了下 Stack Overflow 上有篇文章也说
排掉 logback 的包即可.
于是 我这么做了
http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/5231e3284419eb9b203064fc694ae66d.png
发布启动 一切貌似正常. 正当高兴之余, 突然发现不打印日志了. 很明显与我刚才的操作有关系, 看来刚才解决问题的办法似乎不正确. 静下来分析问题的根本原因:
看看 spring boot 是怎么加载日志的:
源码中 onApplicationStartedEvent 方法, 在系统启动时会被调用, LoggingSystem 获取当然的日志系统
- private void onApplicationStartedEvent(ApplicationStartedEvent event) {
- this.loggingSystem = LoggingSystem
- .get(event.getSpringApplication().getClassLoader());
- this.loggingSystem.beforeInitialize();
- }
默认的会引入下面 3 个日志系统 如果没有任何配置的化 其默认的是 LogbackLoggingSystem
- static {
- Map systems = new LinkedHashMap();
- systems.put("ch.qos.logback.core.Appender",
- "org.springframework.boot.logging.logback.LogbackLoggingSystem");
- systems.put("org.apache.logging.log4j.core.impl.Log4jContextFactory",
- "org.springframework.boot.logging.log4j2.Log4J2LoggingSystem");
- systems.put("java.util.logging.LogManager",
- "org.springframework.boot.logging.java.JavaLoggingSystem");
- SYSTEMS = Collections.unmodifiableMap(systems);
- }
逐步跟踪到第一次系统报错的地方
- private LoggerContext getLoggerContext() {
- ILoggerFactory factory = StaticLoggerBinder.getSingleton().getLoggerFactory();
- Assert.isInstanceOf(LoggerContext.class, factory,
- String.format(
- "LoggerFactory is not a Logback LoggerContext but Logback is on"
- "the classpath. Either remove Logback or the competing"
- "implementation (%s loaded from %s). If you are using"
- "WebLogic you will need to add'org.slf4j'to"
- "prefer-application-packages in WEB-INF/weblogic.xml",
- factory.getClass(), getLocation(factory)));
- return (LoggerContext) factory;
- }
说明返回的 factory 不是 logback 的实例, StaticLoggerBinder.getSingleton().getLoggerFactory() 没有找到 logback,
所以这个时候开始怀疑 StaticLoggerBinder 是否是因为包冲突, 果然 如下图
http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/a9fbe3063e81267c31ec925c4b5e8c35.png
默认用了 slf4j-log4j12 里面的 StaticLoggerBinder 类, 而没有用 logback 的 所以才会报上面的启动错误.
找到问题原因了 下面就是排包
http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/1c7a0bf723ae52db221267fd93e1d7d1.png
来至
com.alibaba.trip.tripspider:tripspider-httpclient:jar:1.0.0-SNAPSHOT:compile
排掉即可
- org.slf4j
- slf4j-log4j12
启动一切正常, 久违的日志又有了.
思考: 遇到问题 google 一下找解决办法或许是最快的, 但是有时候往往解决方案因人而异, 可能并不完全正确, 明白问题出现的根本原因找解决办法才是最靠谱的.
来源: https://yq.aliyun.com/articles/622721