我在使用springboot时,当代码有问题时,发现控制台打印下面信息:

Connected to the target VM, address: '127.0.0.1:42091', transport: 'socket'
log4j:WARN No appenders could be found for logger (org.springframework.boot.devtools.settings.DevToolsSettings).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.6.RELEASE)
2018-10-25 10:10:21.425  INFO 102158 --- [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2018-10-25 10:10:21.427  INFO 102158 --- [  restartedMain] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.34
2018-10-25 10:10:21.444  INFO 102158 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener   : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib]
2018-10-25 10:10:21.590  INFO 102158 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2018-10-25 10:10:24.522  INFO 102158 --- [  restartedMain] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
Disconnected from the target VM, address: '127.0.0.1:42091', transport: 'socket'
Process finished with exit code 0

WTF?没有错误信息怎么解决问题? 各种搜索,总之就是代码有问题,自己检查把...

好吧,直接debug把

内嵌tomcat的入口类是org.apache.catalina.core.StandardService

//TODO 后面补上过程

最终找到org.springframework.context.support.AbstractApplicationContext 定位方法refresh()

if (logger.isWarnEnabled()) {
				logger.warn("Exception encountered during context initialization - " +
						"cancelling refresh attempt: " + ex);

debug可以正常进入,然后就看到我们希望看到的 ex了

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fabricApiController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fabricTemplate': Injection of resource dependencies failed; nested exception is org.springframework.boot.context.properties.ConfigurationPropertiesBindException: Error creating bean with name 'fabricConfiguration': Could not bind properties to 'FabricConfiguration' : prefix=blockchain, ignoreInvalidFields=false, ignoreUnknownFields=true; nested exception is org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'blockchain.channel-peers' to java.util.List<com.smy.bc.fabric.core.configuration.FabricConfiguration$EndPoint>

问题发现了,解决自己代码问题,然后重新启动,正常! 万事大吉?错,这才开始

上面我们简单解决了问题,但是根源没有解决!
要说解决方案把当前流行的日志体系简单说一遍
下面整理的来源网络:
常见的日志框架,注意不是具体解决方案
1 Commons-logging: apache 最早提供的日志的门面接口。避免和具体的日志方案直接耦合。类似于JDBC的api接口,具体的的JDBC driver实现由各数据库提供商实现。通过统一接口解耦,不过其内部也实现了一些简单日志方案
2 Slf4j: 全称为Simple Logging Facade for JAVA:java简单日志门面。是对不同日志框架提供的一个门面封装。可以在部署的时候不修改任何配置即可接入一种日志实现方案。和commons-loging应该有一样的初衷。
常见的日志实现:
log4j
logback
jdk-logging
详细优缺点不是本文重点,请自行搜索。

接着分析上面的问题,Commons-logging 是tomcat默认的日志系统(apache自家东西得支持),具体的日志实现,根据系统已存在日志系统选择。 简单列举以下log的实现: org.apache.commons.logging.Log org.apache.commons.logging.impl.SimpleLog org.apache.commons.logging.impl.NoOpLog org.apache.commons.logging.impl.Log4JLogger org.apache.commons.logging.impl.SLF4JLog org.apache.commons.logging.impl.Jdk14Logger

springboot 默认使用的是logback日志实现,问题就出现在这里了!!!common-logs并没有logback的实现!

根据maven依赖,我们看到log4j和logback的包都被引入了,然后tomcat之能选择的是log4j,springboot使用的是logback。 log4j和logback只见缺少一个桥梁,正是缺少的这个桥梁,导致springboot只能输出logback!!!

中间的桥梁就是下面这个依赖

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
    </dependency>

这个依赖可以将log4j输出到slf4j,从而从sl4j输出。

总结一下,已经搞明白是slf4j/common-logs <> log4j和logback的恩怨情仇

第一种解决方式:根据日志定位问题,然后采用加法处理,增加jcl-over-slf4j,打通slf4j和common-logs通道

第二种解决方式:解决冲突,一山不容二虎,排除掉slf4j,common-logs任意一方,spring使用slf4j,那可以排除调common-logs

从项目优化的角度看,第二种更优,可以减少不必要的依赖。

如果日志出现问题,那就是日志体系发生冲突了,可以参考这个思路,处理项目中日志异常问题。

[干货]再见,Android JNI 封装

1 前言 2 JNI 速查表 2.1 Java 和 Native 数据类型映射表 2.2 引用类型 3 JNI 理论基础速览 4 JNI 常用场景示例 4.1 字符串传递(java->native) 4.2 字符串返回(native->java) 4.3 数组传递(java->native) 4.4 其他......

CVE-2020-15012:Nexus Repository Manager 2 目录遍历漏洞通告

报告编号:B6-2020-100901 报告来源:360CERT 报告作者:360CERT 更新日期:2020-10-09 0x01 漏洞简述 2020年10月09日,360CERT监测发现 nexus repository manager 2 发布了 nexus repository manager 2 目录穿越......

一个爬虫的故事:这是人干的事儿?

爬虫原理 我是一个爬虫,每天穿行于互联网之上,爬取我需要的一切。 说起来还要感谢HTTP协议,因为它,全世界的网站和浏览器才能够连接通信,而我也是借助HTTP协议,获取我想要的数据。 我只需要伪装成一个浏览器...

我写的代码,又被CTO骂了......

点击上方蓝色字关注我们~ “ 大多数时候我都是写一些业务代码,可能一堆 CRUD 就能解决问题,但是这样的工作对技术人的提升并不多,如何让自己从业务中解脱出来找到写代码的乐趣呢,我做过一些尝试,使用设计模式...

排序|优先队列不知道,先看看堆排序吧

前言 在个人的专栏中,其他排序陆陆续续都已经写了,而堆排序迟迟没有写,趁着国庆假期的尾声,把堆排序也写一写。 插入类排序—(折半)插入排序、希尔排序 交换类排序—冒泡排序、快速排序手撕图解 归并类排序—归...

不同角度看问题 - 从 Codable 到 Swift 元编程

作者:王巍(onevcat),江湖人称 "喵神",他是 ObjC 中国组织的发起人和领导者,也是著名开源框架 Kingfisher 的作者。 起源 前几天看到同事的一个 P-R,里面有将一个类型转换为字典的方法。在我们所使用的 API 中...

柯西-比内公式了解一下

本篇比较基础,公式也较多。如果兴趣不大或者已经掌握,可以直接拉到最后看小结。 1行列式乘积法则 自从行列式从方程组中独立出来以后,在矩阵代数出来之前,数学家们对行列式的关注比较多,因此很多性质被揭示出...

卧槽,不用翻墙就能访问Google、Youtube了,真香

刚看到一则消息,赶紧跟大家分享一下 ‭‮地内‬‬用户可以‭‮过通‬‬Tuber浏览器访问‭‮外境‬‬网站,包括:Google、Youtube、Twitter、Facebook、Instagram、Netflix等等。 目前‭‮PPA‬‬已经通过相关‭‮...

如何在 Rust 中使用 MQTT

Rust 是由 Mozilla 主导开发的通用、编译型编程语言。该语言的设计准则为:安全、并发、实用,支持 函数式、并发式、过程式以及面向对象的编程风格。Rust 速度惊人且内存利用率极高。由于没有运行时和垃圾回收,它...

技术分享 | MySQL 内存管理初探

作者:xuty 本文来源:原创投稿 *爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。 一、背景 经常在项目上碰到在没有大并发活跃 SQL 的情况下,MySQL 所占用的物理内存远大于 Inno...