记一次由jdk版本导致的错误

异常表现

项目本地开发环境启动正常, 部署到生产环境启动卡死.

解决步骤

  1. 首先当然是找到启动日志. 由于项目在windows Server 2012上运行, 注册为windows服务. 所以不会有控制台日志, 所有日志均需要在日志文件夹中找到. 最终发现无限循环输出日志:

Logging initialized using ‘class org.apache.ibatis.logging.stdout.StdOutImpl’ adapter.
Logging initialized using ‘class org.apache.ibatis.logging.stdout.StdOutImpl’ adapter.
Logging initialized using ‘class org.apache.ibatis.logging.stdout.StdOutImpl’ adapter.
Logging initialized using ‘class org.apache.ibatis.logging.stdout.StdOutImpl’ adapter.
… …

  1. 到网上查找解决办法, 都说是Mybatis的Mapper文件解析出错导致, 但是反复检查Mapper文件, 并与上一版本项目部署时的代码进行核对, 并没有发现错误.
  2. 找到了这篇文章:https://blog.csdn.net/isea533/article/details/51277786, 授人以鱼不如授人以渔, 这里面并没有直接告诉说是什么引起的异常. 而是通过断点调试的方式来找到异常.
  3. 但是由于本地启动正常, 无法进行本地调试, 百度发现Eclipse居然可以远程调试!https://blog.csdn.net/guolong1983811/article/details/78081470
  4. 经过远程调试, 最终找到异常, 是由于新增的一个jar包是通过jdk1.8打包的. 而整个项目的环境一直运行在jdk1.7环境下, 最终导致上面的一系列问题.

详细解决过程

查看Tomcat日志文件

如图为一次启动生成的日志:
tomcat在windows下的日志
https://www.cnblogs.com/qlqwjy/p/8036091.html解释了各个文件的含义:

  • catalina.日期.log – 这个主要是记录tomcat启动时候的信息,类似于我们在eclipse中启动服务的时候在控制台看到的信息。在里面可以看到启动的JVM参数以及操作系统等日志信息。如果没有使用log4j等日志机制,系统的的错误信息与打印语句也在这个日志文件中记录。(linux下所有的日志都在catalina.out中)
  • commons-daemon.日期.log – 这个日期放的估计是利用服务方式启动tomcat作为守护进程的日志记录,因为我的tomcat启动方式是以服务的方式启动的,索引产生这个日志文件记录了服务的启动状态。
  • host-manager.日期.log – 这个估计是放tomcat的自带的manager项目的日志信息的,也没有看到有什么重要的日志信息.
  • localhost.日期.log – 这个类似于第一种日志,可是信息没有第一种全
  • localhost_access_log.日期.txt – 这个是存放访问tomcat的请求的所有地址以及请求的路径、时间,请求协议以及返回码等信息(重要)
  • manager.日志.log – 这个估计也是manager项目专有的日志文件,看不出有什么重要的信息
  • tomcat7-stderr.日期.log – 这个是log4j的错误日志,因此在程序中要合理的捕捉异常。
  • tomcat7-stdout.日期.log(类似于eclipse的控制台的信息) – 这个是程序中的System语句打印的日志(包括系统抛出的异常),也终于明白了为什么一再强调不能用打印语句进行系统调试

最后在tomcat7-stdout.2018-10-11.log中找到了问题:
循环输出的日志

远程断点调试

  1. 配置服务器的tomcat开启远程断点调试监听:

SET CATALINA_OPTS=-server -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=8081,server=y,suspend=n

  1. Eclipse连接远程服务器:
    调试配置
  2. 根据网上查找到的断点位置, 在图上位置加上断点:
    在这里插入图片描述

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory的protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs)方法
org.springframework.beans.factory.support.AbstractBeanFactory的protected Class<?> getTypeForFactoryBean(String beanName, RootBeanDefinition mbd) 方法

  1. 使用startup.bat启动远程服务.
  2. 启动Eclipse远程调试.
  3. 结果上面第一个断点处一直进入, 第二个断点没有反应. 我把第一个断点关掉. 过了一会, 进入第二个断点.
    在这里插入图片描述
    终于得到错误日志了: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘sqlSessionFactory’ defined in class path resource [mapper/applicationContext-db.xml]: Invocation of init method failed; nested exception is java.lang.UnsupportedClassVersionError: com/frog/report/model/DataSource : Unsupported major.minor version 52.0 (unable to load class com.frog.report.model.DataSource)
    同时发现每打印一句之前循环输出的日志, 就进入断点一次.
    根据上面的错误日志, 可以知道version52.0对应的是jdk1.8, 而我们的项目使用的是jdk1.7, 所以出错.

问题总结

引起这个问题有两方面原因:

  1. 开发环境管理混乱, 没有使用统一的jdk版本进行控制.
  2. 项目的日志管理存在问题. 下图中实际上是应该输出错误日志的, 这样就会更好的解决问题.
    在这里插入图片描述
    最后发现log4j与logback冲突导致日志输出出现问题, 错误日志没有输出出来:
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值