I'm trying to write a small tool which adds 'exc.printStackTrace()' to each
exception handler which doesn't has one. Here's what I got so far:
import org.apache.bcel.*;
import org.apache.bcel.classfile.*;
import org.apache.bcel.generic.*;
public class AddExceptionStacktrace{
static void process(String fn) throws Exception{
JavaClass jc = new ClassParser(fn).parse();
ConstantPool cp = jc.getConstantPool();
ConstantPoolGen cpg = new ConstantPoolGen(cp);
InstructionFactory factory = new InstructionFactory(cpg);
Method[] methods = jc.getMethods();
for (int i=0; i<methods.length; i++){
Method method = methods[i];
if (!method.isAbstract() && !method.isNative()){
System.out.println(method);
MethodGen mg = new MethodGen(method,jc.getClassName(),cpg);
InstructionList il = mg.getInstructionList();
boolean mChanged = false;
CodeExceptionGen[] cegs = mg.getExceptionHandlers();
for (int j=0; j<cegs.length; j++){
CodeExceptionGen ceg = cegs[j];
System.out.println(" "+ceg.getCatchType());
InstructionHandle ih = ceg.getHandlerPC();
Instruction instr = ih.getInstruction();
if (instr instanceof ASTORE){
InstructionList ilNew = new InstructionList();
ilNew.append(new ALOAD(((ASTORE)instr).getIndex()));
ilNew.append(factory.createInvoke("java.lang.Throwable"
,"printStackTrace"
,Type.VOID
,Type.NO_ARGS
,Constants.INVOKESPECIAL));
il.append(ih,ilNew);
mChanged = true;
System.out.println(ih);
}//if
}//for
if (mChanged){
methods[i] = mg.getMethod();
break;
}//if
}//if
}//for
jc.setConstantPool(cpg.getFinalConstantPool());
jc.dump(fn+".mod");
}//process
public static void main(String[] args){
try{
for (int i=0; i<args.length; i++){
process(args[i]);
}//for
}catch(Exception ex){
ex.printStackTrace();
System.exit(1);
}//catch
}//main
}//class AddExceptionStacktrace
It works so far, but when I apply it against something like
public class Target{
static void m1(){
try{
System.out.println("test1");
}catch(Exception ex){
System.out.println("def");
}//catch
System.out.println("abc");
}//m1
public static void main(String[] args){
m1();
}//main
}//class Target
and I try to execute Target, I get a message
Exception in thread "main" java.lang.VerifyError: (class:
com/cisco/nm/tools/transposer/Target, method: m1 signature: ()V) Illegal use of
nonvirtual function call
The Javap for the Target class says
Compiled from Target.java
public class com.cisco.nm.tools.transposer.Target extends java.lang.Object {
public com.cisco.nm.tools.transposer.Target();
static void m1();
public static void main(java.lang.String[]);
}
Method com.cisco.nm.tools.transposer.Target()
0 aload_0
1 invokespecial #1 <Method java.lang.Object()>
4 return
Method void m1()
0 getstatic #2 <Field java.io.PrintStream out>
3 ldc #3 <String "test1">
5 invokevirtual #4 <Method void println(java.lang.String)>
8 goto 24
11 astore_0
12 aload_0
13 invokespecial #49 <Method void printStackTrace()>
16 getstatic #2 <Field java.io.PrintStream out>
19 ldc #6 <String "def">
21 invokevirtual #4 <Method void println(java.lang.String)>
24 getstatic #2 <Field java.io.PrintStream out>
27 ldc #7 <String "abc">
29 invokevirtual #4 <Method void println(java.lang.String)>
32 return
Exception table:
from to target type
0 8 11 <Class java.lang.Exception>
Method void main(java.lang.String[])
0 invokestatic #8 <Method void m1()>
3 return
I'm clearly missing something -- but what is it?
Regards,
-Max
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>