Arthas之實例操作
1. 靜態(tài)類屬性操作
獲取public靜態(tài)屬性
ognl?-c?7cd84586?'@com.system.framework.ArtahsDemoClassLoader@pubTestPrex'
ognl?-c?7cd84586?"@com.system.framework.ArtahsDemoClassLoader@pubfinalTestPrex"
輸出各式 @Type[屬性值],內(nèi)容如下
@String[static?public]
...
@String[final?static?public]
獲取private靜態(tài)屬性
ognl?-c?7cd84586?'@com.system.framework.ArtahsDemoClassLoader@privTestPrex'
ognl?-c?7cd84586?'@com.system.framework.ArtahsDemoClassLoader@privFnalTestPrex'
@String[static?private]
...
@String[final?static?private]
修改public靜態(tài)屬性,被final修飾,不能被修改
//?測試代碼想修改FINAL修飾符,結果沒有成功
@Test
public?void?testModifyFinal()?throws?Exception?{
??Field?finalField?=?this.getClass().getDeclaredField("privFnalTestPrex");
??finalField.setAccessible(true);
??System.out.println("==========初始值==========");
??System.out.println(finalField.get(null));
??Field?modiField?=?Field.class.getDeclaredField("modifiers");
??modiField.setAccessible(true);
??modiField.setInt(finalField,?finalField.getModifiers()?&?~Modifier.FINAL);
??finalField.set(null,?"修改后FInal");
??System.out.println("==========修改值==========");
??System.out.println(privFnalTestPrex);
}
靜態(tài)變量賦值,不能通過=直接賦值,需要采用反射的方式設置值
ognl?'#[email protected]@class,#f=#c.getDeclaredField("pubTestPrex"),#f.set(#c,"modify?static?public?")'
修改private靜態(tài)屬性,需要在反射時調(diào)用方法setAccessible,使private特殊轉化為public
ognl?'#[email protected]@class,#f=#c.getDeclaredField("privTestPrex"),#f.setAccessible(true),#f.set(#c,"modify?static?private?")'
2. 靜態(tài)類方法調(diào)用
靜態(tài)方法調(diào)用和靜態(tài)屬性一樣,格式為@class@method(args)
無參數(shù)調(diào)用
ognl?-c?7cd84586?'@com.system.framework.ArtahsDemoClassLoader@setPublicStaticMethod()'
ognl?-c?7cd84586?'@com.system.framework.ArtahsDemoClassLoader@modfiyPrivateStaticFiled()'
...
======第5次輸出======
源文件初始輸出==>static?public/static?private/testRefect--1/final?static?public/final?static?private
源文件初始輸出==>static?public/static?private/testRefect--2/final?static?public/final?static?private
======第6次輸出======
源文件初始輸出==>modify?by?method?static?public/static?private/testRefect--1/final?static?public/final?static?private
源文件初始輸出==>modify?by?method?static?public/static?private/testRefect--2/final?static?public/final?static?private
...
======第11次輸出======
源文件初始輸出==>modify?by?method?static?public/static?private/testRefect--1/final?static?public/final?static?private
源文件初始輸出==>modify?by?method?static?public/static?private/testRefect--2/final?static?public/final?static?private
======第12次輸出======
源文件初始輸出==>modify?by?method?static?public/modify?by?method?static?private/testRefect--1/final?static?public/final?static?private
源文件初始輸出==>modify?by?method?static?public/modify?by?method?static?private/testRefect--2/final?static?public/final?static?private
...
有參數(shù)調(diào)用
ognl?-c?7cd84586?'@com.system.framework.ArtahsDemoClassLoader@getPublicStaticMethod("input?params")'
...
ognl?-c?7cd84586?'@com.system.framework.ArtahsDemoClassLoader@getStaticPrivateMethod("input?params")'
@String[input?params?<==>?public?static?method?return?string]
...
@String[input?params?<==>?private?static?method?return?string]
從以上的測試結果來說,靜態(tài)方法不管是public還是private都可以直接調(diào)用。
3. 獲取非靜態(tài)類實例
查看某個類實例,無 --limit 參數(shù)默認10個
vmtool?-c?3e2e18f2?-a?getInstances?--className?*EncryptClass
vmtool?-c?3e2e18f2?-a?getInstances?--className?*EncryptClass?--express?'instances.length'
vmtool?-c?3e2e18f2?-a?getInstances?--className?*EncryptClass?--express?'instances[0]'
@EncryptClass[][
????@EncryptClass[com.system.framework.EncryptClass@3c573d32],
????@EncryptClass[com.system.framework.EncryptClass@68390fae],
]
...
@Integer[2]
...
@EncryptClass[
????note=@String[testRefect--1],
]
經(jīng)過上邊測試發(fā)現(xiàn),一個類存在多個classloader加載時,需要指定classloader。但從返回結果看,返回了所有classloader加載的實例
4. 實例方法調(diào)用
調(diào)用實例 getNote 和 setNote 方法
vmtool?-c?3e2e18f2?-a?getInstances?--className?*EncryptClass?--express?'#val=instances[0],#val.getNote()'
vmtool?-c?3e2e18f2?-a?getInstances?--className?*EncryptClass?--express?'#val=instances[0],#val.setNote("modify?by?instance"+#val.getNote())'
@String[testRefect--1]
======第7次輸出======
源文件初始輸出==>static?public/static?private/testRefect--1/final?static?public/final?static?private
源文件初始輸出==>static?public/static?private/testRefect--2/final?static?public/final?static?private
======第8次輸出======
源文件初始輸出==>static?public/static?private/modify?by?instancetestRefect--1/final?static?public/final?static?private
源文件初始輸出==>static?public/static?private/testRefect--2/final?static?public/final?static?private
從控制臺輸出結果,對比第7次和8次輸出,我們可以發(fā)現(xiàn)第一個loader加載的class實例已經(jīng)成功修改了
5. 實例屬性操作
獲取或者修改第一個實例 note 屬性
vmtool?-c?3e2e18f2?-a?getInstances?--className?*EncryptClass?--express?'#val=instances[1].note'
vmtool?-c?3e2e18f2?-a?getInstances?--className?*EncryptClass?--express?'#val=instances[1],#val.note="modify?by?instance"+#val.note'
@String[testRefect--2]
...
======第121次輸出======
源文件初始輸出==>static?public/static?private/modify?by?instancetestRefect--1/final?static?public/final?static?private
源文件初始輸出==>static?public/static?private/testRefect--2/final?static?public/final?static?private
======第122次輸出======
源文件初始輸出==>static?public/static?private/modify?by?instancetestRefect--1/final?static?public/final?static?private
源文件初始輸出==>static?public/static?private/modify?by?instancetestRefect--2/final?static?public/final?static?private
從控制臺輸出結果,對比第121次和122次輸出,我們可以發(fā)現(xiàn)第二個loader加載的class實例已經(jīng)成功修改了
6. 條件操作
返回的對象集合,可以做二次篩選投影操作,也可以帶條件查詢符合的數(shù)據(jù)
vmtool?-c?3e2e18f2?-a?getInstances?--className?*EncryptClass?--express?'#val=instances'
vmtool?-c?3e2e18f2?-a?getInstances?--className?*EncryptClass?--express?'#val=instances.{note}'
vmtool?-c?3e2e18f2?-a?getInstances?--className?*EncryptClass?--express?'#val=instances.{#this.note}'
vmtool?-c?3e2e18f2?-a?getInstances?--className?*EncryptClass?--express?'#val=instances.{??#this.note.indexOf("1")>0}.{note}'
@EncryptClass[][
????@EncryptClass[com.system.framework.EncryptClass@52790e67],
????@EncryptClass[com.system.framework.EncryptClass@822cf83],
]
...
@ArrayList[
????@String[modify?by?instancetestRefect--1],
????@String[modify?by?instancetestRefect--2],
]
...
@ArrayList[
????@String[modify?by?instancetestRefect--1],
????@String[modify?by?instancetestRefect--2],
]
...
@ArrayList[
????@String[modify?by?instancetestRefect--1],
]
7.?總結
最近測試了Arthas很多命令,下篇將分享"各種監(jiān)控操作的黑魔法".歡迎感興趣的朋友關注我的訂閱號“小院不小”,或點擊下方二維碼關注。我將多年開發(fā)中遇到的難點,以及一些有意思的功能,體會都會一一發(fā)布到我的訂閱號中
