spring boot 2 内嵌Tomcat Stopping service [Tomcat]

我在使用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

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

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

原文地址:https://www.cnblogs.com/jtlgb/p/10288419.html

时间: 2024-10-27 06:50:54

spring boot 2 内嵌Tomcat Stopping service [Tomcat]的相关文章

Spring boot如何打war包发布到tomcat

前言: 平时在使用java做项目开发时,首先想到利用框架来提升开发效率,和提高可维护性.选择spring可以使用ssm(spring框架,springMVC,mybatis),而且企业中应用也比较广泛,然而还是发现,在框架中有很多配置,而且看起来相当繁琐,并且在这些配置中,大部分都属于默认配置,习惯配置.因此spring boot就此诞生,它的主要目的就是实现"0"配置,此处的"0"不是代表没有配置,而是代表极少的配置.并且spring boot还内置了tomcat

spring boot实战(第十五篇)嵌入tomcat源码分析

嵌入tomcat源码分析 在启动spring boot工程时利用@SpringBootApplication注解,该注解启动@EnableAutoConfiguration自动配置,加载META-INF/spring.factories文件 # Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.springframework.boot.autoconfigure.admin.Spri

关于Spring Boot中的业务层(Service)是否要创建接口的分析

很多人在借助Spring Boot框架开发web项目时,在业务层(Service)这一部分,标准做法是:定义一个接口,然后再一个或多个类去实现.疑问来了: ????????为什么我们要维护两份同构代码,而不直接使用一个类呢? ????????不创建接口,通过把业务实现类直接通过注解@Autowired注入控制层Controller,也一点不耽误功能的实现啊,那么我为什么还要创建接口? ????网上大部分回答都是说什么面向对象的解耦云云,引经据典,说得都很好,然而,都没有从根本上回答我们关心的问题

spring boot项目打包成war并在tomcat上运行的步骤

把spring-boot项目按照平常的web项目一样发布到tomcat容器下 一.修改打包形式 在pom.xml里设置 <packaging>war</packaging> 二.移除嵌入式tomcat插件 在pom.xml里找到spring-boot-starter-web依赖节点,在其中添加如下代码, 第一种<dependency> <groupId>org.springframework.boot</groupId> <artifact

解决spring boot中普通类中使用service为null 的方法

我使用的是springboot+mybatisplus +mysql1.创建一个SpringUtil工具类 import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; public final class SpringUtil im

spring boot学习1

转:https://blog.csdn.net/jsyxcjw/article/details/46763639 1 开始 1.1 spring介绍 Spring Boot使开发独立的,产品级别的基于Spring的应用变得非常简单,你只需"just run". 我们为Spring平台及第三方库提供开箱即用的设置,这样你就可以有条不紊地开始.多数Spring Boot应用需要很少的Spring配置. 你可以使用Spring Boot创建Java应用,并使用java -jar启动它或采用传

(转)Spring Boot(一)

(二期)4.springboot的综合讲解 [课程四]springbo...概念.xmind64.5KB [课程四]spring装配方式.xmind0.2MB [课程四预习]spri...解读.xmind0.1MB [课程四]springbo...过程.xmind0.3MB git demo : https://gitee.com/lv-success/git-second/tree/master/course-4-springboot/spring-boot-deep 讲课顺序: 第一节课程

《01.Spring Boot连载:Spring Boot入门介绍》

1 Spring Boot的概述 Spring Boot是开发者和Spring 本身框架的中间层,帮助开发者统筹管理应用的配置,提供基于实际开发中常见配置的默认处理(即习惯优于配置),简化应用的开发,简化应用的运维:总的来说,其目的Spring Boot就是为了对Java web 的开发进行"简化"和加"快"速度,简化开发过程中引入或启动相关Spring 功能的配置.这样带来的好处就是降低开发人员对于框架的关注点,可以把更多的精力放在自己的业务代码上. 同时随着微服

Spring Boot(3):加载DataSource过程的源码分析及yml中DataSource的配置

Spring Boot实现了自动加载DataSource及相关配置.当然,使用时加上@EnableAutoConfiguration注解是必须的.下面就是对这一部分的源码分析. (1)Spring Boot启动后会调用org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration.下面是部分源码. 1 @Configuration 2 @ConditionalOnClass({ DataSource.class, E