2

我目前正在尝试跟踪用于学习目的的方法调用。

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

你有什么想法如何做到这一点吗?

4

2 回答 2

0

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

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

于 2015-06-19T11:46:20.037 回答
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. 修复了 methodReturnsValueJavassistHelper 的方法,以正确区分方法和构造函数。

    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只是为了检查操作行为。

输出如下所示:

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

我希望它有所帮助。如果没有,请添加更多关于您正在尝试做的事情的详细信息。

于 2015-06-19T23:11:13.690 回答