我目前正在尝试跟踪用于学习目的的方法调用。
我实现的javagent是本文中实现的修改版本。该程序将任何方法的调用记录指令添加到字节码中。不幸的是,引导类加载器拒绝从 rt.jar 加载任何纵的内容。我可以理解这对于生产环境来说不是一个好主意,但对于学生来说,这将是非常惊人的。
你有什么想法如何实现这一目标吗?
我可以成功地从 rt.jar 操作类。
例如,作了BigDecimal
类的字节码。您正在训练哪个课程来操纵?你在做什么样的操纵?只是像您提到的文章中那样将日志添加到类的每个方法中?
除了遵循文章的说明之外,我还必须做一些其他事情才能操作 rt.jar 的类。
-
在
LoggerAgent
类中,我添加了一个我明确想要操作的类数组。String[] includeArr = new String[] { "java/math/BigDecimal" }; ArrayList<String> include = new ArrayList(Arrays.asList(includeArr));
-
在
LoggerAgent
类的transform
方法中,我修改了循环以包含我明确想要操作的类。for (int i = 0; i < ignore.length; i++) { if (className.startsWith(ignore[i]) && !include.contains(className)) { return bytes; } }
-
修复了 JavassistHelper 的方法
methodReturnsValue
,以正确区分方法和构造函数。private static boolean methodReturnsValue(CtBehavior method)throws NotFoundException { if (method instanceof CtMethod){ CtClass returnType = ((CtMethod) method).getReturnType(); String returnTypeName = returnType.getName(); if(returnTypeName.equals("void")){ return false; }else{ return true; } } else{ return false; } }
-
最后,在 HelloWorld 类中,我创建了一个
BigDecimal
来检查操作行为。
输出如下所示:
19/06/2015 16:00:26 java.math.BigDecimal signum
INFO: << signum() returns: 1
19/06/2015 16:00:26 java.math.BigDecimal layoutChars
INFO: << layoutChars(1=true) returns: 11.1099999999999994315658113919198513031005859375
19/06/2015 16:00:26 java.math.BigDecimal toString
INFO: << toString() returns: 11.1099999999999994315658113919198513031005859375
19/06/2015 16:00:26 com.runjva.demo.HelloWorld main
INFO: << main(args=[])
BigDecimal=11.1099999999999994315658113919198513031005859375
Stop at Fri Jun 19 16:00:26 PDT 2015
我希望它有所帮助。如果没有,请添加您尝试执行的操作的更多详细信息。
您唯一的机会是更改 rt.jar 的内容。引导类装入器在许多方面都很特殊,许多(但不是全部)类甚至在代理启动之前就被装入了。
可以使用 redefine
方法显式重新定义某些类。但是,并非所有引导类都可以做到这一点。