Java agentmain 代理修改类报错 class redefinition failed: attempted to add a method

谈谈1974 2020-12-04 04:33:12
使用 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);
...全文
8686 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
谈谈1974 2020-12-07
  • 打赏
  • 举报
回复
谈谈1974 2020-12-07
  • 打赏
  • 举报
回复
NANA 威武,,400 分给你
谈谈1974 2020-12-07
  • 打赏
  • 举报
回复
引用 10 楼 NANU-NANA 的回复:
[quote=引用 9 楼 谈谈1974 的回复:][quote=引用 6 楼 NANU-NANA 的回复:][quote=引用 4 楼 谈谈1974 的回复:][quote=引用 3 楼 NANU-NANA 的回复:]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.
哇,,我找半天文档没找到,nana 帮忙给个url,谢啦[/quote] 你要什么api?Javassist么? https://www.javassist.org[/quote]不是哦,就是你贴的这段英文是在哪里的呢,我去看下[/quote] 这可记不起来了,我当时给你上网搜了一下,好像是stackoverflow上的一个帖子[/quote]看了下 javassist 的文档,也提到了已经加载的类不能改变类的 schema,方法列表和成员变量必须和原本的类一致
NANU-NANA 2020-12-07
  • 打赏
  • 举报
回复
引用 9 楼 谈谈1974 的回复:
[quote=引用 6 楼 NANU-NANA 的回复:][quote=引用 4 楼 谈谈1974 的回复:][quote=引用 3 楼 NANU-NANA 的回复:]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.
哇,,我找半天文档没找到,nana 帮忙给个url,谢啦[/quote] 你要什么api?Javassist么? https://www.javassist.org[/quote]不是哦,就是你贴的这段英文是在哪里的呢,我去看下[/quote] 这可记不起来了,我当时给你上网搜了一下,好像是stackoverflow上的一个帖子
谈谈1974 2020-12-07
  • 打赏
  • 举报
回复
引用 6 楼 NANU-NANA 的回复:
[quote=引用 4 楼 谈谈1974 的回复:][quote=引用 3 楼 NANU-NANA 的回复:]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.
哇,,我找半天文档没找到,nana 帮忙给个url,谢啦[/quote] 你要什么api?Javassist么? https://www.javassist.org[/quote]不是哦,就是你贴的这段英文是在哪里的呢,我去看下
  • 打赏
  • 举报
回复
alpha Na 不是前端么 怎么做起后端来了?
  • 打赏
  • 举报
回复
aphla Na 不是前端么 怎么做起后端来了?
NANU-NANA 2020-12-07
  • 打赏
  • 举报
回复
引用 4 楼 谈谈1974 的回复:
[quote=引用 3 楼 NANU-NANA 的回复:]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.
哇,,我找半天文档没找到,nana 帮忙给个url,谢啦[/quote] 你要什么api?Javassist么? https://www.javassist.org
谈谈1974 2020-12-04
  • 打赏
  • 举报
回复
引用 3 楼 NANU-NANA 的回复:
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.
哇,,我找半天文档没找到,nana 帮忙给个url,谢啦
NANU-NANA 2020-12-04
  • 打赏
  • 举报
回复
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.
NANU-NANA 2020-12-04
  • 打赏
  • 举报
回复
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.
谈谈1974 2020-12-04
  • 打赏
  • 举报
回复
一楼挽尊

62,634

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧