1 Reply Latest reply on Jan 1, 2007 11:01 PM by Lee Hualiang

    Can I instrument CodeConverter at runtime?

    Mauro Iorio Newbie

      Hi 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.