JVM加载类冲突,导致Mybatis查数据库返回NULL的一个小问题
今天碰到个bug,虽然小,但是有点意思
背景是SpringMVC + Mybatis的一个项目,mapper文件里写了一条sql 大概相当于 select a from tableA where b = "123" 这样的级别
然后不管传进去的是什么 数据库里有没有 都会返回null
第一反应是sql语句写错了,比如把1和小写L弄混了之类的,传给sql的参数里有奇怪的空格等等
于是打开debug log 拿到传给sql的preparedStatement 和对应的参数
复制到console里自己查了一下,可以执行,返回结果也正确,说明不是sql的问题
既然不是sql的问题,那只好调试一下代码了
既然preparedStatement sql能够被打印出来,所以就不从业务逻辑加断点了,直接定位到PreparedStatement类 找到execute方法,上个断点开始单步
单步的时候发现ide提示说源代码和class文件对应行不一致,并且对我正在监视的变量报了一个类中不存在该变量的错
所以怀疑是引用冲突了
接下来确认一下是不是引用了奇怪的类 ,用下面这个方法去定位一下PreparedStatement的位置
public static String where(final Class cls) {
if (cls == null)throw new IllegalArgumentException("null input: cls");
URL result = null;
final String clsAsResource = cls.getName().replace('.', '/').concat(".class");
final ProtectionDomain pd = cls.getProtectionDomain();
if (pd != null) {
final CodeSource cs = pd.getCodeSource();
if (cs != null) result = cs.getLocation();
if (result != null) {
if ("file".equals(result.getProtocol())) {
try {
if (result.toExternalForm().endsWith(".jar") ||
result.toExternalForm().endsWith(".zip"))
result = new URL("jar:".concat(result.toExternalForm())
.concat("!/").concat(clsAsResource));
else if (new File(result.getFile()).isDirectory())
result = new URL(result, clsAsResource);
}
catch (MalformedURLException ignore) {}
}
}
}
if (result == null) {
final ClassLoader clsLoader = cls.getClassLoader();
result = clsLoader != null ?
clsLoader.getResource(clsAsResource) :
ClassLoader.getSystemResource(clsAsResource);
}
return result.toString();
}
用where方法去查一下类,发现jvm没有加载我认为的msql-java-connector-5.1.63 而是加载了一个内部类库里的java-connector,定位进去看了一下 确实是写的有问题,原因找到了。
最后到maven依赖里,打开依赖树,找到了加载这个自定义connector的pom条目,配置了<exclusions> ,然后重启项目,解决。
JVM加载类冲突,导致Mybatis查数据库返回NULL的一个小问题的更多相关文章
- JVM加载类的过程,双亲委派机制中的方法
JVM加载类的过程: 1)JVM中类的整个生命周期: 加载=>验证=>准备=>解析=>初始化=>使用=>卸载 1.1.加载 类的加载阶段,主要是获取定义此类的二进 ...
- jvm加载类(更新中)
作为jvm的用户,从使用者角度来看,我们给jvm输入一个class文件,得到了一个Class对象.我们可以猜想下jvm加载类的过程:class文件有规定的格式,jvm去解析class文件流,读magi ...
- [转]jvm加载类规则
jvm包括三种类加载器: 第一种:bootstrap classloader:加载Java的核心类. 第二种:extension classloader:负责加载jre的扩展目录中的jar包. 第三种 ...
- JVM学习(二)JVM加载类
一.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构 ...
- Picasso加载网络图片失败,提示decodestream时返回null
最近遇到一个问题,项目用的图片加载框架是Picasso,网络加载框架是okhttp,项目在加载轮播图时有时可以正常加载,有时,会加载失败,提示decodestream时返回null. 首先,需要确定是 ...
- JVM加载类的原理机制
在Java中,类装载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载.链接和初始化,其中链接又可以分成校验.准备.解析装载:查找和导入类或接口的二进制数据: 链接:执行下面的校验.准备和解析 ...
- jvm加载类的7个步骤
- 虚拟机(JVM)如何加载类
首先JVM加载类的一般流程分三步: 加载 链接 初始化 那么是否全部Java类都是这样三步走的方式加载呢?我们可以从Java的数据类型去出发.Java分基本类型和引用类型.其中按照面向对象的特性,一切 ...
- JVM加载class文件的原理
当Java编译器编译好.class文件之后,我们需要使用JVM来运行这个class文件.那么最开始的工作就是要把字节码从磁盘输入到内存中,这个过程我们叫做[加载 ].加载完成之后,我们就可以进行一系列 ...
随机推荐
- recovery 界面汉化过程详解
一. 主要是针对recovery汉化,主要汉化对象是界面显示为中文. 二. 基于中文的汉化,有两种方式,一种是基于GB2312的编码格式汉化,另外一种是基于unicode编码格式汉化.下面介绍unic ...
- g4e基础篇#5 创建分支和保存代码
章节目录 前言 1. 基础篇: 为什么要使用版本控制系统 Git 分布式版本控制系统的优势 Git 安装和设置 了解Git存储库(Repo) 起步 1 – 创建分支和保存代码 起步 2 – 了解Git ...
- Kotlin的参考资料
参考资料和站点 http://kotlinlang.org/ 官方网站 https://github.com/JetBrains/kotlin/releases/tag/v1.0.6 下载compil ...
- Wampserver或者帝国CMS安装后, 打开localhost显示IIS欢迎界面图片
我们在安装集成环境Wampserver或者帝国CMS之后,有时会遇到一个问题, 打开localhost显示一张IIS欢迎界面图片,这个问题该如何解决呢,我在这里简单整理了一下解决方法 电脑win10系 ...
- mssql sqlserver null数据类型专题
摘要: 下文将详细讲述sql server NULL(空值)的相关知识,如下所示: 实验环境: sql server 2008 R2 NULL(空值)简介: mssql sqlserver null数 ...
- mssql sqlserver避免sql脚本中出现除零错误的方法分享
摘自:http://www.maomao365.com/?p=6612 摘要:下文介绍sql server中,sql脚本避免出现除零错误的方法分享 在各种业务系统开发中,通常会遇到除零的错误,下文分享 ...
- 数据挖掘---Matplotib的学习
什么是matplotlib mat - matrix 矩阵 二维数据 - 二维图表 plot - 画图 lib - libra ...
- 排序算法之快速排序的思想以及Java实现
1 基本思想 快速排序是在冒泡排序的基础上改进而来的,它是基于分治的思想.通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据 ...
- 【算法】LeetCode算法题-Reverse Integer
这是悦乐书的第143次更新,第145篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第2题(顺位题号是7),给定32位有符号整数,然后将其反转输出.例如: 输入: 123 ...
- [福大软工] Z班 第2次成绩排行榜
作业链接 http://www.cnblogs.com/easteast/p/7469291.html 评分细则 本次个人项目分数由三部分组成,分别是 (1)博客 - 20分,分数组成如下: 在文章开 ...