Arthas: 是否可以考虑支持setstatic

Created on 12 Apr 2019  ·  18Comments  ·  Source: alibaba/arthas

项目中经常会使用一些静态字段,如GlobalOptions里面的这些配置,我们可以通过options命令去修改。在实际项目中也会有这种需求,实现也比较简单。

question-answered

All 18 comments

直接用 ognl 命令就可以了

Ognl如何设置,如果没有setter方法的话,没有找到相关用法。
比如配置 com.taobao.arthas.core.GlobalOptions.isUnsafe = true。

list、map或者其他复杂对象是否可以支持?
如 private static List blackList = new ArrayList();

@hengyunabc

有个比较笨的办法是,自己写个静态方法,在ognl表达式里面有调用静态方法的,在静态方法内做一些自己想做的事。我还没看到静态属性赋值.

@class@method(args)
Static method reference

好像ognl的确不能设置 static field。

可以写一个新的类,里面设置 static field的值。然后用 classloader 命令把这个新的类 load到JVM里再执行。

好像ognl的确不能设置 static field。

可以写一个新的类,里面设置 static field的值。然后用 classloader 命令把这个新的类 load到JVM里再执行。

还是有点麻烦,set static field的使用场景还是有的,不知能否作为通用能力提供。

arthas里面有用到动态代理,像那些字节码的操作,可以动态的修改类,从字节码层面上应该可以提供给一个属性提供set的功能。
在set属性的时候,内部尝试动态生成一个类包含set方法,然后进行操作。用完然后再销毁.

不知道这样行不行?

不用那么复杂,实现在getstatic的基础上加个field.set就可以了。 其实options已经实现了,只不过是内部的。

一般这种需求,若是在微服务里都是用的配置中心吧,arthas没有setXX方法,应也是基于安全性考虑,BTrace也是一样 只能看不能改

基于安全性的话,那Ognl调用静态方法也是不安全。redefine就更不用说了。作为诊断工具,甚至修一些小bug,有时候是需要set操作的。

Ognl也确实不安全,若急用的话 何不自己down下来先修改?后面再提交社区

我已经实现过了,是想问是否作为标准功能提供。

UP

@xuzhiyiYoh

  • getstatic是在 ognl命令之前做的。ognl命令实际上包含了getstatic的功能。本来是想把getstatic命令去掉的
  • 设置static field的功能感觉很少会用到,比如object从哪里来
  • 本质是如果实现一个setstatic命令,最终还是用反射去设置。所以实际上用户可以直接在ognl里写反射的代码。以arthas-demo为例,比如

ognl '#[email protected]@class.getDeclaredField("random"), #field.setAccessible(true), #field.set(null,null)'

我个人觉得增加setstatic命令的理由还不是很充分。 issue里的各位怎么看?

感觉getstatic可能会用到,像有些可能需要变动的static field,一般都是通过配置中心来修改,一方面这样有迹可循,也防止像setstatic修改了,也没有人知道是什么时候改的,谁改的。

感觉getstatic可能会用到,像有些可能需要变动的static field,一般都是通过配置中心来修改,一方面这样有迹可循,也防止像setstatic修改了,也没有人知道是什么时候改的,谁改的。

配置当然是通过配置中心来,支持setstatic是为了支持该一些非配置化代码,比如在业务代码里写死里某个类型,想变更进行调试,或者想其他中间件的某个指,类似日志场景。

当然总的来说,这个场景还是比较偏,ognl也一定程度上可以实现。

感觉getstatic可能会用到,像有些可能需要变动的static field,一般都是通过配置中心来修改,一方面这样有迹可循,也防止像setstatic修改了,也没有人知道是什么时候改的,谁改的。

配置当然是通过配置中心来,支持setstatic是为了支持该一些非配置化代码,比如在业务代码里写死里某个类型,想变更进行调试,或者想其他中间件的某个指,类似日志场景。

当然总的来说,这个场景还是比较偏,ognl也一定程度上可以实现。

最近看到这个问题,也是觉得比较麻烦,Arthas IDEA 插件支持这个功能,也是通过反射,但是和IDEA 集成起来,用起来比较简单,原理一样的,通过ognl 实现 ,2.5 版本,欢迎使用
https://plugins.jetbrains.com/plugin/13581-arthas-idea/

今天正好遇到了一个场景 如果有setstaitc还是很方便的

private static final int DEFAULT_MIN_COUNT = 10;
private static final int DEFAULT_MAX_COUNT = 50;

调用外部接口 有权限 取50个 无权限 取10个 结果由于第48个数据有问题 导致有权限的情况下报错了

需要临时紧急修改 有权限情况下 返回47个 (等外部接口修复后再改回来)

private static final int DEFAULT_MAX_COUNT = 47;

很天真的使用下面的方式来赋值

ognl '@com.foo.web.MyController@DEFAULT_MAX_COUNT = 47'

不work 没有找着setstatic 因为有final 反射应该也不行了

ognl '#[email protected]@class.getDeclaredField("random"), #field.setAccessible(true), #field.set(null,null)'

只好上传class到服务器上 redefine 解决了

但是redefine也不方便 redefine之后 发现生效了 就执行stop了 结果马上就失效了 似乎stop回滚了redefine的修改 但是好像命令行会话过期退出不会回滚

ognl可以实现setStatic的效果。

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hezhiqiang picture hezhiqiang  ·  6Comments

kylixs picture kylixs  ·  4Comments

hengyunabc picture hengyunabc  ·  4Comments

EternalHao picture EternalHao  ·  4Comments

xiuqianli1996 picture xiuqianli1996  ·  4Comments