Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alibaba Arthas实践--获取到Spring Context,然后为所欲为 #482

Closed
hengyunabc opened this issue Jan 28, 2019 · 30 comments
Closed

Alibaba Arthas实践--获取到Spring Context,然后为所欲为 #482

hengyunabc opened this issue Jan 28, 2019 · 30 comments

Comments

@hengyunabc
Copy link
Collaborator

背景

Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。

Arthas提供了非常丰富的关于调用拦截的命令,比如 trace/watch/monitor/tt 。但是很多时候我们在排查问题时,需要更多的线索,并不只是函数的参数和返回值。
比如在一个spring应用里,想获取到spring context里的其它bean。如果能随意获取到spring bean,那就可以“为所欲为”了。

下面介绍如何利用Arthas获取到spring context。

Demo: https://github.com/hengyunabc/spring-boot-inside/tree/master/demo-arthas-spring-boot

Arthas快速开始:https://alibaba.github.io/arthas/quick-start.html

使用tt命令获取到spring context

Demo是一个spring mvc应用,请求会经过一系列的spring bean处理,那么我们可以在spring mvc的类里拦截到一些请求。

启动Demo: mvn spring-boot:run

使用Arthas Attach成功之后,执行tt命令来记录RequestMappingHandlerAdapter#invokeHandlerMethod的请求

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

然后访问一个网页: http://localhost:8080/

可以看到Arthas会拦截到这个调用,index是1000,并且打印出:

$ watch com.example.demo.Test * 'params[0]@sss'
$ tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 101 ms.
 INDEX  TIMESTAMP         COST(ms  IS-RE  IS-EX  OBJECT       CLASS                     METHOD
                          )        T      P
------------------------------------------------------------------------------------------------------------------
 1000   2019-01-27 16:31  3.66744  true   false  0x4465cf70   RequestMappingHandlerAda  invokeHandlerMethod
        :54                                                   pter

那么怎样获取到spring context?

可以用tt命令的-i参数来指定index,并且用-w参数来执行ognl表达式来获取spring context:

$ tt -i 1000 -w 'target.getApplicationContext()'
@AnnotationConfigEmbeddedWebApplicationContext[
    reader=@AnnotatedBeanDefinitionReader[org.springframework.context.annotation.AnnotatedBeanDefinitionReader@35dc90ec],
    scanner=@ClassPathBeanDefinitionScanner[org.springframework.context.annotation.ClassPathBeanDefinitionScanner@72078a14],
    annotatedClasses=null,
    basePackages=null,
]
Affect(row-cnt:1) cost in 7 ms.

从spring context里获取任意bean

获取到spring context之后,就可以获取到任意的bean了,比如获取到helloWorldService,并调用getHelloMessage()函数:

$ tt -i 1000 -w 'target.getApplicationContext().getBean("helloWorldService").getHelloMessage()'
@String[Hello World]
Affect(row-cnt:1) cost in 5 ms.

更多的思路

在很多代码里都有static函数或者static holder类,顺滕摸瓜,可以获取很多其它的对象。比如在Dubbo里通过SpringExtensionFactory获取spring context:

$ ognl '#context=@com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory@contexts.iterator.next, 
#context.getBean("userServiceImpl").findUser(1)'
@User[
    id=@Integer[1],
    name=@String[Deanna Borer],
]

链接

@sunnyxd
Copy link

sunnyxd commented Feb 12, 2019

spring bean中要调用的方法参数是对象类型,这个要怎么调用呢?

@hengyunabc
Copy link
Collaborator Author

spring bean中要调用的方法参数是对象类型,这个要怎么调用呢?

参考 https://commons.apache.org/proper/commons-ognl/language-guide.html "Calling Constructors"

@senlu
Copy link

senlu commented Feb 15, 2019

spring bean中调用无异常抛出的方法成功,但调用有异常(加了注解事物)的方法时报java.lang.NoSuchMethodException错?有异常方法调用和普通的不一致吗?
tt -i 1125 -w 'target.getApplicationContext().getBean("XXX").XX()'

@hengyunabc
Copy link
Collaborator Author

spring bean中调用无异常抛出的方法成功,但调用有异常(加了注解事物)的方法时报java.lang.NoSuchMethodException错?有异常方法调用和普通的不一致吗?
tt -i 1125 -w 'target.getApplicationContext().getBean("XXX").XX()'

应该是一个aop动态生成的类,有些行为可能不一样。可以自己在代码里试下。

@sun3Lu
Copy link

sun3Lu commented Aug 14, 2019

请教个问题 获取到spring context之后,如调用bean方法getXXX("参数")方法,中文参数无法正确显示和传递到方法上执行,如何解决???

@liugddx
Copy link

liugddx commented Sep 6, 2019

spring bean中要调用的方法参数是对象类型,这个要怎么调用呢?

参考 https://commons.apache.org/proper/commons-ognl/language-guide.html "Calling Constructors"

这个ognl语言不简单~~~

@WangJi92
Copy link
Contributor

WangJi92 commented Jan 6, 2020

spring bean中要调用的方法参数是对象类型,这个要怎么调用呢?

参考 https://commons.apache.org/proper/commons-ognl/language-guide.html "Calling Constructors"

这个ognl语言不简单~~~

arthas 基本命令和 ognl 使用起来还是有点麻烦,毕竟不经常使用ognl语言,这里弄了一个小插件可以简化一些常用的命令的使用,具体可以参考 https://plugins.jetbrains.com/plugin/13581-arthas-idea
插件使用介绍 https://www.yuque.com/docs/share/fa77c7b4-c016-4de6-9fa3-58ef25a97948?#

@lihengcn
Copy link

lihengcn commented Jun 29, 2020

tt -i 1000 -w 'target.getApplicationContext().getBean("userService")'
获取到的对象都是null
rootUserName=null,
sysUserRepository=null,
sysRoleRepository=null,
authService=null,
nbmsEntPrefixRepository=null,
nbmsEntRepository=null,
nbmsEntPrefixApplyRepository=null,
nbmsEntPrefixConfigService=null,
mailService=null,
shrPrefix=null,
eppEntService=null,
userService=null,
sysLogUserRepository=null,
repository=null,

@hengyunabc
Copy link
Collaborator Author

tt -i 1000 -w 'target.getApplicationContext().getBean("userService")'
获取到的对象都是null
rootUserName=null,
sysUserRepository=null,
sysRoleRepository=null,
authService=null,
nbmsEntPrefixRepository=null,
nbmsEntRepository=null,
nbmsEntPrefixApplyRepository=null,
nbmsEntPrefixConfigService=null,
mailService=null,
shrPrefix=null,
eppEntService=null,
userService=null,
sysLogUserRepository=null,
repository=null,

贴出全部的操作日志和结果

@lihengcn
Copy link

tt -i 1000 -w 'target.getApplicationContext().getBean("userService")'
获取到的对象都是null
rootUserName=null,
sysUserRepository=null,
sysRoleRepository=null,
authService=null,
nbmsEntPrefixRepository=null,
nbmsEntRepository=null,
nbmsEntPrefixApplyRepository=null,
nbmsEntPrefixConfigService=null,
mailService=null,
shrPrefix=null,
eppEntService=null,
userService=null,
sysLogUserRepository=null,
repository=null,

贴出全部的操作日志和结果

`[arthas@9]$ tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 451 ms, listenerId: 1
INDEX TIMESTAMP COST(ms) IS-RET IS-EXP OBJECT CLASS METHOD

1000 2020-06-30 12:25:14 48.844374 true false 0x5c4714ef RequestMappingHandlerAdapter invokeHandlerMethod
1001 2020-06-30 12:25:21 9.525508 true false 0x5c4714ef RequestMappingHandlerAdapter invokeHandlerMethod
1002 2020-06-30 12:25:28 4.081598 true false 0x5c4714ef RequestMappingHandlerAdapter invokeHandlerMethod
[arthas@9]$
[arthas@9]$ tt -i 1000 -w 'target.getApplicationContext().getBean("dictService")'
@DictService$$EnhancerBySpringCGLIB$$eab4e97d[
CGLIB$BOUND=@boolean[false],
CGLIB$FACTORY_DATA=@EnhancerFactoryData[org.springframework.cglib.proxy.Enhancer$EnhancerFactoryData@5fed9c9e],
CGLIB$THREAD_CALLBACKS=@ThreadLocal[java.lang.ThreadLocal@1b5043a7],
CGLIB$STATIC_CALLBACKS=null,
CGLIB$CALLBACK_0=@DynamicAdvisedInterceptor[org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor@7143c0d6],
CGLIB$CALLBACK_1=@StaticUnadvisedInterceptor[org.springframework.aop.framework.CglibAopProxy$StaticUnadvisedInterceptor@319d69fe],
CGLIB$CALLBACK_2=@SerializableNoOp[org.springframework.aop.framework.CglibAopProxy$SerializableNoOp@4452aba9],
CGLIB$CALLBACK_3=@StaticDispatcher[org.springframework.aop.framework.CglibAopProxy$StaticDispatcher@15334a0b],
CGLIB$CALLBACK_4=@AdvisedDispatcher[org.springframework.aop.framework.CglibAopProxy$AdvisedDispatcher@6b0d9f2a],
CGLIB$CALLBACK_5=@EqualsInterceptor[org.springframework.aop.framework.CglibAopProxy$EqualsInterceptor@3185d92c],
CGLIB$CALLBACK_6=@HashCodeInterceptor[org.springframework.aop.framework.CglibAopProxy$HashCodeInterceptor@605b3356],
CGLIB$CALLBACK_FILTER=@ProxyCallbackFilter[org.springframework.aop.framework.CglibAopProxy$ProxyCallbackFilter@241305f2],
CGLIB$getValue$0$Method=@method[public java.lang.String cn.teleinfo.bussiness.embed.service.DictService.getValue(java.lang.String,java.lang.String)],
CGLIB$getValue$0$Proxy=@MethodProxy[org.springframework.cglib.proxy.MethodProxy@6fb75e44],
CGLIB$emptyArgs=@object[][isEmpty=true;size=0],
CGLIB$delete$1$Method=@method[public void cn.teleinfo.bussiness.embed.service.DictService.delete(java.lang.Iterable)],
CGLIB$delete$1$Proxy=@MethodProxy[org.springframework.cglib.proxy.MethodProxy@68446857],
CGLIB$save$2$Method=@method[public void cn.teleinfo.bussiness.embed.service.DictService.save(java.lang.Object)],
CGLIB$save$2$Proxy=@MethodProxy[org.springframework.cglib.proxy.MethodProxy@771790ca],
CGLIB$save$3$Method=@method[public void cn.teleinfo.bussiness.embed.service.DictService.save(cn.teleinfo.bussiness.embed.model.entity.SysDictPO)],
CGLIB$save$3$Proxy=@MethodProxy[org.springframework.cglib.proxy.MethodProxy@4eefdcfd],
CGLIB$findByKey$4$Method=@method[public java.util.List cn.teleinfo.bussiness.embed.service.DictService.findByKey(java.lang.String)],
CGLIB$findByKey$4$Proxy=@MethodProxy[org.springframework.cglib.proxy.MethodProxy@1b7fee1a],
CGLIB$findByParentId$5$Method=@method[public java.util.List cn.teleinfo.bussiness.embed.service.DictService.findByParentId(java.lang.Long)],
CGLIB$findByParentId$5$Proxy=@MethodProxy[org.springframework.cglib.proxy.MethodProxy@50322bf2],
CGLIB$findLinkage$6$Method=@method[public cn.hutool.json.JSONObject cn.teleinfo.bussiness.embed.service.DictService.findLinkage(java.lang.String,java.lang.String)],
CGLIB$findLinkage$6$Proxy=@MethodProxy[org.springframework.cglib.proxy.MethodProxy@1b6860fe],
CGLIB$pageQuery$7$Method=@method[public cn.teleinfo.bussiness.embed.model.P cn.teleinfo.bussiness.embed.service.DictService.pageQuery(java.lang.String,java.lang.String,java.lang.String,java.lang.Integer,java.lang.Integer)],
CGLIB$pageQuery$7$Proxy=@MethodProxy[org.springframework.cglib.proxy.MethodProxy@2b505f5a],
CGLIB$findAll$8$Method=@method[public java.util.List cn.teleinfo.bussiness.embed.service.BaseService.findAll()],
CGLIB$findAll$8$Proxy=@MethodProxy[org.springframework.cglib.proxy.MethodProxy@4f3b6b14],
CGLIB$findOne$9$Method=@method[public java.lang.Object cn.teleinfo.bussiness.embed.service.BaseService.findOne(java.io.Serializable)],
CGLIB$findOne$9$Proxy=@MethodProxy[org.springframework.cglib.proxy.MethodProxy@e17b4ba],
CGLIB$delete$10$Method=@method[public void cn.teleinfo.bussiness.embed.service.BaseService.delete(java.lang.Object)],
CGLIB$delete$10$Proxy=@MethodProxy[org.springframework.cglib.proxy.MethodProxy@56204a16],
CGLIB$delete$11$Method=@method[public void cn.teleinfo.bussiness.embed.service.BaseService.delete(java.io.Serializable)],
CGLIB$delete$11$Proxy=@MethodProxy[org.springframework.cglib.proxy.MethodProxy@7f236507],
CGLIB$save$12$Method=@method[public void cn.teleinfo.bussiness.embed.service.BaseService.save(java.lang.Iterable)],
CGLIB$save$12$Proxy=@MethodProxy[org.springframework.cglib.proxy.MethodProxy@6bd4d23c],
CGLIB$equals$13$Method=@method[public boolean java.lang.Object.equals(java.lang.Object)],
CGLIB$equals$13$Proxy=@MethodProxy[org.springframework.cglib.proxy.MethodProxy@58d50998],
CGLIB$toString$14$Method=@method[public java.lang.String java.lang.Object.toString()],
CGLIB$toString$14$Proxy=@MethodProxy[org.springframework.cglib.proxy.MethodProxy@cf1986e],
CGLIB$hashCode$15$Method=@method[public native int java.lang.Object.hashCode()],
CGLIB$hashCode$15$Proxy=@MethodProxy[org.springframework.cglib.proxy.MethodProxy@681edfaa],
CGLIB$clone$16$Method=@method[protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException],
CGLIB$clone$16$Proxy=@MethodProxy[org.springframework.cglib.proxy.MethodProxy@2596a5a7],
sysDictRepository=null,
repository=null,
]
Affect(row-cnt:1) cost in 140 ms.
`

@lihengcn
Copy link

lihengcn commented Jun 30, 2020

tt -i 1000 -w 'target.getApplicationContext().getBean("userService")'
获取到的对象都是null
rootUserName=null,
sysUserRepository=null,
sysRoleRepository=null,
authService=null,
nbmsEntPrefixRepository=null,
nbmsEntRepository=null,
nbmsEntPrefixApplyRepository=null,
nbmsEntPrefixConfigService=null,
mailService=null,
shrPrefix=null,
eppEntService=null,
userService=null,
sysLogUserRepository=null,
repository=null,

贴出全部的操作日志和结果

获取到的repository都是null,项目是springboot,持久层是jpa

@hengyunabc
Copy link
Collaborator Author

tt -i 1000 -w 'target.getApplicationContext().getBean("userService")'
获取到的对象都是null
rootUserName=null,
sysUserRepository=null,
sysRoleRepository=null,
authService=null,
nbmsEntPrefixRepository=null,
nbmsEntRepository=null,
nbmsEntPrefixApplyRepository=null,
nbmsEntPrefixConfigService=null,
mailService=null,
shrPrefix=null,
eppEntService=null,
userService=null,
sysLogUserRepository=null,
repository=null,

贴出全部的操作日志和结果

获取到的repository都是null,项目是springboot,持久层是jpa

。。这个是cglib的代理对象,搜索下cglib原理相关。

@WangJi92
Copy link
Contributor

tt -i 1000 -w 'target.getApplicationContext().getBean("userService")'
获取到的对象都是null
rootUserName=null,
sysUserRepository=null,
sysRoleRepository=null,
authService=null,
nbmsEntPrefixRepository=null,
nbmsEntRepository=null,
nbmsEntPrefixApplyRepository=null,
nbmsEntPrefixConfigService=null,
mailService=null,
shrPrefix=null,
eppEntService=null,
userService=null,
sysLogUserRepository=null,
repository=null,

贴出全部的操作日志和结果

获取到的repository都是null,项目是springboot,持久层是jpa

之前给同事排查遇到过,可以使用这个看一下!

tt -i 1000 -w '#userServers=target.getApplicationContext().getBean("userService"),@org.springframework.aop.support.AopUtils@getTargetClass(#userServers)'

@lihengcn
Copy link

tt -i 1000 -w 'target.getApplicationContext().getBean("userService")'
获取到的对象都是null
rootUserName=null,
sysUserRepository=null,
sysRoleRepository=null,
authService=null,
nbmsEntPrefixRepository=null,
nbmsEntRepository=null,
nbmsEntPrefixApplyRepository=null,
nbmsEntPrefixConfigService=null,
mailService=null,
shrPrefix=null,
eppEntService=null,
userService=null,
sysLogUserRepository=null,
repository=null,

贴出全部的操作日志和结果

获取到的repository都是null,项目是springboot,持久层是jpa

之前给同事排查遇到过,可以使用这个看一下!

tt -i 1000 -w '#userServers=target.getApplicationContext().getBean("userService"),@org.springframework.aop.support.AopUtils@getTargetClass(#userServers)'

大佬 我是想获取到userService对象后调用对象的方法 你发的命令执行完后显示如下

[arthas@9]$ tt -i 1003 -w '#userService=target.getApplicationContext().getBean("userService"), @org.springframework.aop.support.AopUtils@getTargetClass(#userService)'
@Class[
ANNOTATION=@integer[8192],
ENUM=@integer[16384],
SYNTHETIC=@integer[4096],
cachedConstructor=null,
newInstanceCallerCache=null,
name=@string[cn.teleinfo.bussiness.embed.service.UserService],
allPermDomain=@ProtectionDomain[ProtectionDomain null
null

java.security.Permissions@1abd60cd (
("java.security.AllPermission" "" "")
)

],
useCaches=@boolean[true],
reflectionData=@SoftReference[java.lang.ref.SoftReference@16c8bcfb],
classRedefinedCount=@integer[0],
genericInfo=@ClassRepository[sun.reflect.generics.repository.ClassRepository@7bf1f2a0],
serialVersionUID=@long[3206093459760846163],
serialPersistentFields=@ObjectStreamField[][isEmpty=true;size=0],
reflectionFactory=@ReflectionFactory[sun.reflect.ReflectionFactory@2e5c7cb6],
initted=@boolean[true],
enumConstants=null,
enumConstantDirectory=null,
annotationData=@AnnotationData[java.lang.Class$AnnotationData@5f96cab8],
annotationType=null,
classValueMap=null,
]
Affect(row-cnt:1) cost in 2 ms.

@lihengcn
Copy link

tt -i 1000 -w 'target.getApplicationContext().getBean("userService")'
获取到的对象都是null
rootUserName=null,
sysUserRepository=null,
sysRoleRepository=null,
authService=null,
nbmsEntPrefixRepository=null,
nbmsEntRepository=null,
nbmsEntPrefixApplyRepository=null,
nbmsEntPrefixConfigService=null,
mailService=null,
shrPrefix=null,
eppEntService=null,
userService=null,
sysLogUserRepository=null,
repository=null,

贴出全部的操作日志和结果

获取到的repository都是null,项目是springboot,持久层是jpa

。。这个是cglib的代理对象,搜索下cglib原理相关。

谢谢大佬,我查下资料

@WangJi92
Copy link
Contributor

WangJi92 commented Jun 30, 2020

大佬 我是想获取到userService对象后调用对象的方法 你发的命令执行完后显示如下

看看这个文章-arthas 入门最佳实践直接使用arthas idea plugin 生成 通过静态的static 、或者tt 也就是你这种方式、或者watch 直接集成给你生成命令

@longshengtang
Copy link

tt -i 1000 -w 'target.getApplicationContext().getBean("userService")'
获取到的对象都是null
rootUserName=null,
sysUserRepository=null,
sysRoleRepository=null,
authService=null,
nbmsEntPrefixRepository=null,
nbmsEntRepository=null,
nbmsEntPrefixApplyRepository=null,
nbmsEntPrefixConfigService=null,
mailService=null,
shrPrefix=null,
eppEntService=null,
userService=null,
sysLogUserRepository=null,
repository=null,

贴出全部的操作日志和结果

获取到的repository都是null,项目是springboot,持久层是jpa

。。这个是cglib的代理对象,搜索下cglib原理相关。

谢谢大佬,我查下资料
您好,我现在也遇到这个问题,请问怎么解决

@lixuanbin
Copy link

great examples! mark~

@me10zyl
Copy link

me10zyl commented Mar 17, 2021

mark

1 similar comment
@yydzxz
Copy link

yydzxz commented May 14, 2021

mark

@yqt8926
Copy link

yqt8926 commented Aug 27, 2021

大佬你好,我在使用中遇到一个问题,就是target.getApplicationContext()报了一个NoSuchMethodException的错误。所以在getBean()的时候更加拿不到了。我们使用的是springboot项目。
1、我的操作是这样的:

tt -t com.hm.mayson.module.recommend.service.link.CdssRuleLink profileRecommend -n 5

INDEX TIMESTAMP COST(m IS-RE IS-EX OBJECT CLASS METHOD
s) T P

1000 2021-08-27 16:5 120.84 true false 0x7100dea CdssRuleLink profileRecommend
8:12 4801

tt -i 1000 -w 'target.getApplicationContext()'
2、然后报了一个这样的错误:

ognl.MethodFailedException: Method "getApplicationContext" failed for object com.hm.mayson.module.recommend.service.link.CdssRuleLink@7100dea [java.lang.NoSuchMethodException: com.hm.mayson.module.recommend.service.link.CdssRuleLink.getApplicationContext()], visit /root/logs/arthas/arthas.log for more detail
3、arthas.log中的报错信息如下:

ognl.MethodFailedException: Method "getApplicationContext" failed for object com.hm.mayson.module.recommend.service.link.CdssRuleLink@7100dea
at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1556)
at ognl.ObjectMethodAccessor.callMethod(ObjectMethodAccessor.java:68)
at ognl.OgnlRuntime.callMethod(OgnlRuntime.java:1620)
at ognl.ASTMethod.getValueBody(ASTMethod.java:91)
at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
at ognl.SimpleNode.getValue(SimpleNode.java:258)
at ognl.ASTChain.getValueBody(ASTChain.java:141)
at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
at ognl.SimpleNode.getValue(SimpleNode.java:258)
at ognl.Ognl.getValue(Ognl.java:470)
at ognl.Ognl.getValue(Ognl.java:572)
at ognl.Ognl.getValue(Ognl.java:542)
at com.taobao.arthas.core.command.express.OgnlExpress.get(OgnlExpress.java:37)
at com.taobao.arthas.core.command.monitor200.TimeTunnelCommand.processWatch(TimeTunnelCommand.java:366)
at com.taobao.arthas.core.command.monitor200.TimeTunnelCommand.process(TimeTunnelCommand.java:293)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.process(AnnotatedCommandImpl.java:82)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.access$100(AnnotatedCommandImpl.java:18)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:111)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:108)
at com.taobao.arthas.core.shell.system.impl.ProcessImpl$CommandProcessTask.run(ProcessImpl.java:385)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoSuchMethodException: com.hm.mayson.module.recommend.service.link.CdssRuleLink.getApplicationContext()
at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1497)
... 26 common frames omitted
2021-08-27 17:38:06 [arthas-command-execute] WARN c.t.a.c.c.m.TimeTunnelCommand -tt failed.
com.taobao.arthas.core.command.express.ExpressException: ognl.MethodFailedException: Method "getApplicationContext" failed for object com.hm.mayson.module.recommend.service.link.CdssRuleLink@7100dea [java.lang.NoSuchMethodException: com.hm.mayson.module.recommend.service.link.CdssRuleLink.getApplicationContext()]
at com.taobao.arthas.core.command.express.OgnlExpress.get(OgnlExpress.java:40)
at com.taobao.arthas.core.command.monitor200.TimeTunnelCommand.processWatch(TimeTunnelCommand.java:366)
at com.taobao.arthas.core.command.monitor200.TimeTunnelCommand.process(TimeTunnelCommand.java:293)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.process(AnnotatedCommandImpl.java:82)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.access$100(AnnotatedCommandImpl.java:18)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:111)
at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:108)
at com.taobao.arthas.core.shell.system.impl.ProcessImpl$CommandProcessTask.run(ProcessImpl.java:385)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: ognl.MethodFailedException: Method "getApplicationContext" failed for object com.hm.mayson.module.recommend.service.link.CdssRuleLink@7100dea
at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1556)
at ognl.ObjectMethodAccessor.callMethod(ObjectMethodAccessor.java:68)
at ognl.OgnlRuntime.callMethod(OgnlRuntime.java:1620)
at ognl.ASTMethod.getValueBody(ASTMethod.java:91)
at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
at ognl.SimpleNode.getValue(SimpleNode.java:258)
at ognl.ASTChain.getValueBody(ASTChain.java:141)
at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
at ognl.SimpleNode.getValue(SimpleNode.java:258)
at ognl.Ognl.getValue(Ognl.java:470)
at ognl.Ognl.getValue(Ognl.java:572)
at ognl.Ognl.getValue(Ognl.java:542)
at com.taobao.arthas.core.command.express.OgnlExpress.get(OgnlExpress.java:37)
... 14 common frames omitted
Caused by: java.lang.NoSuchMethodException: com.hm.mayson.module.recommend.service.link.CdssRuleLink.getApplicationContext()
at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1497)
... 26 common frames omitted

@hengyunabc
Copy link
Collaborator Author

@yqt8926 现在可以用 vmtool 命令更方便 : https://arthas.aliyun.com/doc/vmtool ,把在线教程跑一下。

@yqt8926
Copy link

yqt8926 commented Aug 27, 2021

@yqt8926 现在可以用 vmtool 命令更方便 : https://arthas.aliyun.com/doc/vmtool ,把在线教程跑一下。

感谢感谢,已经获取到了。

@Miliving
Copy link

tt -i 1002 -w 'target.getApplicationContext().getBean("tempController")'
在控制台看到,通过@resource@Autowired注解注入的属性都是null:
tempService=null,
redisUtil=null,
busContractService=null,
projectCenterLogic=null,
busContractMapper=null,

@hengyunabc
Copy link
Collaborator Author

@Miliving 上面的回复就有关于这个null的,这是cglib生成的代理类。

@Miliving
Copy link

Miliving commented Aug 15, 2022

那标题是不是有点夸张了!!通常spring应用中bean基本都会有@resource或者@Autowired相互注入,然后通过这些注入的属性调用相关的方法,结果通过 tt 命令拿到的bean这些属性都是null,只能调用静态方法!!

@hengyunabc
Copy link
Collaborator Author

那标题是不是有点夸张了!!通常spring应用中bean基本都会有@resource或者@Autowired相互注入,然后通过这些注入的属性调用相关的方法,结果通过 tt 命令拿到的bean这些属性都是null,则无法进行方法调用。只能调用静态方法!!

  1. 自己先去看下cglib的原理。这个cglib对象有一个field,是原始的对象,获取到之后,就有原始对象的所有东西了
  2. 通过cglib对象是能直接调用原来对象的函数的,不然自己在代码里@Autowired依赖的也是cglib对象,它是怎么能被调用的?
  3. 现在更多用vmtool来搜对象,不需要用tt命令了。 https://arthas.aliyun.com/doc/vmtool.html

@wisheslee
Copy link

在上面的示例里:tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod。最好把-n 1加上,即tt -n 1 -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod。不然在线上会把所有流量拦截

@seqwait
Copy link

seqwait commented Jan 8, 2023

执行后出现这个错误啥情况
Time fragment[1000] does not exist

@LewJun
Copy link

LewJun commented Mar 8, 2023

[arthas@11232]$ tt -i 1002 -w 'target.getApplicationContext().getBean("fooService").save((#foo=new com.example.lewjun.model.Foo(), #foo.setName("LewJun"), #foo))'
@Boolean[true]
Affect(row-cnt:1) cost in 1 ms.
[arthas@11232]$ tt -i 1002 -w 'target.getApplicationContext().getBean("fooService").getById(6)'
@Foo[
    id=@Integer[6],
    name=@String[LewJun],
    height=null,
    sex=null,
]
Affect(row-cnt:1) cost in 1 ms.
[arthas@11232]$

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests