Rafael Aguilar Rafael Aguilar - 1 year ago 84
Java Question

How to obtain exception message to log it on catch blocks on already existing class with Javassist?

Case:



Try to insert a log method with a String parameter, in this case, with
e.getMessage()
on any catch Block of existing method.

The following snippets can inject a String.

...
CtMethod log = CtNewMethod.make("public void log(String s){ " +
" System.out.println(\"Hello from injected log method \" + s); " +
"}",
ct);
ct.addMethod(log);

...
ControlFlow cf = new ControlFlow(m);
Block blocks[] = cf.basicBlocks();
for(Block block : blocks){
Catcher catchers[] = block.catchers();
ArrayList<Catcher> catchersList = new ArrayList<Catcher>(Arrays.asList(catchers));
Collections.reverse(catchersList);
for (Catcher catcher : catchersList){
Block catchBlock = catcher.block();
int pos = catchBlock.position();

CodeIterator itr = m.getMethodInfo().getCodeAttribute().iterator();

Bytecode code = new Bytecode(m.getMethodInfo().getConstPool(), 0, 0);

code.addAload(0);
code.addLdc("LogParameter");
code.addInvokevirtual(ct,"log",log.getMethodInfo().getDescriptor());
code.addGap(2);
int n = itr.insertAt(pos,code.get());

m.getMethodInfo().rebuildStackMapForME(cp);
}
}


Problem



What i can't do is to get the
e.getMessage()
as input parameter to
log(String)
.

Maybe someone could point me in the right direction.

Answer Source

When you enter a catch block, you will find the exception lying on the stack. Thus, you can extract the message as follows:

  • duplicate the topmost value of the stack which is the exception such that you can call methods of this object without taking away the value for deeper instructions.

  • extract the message from the exception object by calling getMessage virtually on it.

This way, you now have the exception message lying on top of the stack.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download