Search code examples
try-catchbytecodejavassist

Javassist: insert a method at the beginning of catch block


I have code:

ControlFlow cf = new ControlFlow(method);

for (ControlFlow.Block block : cf.basicBlocks()) {
   ControlFlow.Catcher catchBlocks[] = block.catchers();
   for (int i = 0;i < catchBlocks.length;i++) {
      int position = catchBlocks[i].block().position();
      method.insertAt(position, "System.out.println(\"catch block\")")
   }    
}

This code snippet inserts the print statement at beginning of the method, which is not what I want. I want the code to be placed like:

void foo() {
    try {
        a();
    } catch(Exception e) {
        System.out.println("catch block");//inserted by javassist
        b();
    }
}

Any idea where my code got wrong?


A more elegant way to handle it

 CtBehavior.instrument(new ExprEditor() {
            @Override
            public void edit(Handler h) throws CannotCompileException {
                if( !h.isFinally()) {
                    h.insertBefore("System.out.println(\"catch block\")");
                }
            }
        });

Ref: http://www.javassist.org/tutorial/tutorial2.html#intro


Solution

  • You should try to get the line number in the source code of the block you are looking for.

    Try with something like this:

    ControlFlow cf = new ControlFlow(method);
    
    for (ControlFlow.Block block : cf.basicBlocks()) {
       ControlFlow.Catcher catchBlocks[] = block.catchers();
       for (int i = 0;i < catchBlocks.length;i++) {
          int position = catchBlocks[i].block().position();
          // Get source code line position 
          int lineNumber = method.getMethodInfo().getLineNumber(position ); 
          method.insertAt(lineNumber+1 , "System.out.println(\"catch block\")")
       }    
    }