最近在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过程中一个有趣的问题的更多相关文章

  1. Debug过程中的mock (及display窗口的使用)

    转载:http://m.blog.csdn.net/blog/u012516903/18004965 在debug的时候,有3个地方可以进行mock测试 测试代码如下: 1.使用display窗口 W ...

  2. 如何在Eclipse和Tomcat的Debug过程中启用热部署

    参考的地址是 http://blog.redfin.com/devblog/2009/09/how_to_set_up_hot_code_replacement_with_tomcat_and_ecl ...

  3. xargs命令的使用过程中一个小领悟:管道与xargs的差别

    对xargs的使用总是比较模糊,大概的理解为:通道中,上一个命令的标准输出逐行作为下一个命令的参数 例如 find /var/temp* | xargs rm -r 功效:找出/var/中所有temp ...

  4. vue生命周期updated的触发时机之debug过程中发现的firefox问题

    现象描述: 断点位置1 谷歌debug的过程: 火狐debug的过程: 只要在改变数据之后有断点停顿,就会先去执行updated函数 断点位置2 此时火狐和谷歌是一样的效果,但是执行顺序是不一致的 谷 ...

  5. 【UEFI】---记录一次debug过程中的调试经验

    最近在调试一次SMBIOS的动态更新以及I2c设备的配置读取时,遇到了很多问题,特此总结: 1. 第一个是调试一个I2c设备的时候,遇到了一个很奇怪的问题,也由此问题总结了下SMBUS模块的知识,如下 ...

  6. IDEA Debug过程中使用Drop Frame或Reset Frame实现操作回退

    大家在Debug程序的时候,是否遇到过因为"下一步"按太快,而导致跳过了想要深入分析的那段代码?是不是很想要有"回到上一步"这样的操作呢? 在IDEA中就提供了 ...

  7. 解析 Java 反射题中一个有趣的坑

    public class Test { public void age(int age) { System.out.println("int age="+age); } publi ...

  8. c++ 内存分配中一个有趣的小问题

    以下代码测试环境:vs2019 执行这么一段代码,看看会发生什么. int main() { ] = { }; arr[] = ; } 毫无疑问,会报错,因为访问越界了. 再看看另一段代码 ] = { ...

  9. connect & send 在三次握手过程中的有趣问题

    一.问题回顾 面试的时候被问到的问题,原问题是: 1:写一下socket网络编程服务端和客户端常用的函数. 2:如果服务端在listen之后没有accept,那客户端的connect会返回吗?为什么? ...

随机推荐

  1. Linux 下 vim 编辑文件,解决中文乱码,设置Tab键空格数

    vim编辑文件的时候,输入中文就出现乱码 解决办法: 以哪个用户登录的就在哪个用户目录下创建文件 vimrc vim .vimrc       (.创建的是隐藏文件) 文件内容: set tabsto ...

  2. JavaScript之优化DOM

    优化DOM得从重绘和重排讲起,long long ago... 1.重绘和重排 1.1 重绘和重排是什么 重绘是指一些样式的修改,元素的位置和大小都没有改变: 重排是指元素的位置或尺寸发生了变化,浏览 ...

  3. git仓库搭建及客户端使用

    这里只在linux上做git仓库搭建 这里只在linux上做git仓库搭建 这里只在linux上做git仓库搭建 linux 服务器上安装及配置git 一.安装git yum install -y g ...

  4. 【Unity3D与23种设计模式】中介者模式(Mediator)

    GoF中定义: 定义一个接口来封装一群对象的互动行为 中介者通过移除对象之间的引用 以减少他们之间的耦合度 并且能改变它们之间的互动独立性 游戏做的越大,系统划分的也就越多 如事件系统,关卡系统,信息 ...

  5. Flume搭建

    [root@hadoop01 src]# mkdir flume [root@hadoop01 src]# ll 总用量 0 drwxr-xr-x. 2 root root  6 4月   7 201 ...

  6. delphi XE Datasnap SERVER 在windows 7 下为服务添加描述信息

    网上对服务添加描述信息的,多数是用注册表的方式,而注册表的方式,我在win7 下测试,不知为什么,总是不行,把执行的CMD以管理员模式开启,还是没加进去. 于是在网上查到下面的代码,保存供叁考,原文博 ...

  7. PHP中文关键词匹配

    关键词匹配是比较常见的需求,如留言.弹幕及游戏聊天中的敏感词过滤,都需要对一段文字进行关键词匹配.提取到关键词后,再做进一步处理. 本类借助PHP高效的数组和mbstring扩展,来实现对中文关键词的 ...

  8. VS调试再次遭遇“应用程序中断模式”问题,附解决方法

    最近重构某项目过程中发现的,有同事反馈调试不正常,很久以前也发生过,虽然搜索了一下找到解决方案,但个人觉得还是有必要再记录一下. 调试某CS结构的应用程序,大致效果可以看下图: 我们组最终解决方案是: ...

  9. Microsoft AI - Custom Vision in C#

    概述 前面一篇 Microsoft AI - Custom Vision 中,我们介绍了 Azure 认知服务中的自定义影像服务:Custom Vision,也介绍了如果通过这个在线服务,可视化的完成 ...

  10. 【Python】 用户图形界面GUI wxpython IV 菜单&对话框

    更多组件 ■ 菜单栏 Menu 菜单是很多GUI必不可少的一部分.要建立菜单,必须先创建菜单栏: menuBar = MenuBar() menu = Menu() item1 = menu.Appe ...