Hi,
I use Javassist to manually add a exception table entry:
MethodInfo minfo = (MethodInfo) aclasscf.getMethods().get(0); CodeAttribute ca = minfo.getCodeAttribute(); ExceptionTable et = ca.getExceptionTable(); et.add(26, 30, 40, 0); System.out.println("exception table size: " + et.size());
If I get the bytecode with javap it seems to work:
But the problem is that I can't run the file anymore. Simply running it with the java command results in "java.lang.VerifyError: Expecting a stackmap frame at branch target 13". After some research this seems to be a problem with java 7 and a stricter verifier. I read several times that java -XX:-UseSplitVerifier should be used instead.Exception Table from to target type 26 30 40 any
This really fixed the stackmap error, but then another error appeared: "java.lang.VerifyError: (class: AClass, method: signature: ()V) Inconsistent stack height 0 != 1". Are there any further steps required to insert a new exception in the exception table?
Additional info: Later I want to remove gotos (in this case the goto at line 27) and add a function call instead. When this function finishes it will throw a exception and propagate it back to the caller (which will be at line 27). Then the program should go on as if nothing happend, that is also the reason why the target of the exception is the same as the target of the goto (40)
EDIT:
I just found out that I have to use the absolute address for the exception table entrys target. (=40)
Changed that everywhere in the post and also added the bytecode after the inserted exception table.
Here is the bytecode before inserting the exception table entry:
0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V 4: iconst_0 5: istore_1 6: goto 19 9: getstatic #10 // Field java/lang/System.out:Ljava/io/PrintStream; 12: iload_1 13: invokevirtual #16 // Method java/io/PrintStream.println:(I)V 16: iinc 1, 1 19: iload_1 20: bipush 20 22: if_icmplt 9 25: iconst_1 26: istore_1 27: goto 40 30: getstatic #10 // Field java/lang/System.out:Ljava/io/PrintStream; 33: iload_1 34: invokevirtual #16 // Method java/io/PrintStream.println:(I)V 37: iinc 1, 1 40: iload_1 41: bipush 20 43: if_icmplt 30 46: return
Here is the bytecode afert inserting the exception table entry:
0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V 4: iconst_0 5: istore_1 6: goto 19 9: getstatic #10 // Field java/lang/System.out:Ljava/io/PrintStream; 12: iload_1 13: invokevirtual #16 // Method java/io/PrintStream.println:(I)V 16: iinc 1, 1 19: iload_1 20: bipush 20 22: if_icmplt 9 25: iconst_1 26: istore_1 27: goto 40 30: getstatic #10 // Field java/lang/System.out:Ljava/io/PrintStream; 33: iload_1 34: invokevirtual #16 // Method java/io/PrintStream.println:(I)V 37: iinc 1, 1 40: iload_1 41: bipush 20 43: if_icmplt 30 46: return Exception table: from to target type 26 30 40 any