使用来自rt.jar的拼接字节码重新加载类

时间:2015-06-18 23:33:12

标签: java classloader bootstrapping bytecode-manipulation rt.jar

我目前正在尝试跟踪方法调用以进行学习。

我实施的javagent是this article中实现的修改版本。该程序将任何方法调用记录指令添加到字节码中。不幸的是,bootstrap类加载器拒绝从rt.jar加载任何被操纵的内容。我可以理解这对于生产环境来说不是一个好主意,但对于学生来说这真的很棒。

你有任何想法如何实现这一目标吗?

2 个答案:

答案 0 :(得分:0)

您唯一的机会是更改 rt.jar 的内容。引导类加载器在许多方面都很特殊,在代理甚至启动之前,许多(但不是全部)类都被加载。

可以使用redefine方法显式重新定义某些类。但是,这对于所有引导类都不可能。

答案 1 :(得分:0)

我可以成功地操作rt.jar中的类。

例如,我操纵了BigDecimal类的字节码。你在训练哪个班级操纵?你在做什么样的操纵?只是将日志添加到类的每个方法,就像你提到的文章一样?

除了遵循文章的说明之外,我还必须做一些其他事情才能操作rt.jar的类。

  1. LoggerAgent类中,我添加了一系列我明确想要操作的类。

    String[] includeArr = new String[] { "java/math/BigDecimal" };
    ArrayList<String> include = new ArrayList(Arrays.asList(includeArr));
    
  2. transform类的LoggerAgent方法中,我修改了循环以包含我明确想要操作的类。

    for (int i = 0; i < ignore.length; i++) {
        if (className.startsWith(ignore[i]) && !include.contains(className)) {        
            return bytes;
        }
    }
    
  3. 修正了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. 最后,在HelloWorld类中,我创建了一个BigDecimal来检查操作行为。

  5. 输出如下所示:

    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
    

    我希望它有所帮助。如果没有,请添加您要执行的操作的更多详细信息。

相关问题