使用 agentmain 時用 Javassist 工具將原來的方法 handle 復制出一個新方法 handle,然后修改原方法名為 handle$old,最后再設定復制出的 handle 方法的方法體,運行時報出標題上的錯誤。有大佬知道使用 agentmain 是有什么不能新增方法之類的限制嗎?
CtMethod ctMethod = ctClass.getDeclaredMethod(methodName);// 得到這方法實體
// 創建新的方法,復制原來的方法,名字為原來的名字
CtMethod newMethod = CtNewMethod.copy(ctMethod, methodName, ctClass, null);
// 定義一個方法名用于描述修改位元組碼之前的原方法
String oldMethodName = methodName + "$old";
// 將原方法名稱修改掉,避免和新添加的方法同名沖突
ctMethod.setName(oldMethodName);
// 構建新的方法體
StringBuilder bodyStr = new StringBuilder();
bodyStr.append("{");
bodyStr.append("long startTime = System.currentTimeMillis();\n");
// 呼叫原方法代碼,類似于method();($$)表示所有的引數
bodyStr.append(oldMethodName).append("($$);\n");
bodyStr.append("long endTime = System.currentTimeMillis();\n");
String outputStr = "System.out.println(\"this method " + methodName
+ " cost:\" +(endTime - startTime) +\"ms.\");\n";
bodyStr.append(outputStr);
bodyStr.append("}");
// 設定新的目標方法的方法體
newMethod.setBody(bodyStr.toString());
// 增加新方法, 原來的方法已經被修改名稱為 oldMethodName,呼叫時會呼叫到新的目標方法
ctClass.addMethod(newMethod);
uj5u.com熱心網友回復:
一樓挽尊
uj5u.com熱心網友回復:
Adding a field or method is impossible as it is today, only the code evolution VM supports it as of today and it is doubtful if this feature ever makes it to OpenJDK.uj5u.com熱心網友回復:
With an AgentBuilder, you should register a Listener to see if errors happen during retransformation. You probably should set .disableClassFormatChanges() as the average JVM does not support adding methods or fields to a class that already is defined.uj5u.com熱心網友回復:
哇,,我找半天檔案沒找到,nana 幫忙給個url,謝啦
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/229998.html
標籤:Java SE
