简体   繁体   English

从rt.jar中使用经过处理的字节码重新加载类

[英]Reloading classes with maniupulated bytecode from rt.jar

I am currently trying to track method calls for learning purposes. 我目前正在尝试跟踪用于学习目的的方法调用。

The javagent I have implemented is a modified version of the implementation in this article . 我已经实现了javagent是在执行修改后的版本这篇文章 The programm adds to any method call logging instructions into the bytecode. 该程序将任何记录调用指令添加到字节码中。 Unfortunately bootstrap classloader refuses to load any manipulated content from rt.jar. 不幸的是,引导类加载器拒绝从rt.jar加载任何操作的内容。 I can understand that this isn't a good idea for a production enviroment, but for a student it would be really amazing. 我可以理解,对于生产环境而言,这不是一个好主意,但是对于学生而言,这确实是一个了不起的主意。

Do you got any ideas how to make this happen? 您有任何想法如何实现这一目标吗?

The only chance you have is to change the contents of rt.jar . 您唯一的机会是更改rt.jar的内容。 The bootstrap class loader is special in many ways, many, but not all, of the classes are loaded before the agent even starts up. 引导类加载器在许多方面都很特殊,许多(但不是全部)类在代理启动之前就已加载。

Some classes can be explicitly redefined using the redefine method. 可以使用redefine方法显式重新定义某些类。 This is however not possible for all bootstrap classes. 但是,并非所有引导类都可以这样做。

I could successfully manipulate classes from the rt.jar. 我可以从rt.jar成功地操作类。

For example I manipulated the bytecode of the BigDecimal class. 例如,我操纵了BigDecimal类的字节码。 Which class are you training to manipulate? 您正在训练要上哪堂课? And what kind of manipulation are you doing? 您在进行哪种操作? Just adding logs to every method of the class like in the article that you mentioned? 只是将日志添加到您提到的文章中的类的每个方法上?

In additional of following the instructions of article, I had to do some other things in order to be able manipulate the classes of rt.jar. 除了按照本文的说明进行操作外,我还必须执行其他一些操作才能处理rt.jar类。

  1. In the LoggerAgent class I added an array of classes that I explicitly want to manipulate. LoggerAgent类中,我添加了一个我明确要处理的类的数组。

     String[] includeArr = new String[] { "java/math/BigDecimal" }; ArrayList<String> include = new ArrayList(Arrays.asList(includeArr)); 
  2. In the transform method of the LoggerAgent class I modified the loop to include the classes I explicitly want to manipulate. LoggerAgent类的transform方法中,我修改了循环以包含我明确想要处理的类。

     for (int i = 0; i < ignore.length; i++) { if (className.startsWith(ignore[i]) && !include.contains(className)) { return bytes; } } 
  3. Fixed the method methodReturnsValue of JavassistHelper to correctly distinguish between methods and constructors. 修复了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; } } 
  4. Last, in the HelloWorld class I created a BigDecimal just to check the manipulation behavior. 最后,在HelloWorld类中,我创建了一个BigDecimal来检查操作行为。

The output looks like as follow: 输出如下:

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

I hope it helps. 希望对您有所帮助。 If not, please add more details of what you are trying to do. 如果没有,请添加您要执行的操作的更多详细信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM