Community
Participate
Working Groups
We have had a user report a problem where after advice being woven into a particular method is producing code that does not verify. The problem occurs if the bytecode being input to the weaving process includes a subroutine that contains the return from the method. Here is the problematic snippet produced by some unknown compiler: 200: invokespecial #17; //Method com/MyException."<init>":(Ljava/lang/String;)V 203: athrow 204: aload_3 205: astore 6 207: jsr 234 210: aload 6 212: areturn 213: astore 4 215: aload 4 217: invokevirtual #79; //Method java/lang/Throwable.printStackTrace:()V 220: jsr 234 223: goto 238 226: astore 7 228: jsr 234 231: aload 7 233: athrow 234: astore 8 236: aload_3 237: areturn 238: return Exception table: from to target type 2 213 213 Class javax/ejb/FinderException 2 226 226 any see the jsr's jump to 234, but before the subroutine return at 238 there is an areturn out of the method (this method returns a String). After weaving we get something like this: 200: invokespecial #17; //Method com/MyException."<init>":(Ljava/lang/String;)V 203: athrow 204: aload_3 205: astore 6 207: jsr 238 210: aload 6 212: astore 9 214: goto 248 217: astore 4 219: aload 4 221: invokevirtual #79; //Method java/lang/Throwable.printStackTrace:()V 224: jsr 238 227: goto 246 230: astore 7 232: jsr 238 235: aload 7 237: athrow 238: astore 8 240: aload_3 241: astore 9 243: goto 248 246: astore 9 248: invokestatic #299; //Method After.aspectOf:()LAfter; 251: invokevirtual #302; //Method After.ajc$afterReturning$After$1$26d6d4a7:()V 254: aload 9 256: return see how the areturn has been lost - this code will blow up with a verify error (the string is on the stack, we just ignore it and 'return' normally)
the neatest fix here is that when we collect up the returns for a method, if this is a method with a non-void return type we don't try and use 'RETURN' - which is what happens at the moment in BcelShadow. Whilst working on this I discovered a bug where duplicate RETURNs (second is harmless) are inserted in woven code for methods woven with a VOID return value. also fixing that.
fixes committed.
fix available.