You need to traverse your class and use a modified MethodVisitor
in the process. If you wrap your entire method in a try
-catch
construct. You can do so by inserting the construct by intercepting the callbacks for the start and the end of the call block. These methods are visitCode
and visitEnd
which you could intercept like this:
class MyMethodVisitor extends MethodVisitor {
// constructor omitted
private final Label start = new Label(),
end = new Label(),
handler = new Label();
@Override
public void visitCode() {
super.visitCode();
visitTryCatchBlock(start,
end,
handler,
"java/lang/Exception");
visitLabel(start);
}
@Override
public void visitEnd() {
visitJumpInsn(GOTO, end);
visitLabel(handler);
visitMethodInsn(INVOKEVIRTUAL,
"java/lang/RuntimeException",
"printStackTrace",
"()V");
visitInsn(RETURN);
visitLabel(lCatchBlockEnd);
super.visitEnd();
}
}
However, note that this example does not include stack map frames which you need to add if you produce byte code for Java 7+.
Do however note that this solution will register a dominant handler at the beginning of your method's exception table which override all other try-catch-finally blocks in your method that are already present!
Note: In newer versions of ASM, the code for the handler would need to be written in the method visitMaxs(int, int) instead:
@Override
public void visitMaxs(int maxStack, int maxLocals) {
// visit the corresponding instructions
super.visitMaxs(maxStack, maxLocals);
}
This is because labels and instructions can only be visited before visitMaxs
, and visitMaxs
before visitEnd
, therefore producing code in visitEnd
will result in an error.