最新消息:

使用Arthas调用任意类的任意函数 – 1

Arthas niuge678 3290浏览 0评论

使用arthas调用任意函数

最近发现,使用Arthas可以调用jvm中任意的函数,调试问题十分方便,现在总结一下。

调用任何函数可以分为两类:一类是静态方法,另一类是非静态方法,本文介绍非静态方法。

调用当前类的任意方法

首先,使用tt监测指定方法:

tt -t com.alibet.fantasy.settlement.service.impl.ResettleServiceImpl calcPoint

然后,我们就可以观察每一次调用的参数,当前对象,返回值:

tt -i 1000 -w '{params, target, returnObj}' -x 2

我们还可以观测当前对象的任意一个field:

tt -i 1000 -w 'target.playerPoints'

我们还可以调用当前对象的其它方法:

tt -i 1000 -w 'target.getPlayerKey(1010383L, 709007L)'

同样的方式,target中的所有方法都可以调用。

调用任意类的任意方法

对于Spring应用,首先获取applicationContext,通过applicationContext可以获取容器内任意bean,通过bean就可以调用对应的方法:

tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod

tt是arthas的time tunnel命令,可以保存现场;
-t参数指定要观测的类和方法;

原理是:所有SpringMVC 的请求都会通过 RequestMappingHandlerAdapter 执行invokeHandlerMethod 到达目标接口上进行处理,而RequestMappingHandlerAdapter类中有 getApplicationContext。所以,只要tt监测到一次调用,就可以获取容器的ApplicationContext。

然后就可以通过applicationContext获取对应的bean,继而调用方法:

tt -i 1000 -w 'target.getApplicationContext().getBean("remoteEventService").queryGroupFantasyDataByGroupId(200017000L)' 

-i 1000,指定index
-w --watch-express 观察时空隧道里的表达式的值
target关键字就表示当前对象,可以查看当前对象中的属性或者当前对象的方法。

上面的例子通过name获取bean,也可以通过类型获取bean:

tt -i 1000 -w 'target.getApplicationContext().getBeansOfType(@com.fantasy.event.api.EventApi@class).queryEventById(200017000L, @com.fantasy.center.dto.Event@class)'

用类似的方式,就可以调用任意bean的任意方法了,我试用了多次,没发现有任何问题。

有了这样的工具,调查问题的效率是不是会大大提高。

查看静态field和调用静态方法更简单,有时间也写一下。

转载请注明:牛哥678 » 使用Arthas调用任意类的任意函数 – 1

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址