dubbo debug过程中一个有趣的问题
最近在debug dubbo代码过程中遇到的很有趣的问题
我们都知道dubbo ReferenceBean是消费者的spring bean包装,为了查一个consumer端的问题,在ReferenceBean的父类ReferenceConfig的 T get()方法(140行)打上了一个断点。
当我debug 跟进init方法之后发现,ReferenceConfig的成员变量initialized(boolean类型),没有初始化,值变成了true? 纳尼。。。
在学习java的基础知识的时候,我们就知道如果boolean类型如果不初始化变量,运行的时候默认初始为true。为什么变量initialized没有赋值的情况,值是true呢?
更奇怪的是,debug模式下,因为initialized=true consumer的桩代码(proxy)没有生成,所以在业务层调用的时候跑出了NPE;但是在run模式下是对的。
初步怀疑
初步怀疑是debug模式和run模式下初始化的值是不同的,然后上google去搜索一下是不是存在这个问题,可惜没有任何的收获;同时在初始化的时候,直接把initialized初始化为false,防止缺省值初始成true。
但是问题依旧,放弃了这条思路!!!
然后开始怀疑是IDEA编辑器是不是在断点处有setvalue的情况,就把IDEA全部缓存清空并重启了(File->Invalidate....),debug后问题依然!!!
修改dubbo的源代码加日志输出
实在没什么思路了,想着先去增加一些日志输出,办法虽然很土,但是可能会有线索。在initialized=true 这行代码之后加一行输出
System.out.println("init initialized="+initialized);
同时断点还在ReferenceConfig.get()方法里面
当运行到断点出,观察console的输出,果然有输出!!!!
这说明当我断点在ReferenceConfig.get()方法里时候,有线程执行了init()方法导致initialized的值被修改成了true(dubbo代码只有一处修改ReferenceConfig.initialized值的地方,就在init里面)
所以只要找出哪个线程在我断点的时候,执行了init方法就行了
日志输出又立大功
继续在init方法里面加日志输出,以下日志能显示出哪个堆栈调用了init方法
继续debug运行,得到结果出乎意外
从日志输出可以看出来,在ReferenceConfig构造函数的地方,调用了父类AbstractConfig.toString方法,而在AbstractConfig的toString方法里面反射间接调用了ReferenceConfig.init()方法
这下算是找到谁在我断点的时候调用了ReferenceConfig.init()方法,就是toString()方法。
但是谁调用了toString()方法呢?
真想大白
首先可以排除程序在构造函数里面调用AbstractConfig.toString方法,还有一种可能就是IDEA 为了显示触发了这个类实例的toString方法。有了这个假设思路,写了一个demo验证一下
果不其然console里面输出了invoke toString()
总结
IDEA 这类编辑器带debug功能为了断点处能显示一个类的实例,就会反射调用实例的toString!!!!
真是一个有趣的发现!!!!
附送dubbo ReferenceConfig源码链接
dubbo debug过程中一个有趣的问题的更多相关文章
- Debug过程中的mock (及display窗口的使用)
转载:http://m.blog.csdn.net/blog/u012516903/18004965 在debug的时候,有3个地方可以进行mock测试 测试代码如下: 1.使用display窗口 W ...
- 如何在Eclipse和Tomcat的Debug过程中启用热部署
参考的地址是 http://blog.redfin.com/devblog/2009/09/how_to_set_up_hot_code_replacement_with_tomcat_and_ecl ...
- xargs命令的使用过程中一个小领悟:管道与xargs的差别
对xargs的使用总是比较模糊,大概的理解为:通道中,上一个命令的标准输出逐行作为下一个命令的参数 例如 find /var/temp* | xargs rm -r 功效:找出/var/中所有temp ...
- vue生命周期updated的触发时机之debug过程中发现的firefox问题
现象描述: 断点位置1 谷歌debug的过程: 火狐debug的过程: 只要在改变数据之后有断点停顿,就会先去执行updated函数 断点位置2 此时火狐和谷歌是一样的效果,但是执行顺序是不一致的 谷 ...
- 【UEFI】---记录一次debug过程中的调试经验
最近在调试一次SMBIOS的动态更新以及I2c设备的配置读取时,遇到了很多问题,特此总结: 1. 第一个是调试一个I2c设备的时候,遇到了一个很奇怪的问题,也由此问题总结了下SMBUS模块的知识,如下 ...
- IDEA Debug过程中使用Drop Frame或Reset Frame实现操作回退
大家在Debug程序的时候,是否遇到过因为"下一步"按太快,而导致跳过了想要深入分析的那段代码?是不是很想要有"回到上一步"这样的操作呢? 在IDEA中就提供了 ...
- 解析 Java 反射题中一个有趣的坑
public class Test { public void age(int age) { System.out.println("int age="+age); } publi ...
- c++ 内存分配中一个有趣的小问题
以下代码测试环境:vs2019 执行这么一段代码,看看会发生什么. int main() { ] = { }; arr[] = ; } 毫无疑问,会报错,因为访问越界了. 再看看另一段代码 ] = { ...
- connect & send 在三次握手过程中的有趣问题
一.问题回顾 面试的时候被问到的问题,原问题是: 1:写一下socket网络编程服务端和客户端常用的函数. 2:如果服务端在listen之后没有accept,那客户端的connect会返回吗?为什么? ...
随机推荐
- Nancy启用跨站攻击防护(CSRF)
什么是CSRF(跨站攻击) 可能很多人已经对CSRF有所了解,就简单的介绍下: CSRF全程是 Cross-Site Request Forgery .大概意思就是在登录用户不知情的情况下,由一个网站 ...
- css学习の第一弹—格式创建
构成结构:选择符(又称为选择qi器){声明(属性:值):}*****注意:大括号,冒号,每个声明后的分号. 注释:/*注释内容写在这里*/ 一.css样式 css样式写的地方的不同分类:内联式.嵌入式 ...
- windows下编译caffe报错:error MSB4062: 未能从程序集 E:\NugetPackages\OpenCV.2.4.10\......的解决办法
参考博客:http://blog.csdn.net/u013277656/article/details/75040459 在windows上编译caffe时,用vs打开后会自动加载还原NugetPa ...
- lvm创建卷组和格式化
* 前提条件:/dev/sdb为一块空的硬盘 * 创建物理卷:pvcreate /dev/sdb * 创建卷组:vgcreate vol_name /dev/sdb (vol_name 为卷组名字) ...
- Readiness 探测 - 每天5分钟玩转 Docker 容器技术(144)
除了 Liveness 探测,Kubernetes Health Check 机制还包括 Readiness 探测. 用户通过 Liveness 探测可以告诉 Kubernetes 什么时候通过重启容 ...
- 分享一个命令行计算器-bc
分享一个命令行计算器-bc 假如你在一个图形桌面环境中需要一个计算器时,你可能只需要一路进行点击便可以找到一个计算器.例如,Fedora 工作站中就已经包含了一个名为 Calculator 的工具.它 ...
- 用IDEA生成javadoc文档
用IDEA生成javadoc文档 打开相应的选项面板 设置 -encoding是java代码编码,-charset是对生成文档所用的编码.-windowtitle就是对应html的<title& ...
- 源码实现 --> strcmp
比较字符串大小 函数 int strcmp(const char *string1, const char *string2); 比较字符串string1和string2大小. 返回值< 0, ...
- ASP VNext 开源服务容错处理库Polly使用文档
在进入SOA之后,我们的代码从本地方法调用变成了跨机器的通信.任何一个新技术的引入都会为我们解决特定的问题,都会带来一些新的问题.比如网络故障.依赖服务崩溃.超时.服务器内存与CPU等其它问题.正是因 ...
- openjudge(三)
已知三角形的三边分别是a.b.c, 先算出周长的一半s=1/2(a+b+c) 则该三角形面积S=根号[s(s-a)(s-b)(s-c)] 这个公式叫海伦--秦九昭公式 证明: 设三角形的三边a.b.c ...