我正在尝试使用 javassist 来将 System.out.println 添加到现有类的方法中,使用此代码 -
....
ClassPool pool = new ClassPool();
try {
pool.appendClassPath(targetPath);
CtClass cc = pool.get("model.Ball");
CtMethod[] cm = cc.getDeclaredMethods();
for (CtMethod m : cm) {
String temp = m.getName();
m.insertBefore("{ System.out.println(\"Executed Method \" + temp); }");
}
但是我不断收到此堆栈跟踪:
javassist.CannotCompileException: [source error] no such class: System.out
at javassist.CtBehavior.insertBefore(CtBehavior.java:774)
at javassist.CtBehavior.insertBefore(CtBehavior.java:734)
at reverseEngineer.dynamicparser.DynamicAnalyser.methodInformation(DynamicAnalyser.java:77)
at reverseEngineer.dynamicparser.DynamicAnalyser.loadClass(DynamicAnalyser.java:61)
at reverseEngineer.ModelParser.parseDynamic(ModelParser.java:77)
at reverseEngineer.ModelParser.parseTarget(ModelParser.java:44)
at reverseEngineer.Driver.main(Driver.java:30)
Caused by: compile error: no such class: System.out
at javassist.compiler.MemberResolver.searchImports(MemberResolver.java:468)
at javassist.compiler.MemberResolver.lookupClass(MemberResolver.java:412)
at javassist.compiler.MemberResolver.lookupClassByJvmName(MemberResolver.java:319)
at javassist.compiler.TypeChecker.atCallExpr(TypeChecker.java:678)
at javassist.compiler.JvstTypeChecker.atCallExpr(JvstTypeChecker.java:157)
at javassist.compiler.ast.CallExpr.accept(CallExpr.java:46)
at javassist.compiler.CodeGen.doTypeCheck(CodeGen.java:242)
at javassist.compiler.CodeGen.atStmnt(CodeGen.java:330)
at javassist.compiler.ast.Stmnt.accept(Stmnt.java:50)
at javassist.compiler.CodeGen.atStmnt(CodeGen.java:351)
at javassist.compiler.ast.Stmnt.accept(Stmnt.java:50)
at javassist.compiler.Javac.compileStmnt(Javac.java:569)
at javassist.CtBehavior.insertBefore(CtBehavior.java:754)
... 6 more
我尝试过使用
进行测试
m.insertBefore("{ int x = 1; }");
这工作得很好 - 将 System.out.println() 更改为 System.getcurrenttimemillis() 仅在“没有这样的类:System”时返回相同的堆栈跟踪
您创建 ClassPool 的方式如下:
ClassPool pool = new ClassPool();
这会创建一个空的 ClassPool,甚至不是 rt.jar 中的默认 Java 类。所以没有定义System类,编译失败。
通过使用:
ClassPool pool = new ClassPool(true);
您将获得一个 ClassPool,其中包含已添加的 classPath 和系统 jar 中的内容。找到系统类并进行编译。
我是一名优秀的程序员,十分优秀!