最近在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源码链接

最新文章

  1. (heartbeat与KeepAlived)
  2. LDAP客户端
  3. 前端工程化开发之yeoman、bower、grunt
  4. The main difference between Java & C++(转载)
  5. js获取页面传过来的参数
  6. PHP邮件注入攻击技术
  7. ie8默认主页/起始页无法修改
  8. EditorWindow窗口大小锁死后没有边框的解决方法
  9. OpenSSH for Windows,CopSSH
  10. CentOS+Apache+php无法访问redis的解决方法
  11. (转)iOS7界面设计规范(3) - UI基础 - 启动与退出
  12. window.dialogArguments的使用
  13. SGU 106 The Equation 扩展欧几里得应用
  14. PHP 性能追踪及分析工具(XHPROF)
  15. 高性能 TCP & HTTP 通信框架 HP-Socket v4.2.1
  16. laravel服务容器
  17. android sdk content loader 0%不动
  18. 两个list对应元素相加
  19. ABP .Net Core To Json序列化配置
  20. JS中如何处理多个ajax并发请求?

热门文章

  1. ------ 开源软件 Tor(洋葱路由器,构建匿名网络的方案之一)源码分析——主程序入口点(二)------
  2. 如何提高windows的性能
  3. IO查找文件复制到指定路径
  4. SpringtMVC运行流程:@RequestMapping 方法中的 Map、HttpServletRequest等参数信息是如何封装和传递的(源码理解)
  5. JavaScript之实例
  6. web SPA项目目录、命名规范
  7. mysql limit 接收变量
  8. Android学习笔记1——开发环境配置
  9. Linux创建普通用户以及权限的分配
  10. mybatis代码生成器