Can I instrument CodeConverter at runtime?
dodomio Dec 15, 2006 11:09 AMHi everybody,
I'm trying to modify a method of my custom CodeConverter at runtime, as the instrumentation is based on the content of a configuration file. I'm stuck at the error You can see below.
Actually I wrote this:
public class Main { public static void main(String[] args) throws Throwable { ClassPool cp = ClassPool.getDefault(); Loader loader = new Loader(Main.class.getClassLoader(),cp); // Get the class and instrument CtClass conv = cp.get("pkg.CustomConverter"); CtMethod m = conv.getDeclaredMethod("init"); StringBuffer sb = new StringBuffer(); sb.append("{\n"); sb.append("CtMethod m1 = thePool.get(\"pkg.Hello\").getDeclaredMethod(\"say\");\n"); sb.append("CtMethod m2 = thePool.get(\"pkg.Hello\").getDeclaredMethod(\"first\");\n"); sb.append("insertBeforeMethod(m1, m2);\n"); sb.append("}\n"); m.setBody(sb.toString()); // (*) Here I got the error shown below CustomConverter conv = (CustomConverter) conv.toClass().newInstance(); CustXlator xlat = new CustXlator(conv); loader.addTranslator(cp, xlat); loader.run(args); // Loads and runs the class pkg.Hello } }
CustXlator's onLoad method does simply:
if (className.equals("pkg.Hello")) { CtClass c = pool.get(className); c.instrument(converter); // converter is an instance of CustomConverter passed as // the only parameter to CustXlat constructor }
while CustomConverter has only the init method that I'm trying to instrument.
I'm stuck at an exception occourring during setBody execution. The stacktrace is:
javassist.CannotCompileException: [source error] no such class: CtMethod at javassist.CtBehavior.setBody(CtBehavior.java:346) at javassist.CtBehavior.setBody(CtBehavior.java:315) at pkg.Main.main(Main.java:29) Caused by: compile error: no such class: CtMethod at javassist.compiler.MemberResolver.searchImports(MemberResolver.java:416) at javassist.compiler.MemberResolver.lookupClass(MemberResolver.java:392) at javassist.compiler.MemberResolver.lookupClassByJvmName(MemberResolver.java:310) at javassist.compiler.MemberResolver.resolveJvmClassName(MemberResolver.java:460) at javassist.compiler.MemberCodeGen.resolveClassName(MemberCodeGen.java:1064) at javassist.compiler.CodeGen.atDeclarator(CodeGen.java:698) at javassist.compiler.ast.Declarator.accept(Declarator.java:99) at javassist.compiler.CodeGen.atStmnt(CodeGen.java:344) at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49) at javassist.compiler.CodeGen.atStmnt(CodeGen.java:344) at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49) at javassist.compiler.CodeGen.atMethodBody(CodeGen.java:285) at javassist.compiler.Javac.compileBody(Javac.java:212) at javassist.CtBehavior.setBody(CtBehavior.java:340) ... 2 more
It seems that CustomConverter was unable to resolve CtMethod class!!!
But if I statically modify the init method all is ok.
I really don't know how to solve the problem.
Can someone help me? I'll appreciate it very much!
Thanks in advance, Mauro.