Community
Participate
Working Groups
After upgrading from AspectJ 1.7.2 (Spring EBR osgi bundle) to 1.8.7 (Apache ServiceMix osgi bundle) in our OSGI environment, we started seeing VerifyErrors like these for load-time woven classes: HttpServiceContext{httpContext=our.paclage.BundleHttpContext@5552fc77}: java.lang.VerifyError: Expecting a stackmap frame at branch target 63|Exception Details:| Location:| our/package/OurResource.<init>()V @23: ifnull| Reason:| Expected stackmap frame at this location.| Bytecode:| 0x0000000: 2ab7 0001 b200 c62a 2ab8 009c 4db2 0096| 0x0000010: 2a2a b800 9c4c 2ac6 0028 2ab6 00ac 12ae| 0x0000020: b600 bc99 001c 2ab6 00ac 12ae b600 b4c0| 0x0000030: 00ae b800 b899 000a b800 a22a b600 a800| 0x0000040: 2ac6 0021 2ab6 00ac 12ae b600 bc99 0015| 0x0000050: 2ab6 00ac 12ae b600 b4c0 00ae b800 b89a| 0x0000060: 0021 2ac6 001d 2ab6 00ac 12ae b600 bc99| 0x0000070: 0011 2bb8 00c3 9900 0ab8 00a2 2ab6 00bf| 0x0000080: 00a7 0003 2ab6 00ac 12ae b600 b4c0 00ae| 0x0000090: b800 b89a 0011 2cb8 00c3 9900 0ab8 00a2| 0x00000a0: 2ab6 00bf b1 | java.lang.VerifyError: Expecting a stackmap frame at branch target 63|Exception Details:| Location:| our/package/OurResource.<init>()V @23: ifnull| Reason:| Expected stackmap frame at this location.| Bytecode:| 0x0000000: 2ab7 0001 b200 c62a 2ab8 009c 4db2 0096| 0x0000010: 2a2a b800 9c4c 2ac6 0028 2ab6 00ac 12ae| 0x0000020: b600 bc99 001c 2ab6 00ac 12ae b600 b4c0| 0x0000030: 00ae b800 b899 000a b800 a22a b600 a800| 0x0000040: 2ac6 0021 2ab6 00ac 12ae b600 bc99 0015| 0x0000050: 2ab6 00ac 12ae b600 b4c0 00ae b800 b89a| 0x0000060: 0021 2ac6 001d 2ab6 00ac 12ae b600 bc99| 0x0000070: 0011 2bb8 00c3 9900 0ab8 00a2 2ab6 00bf| 0x0000080: 00a7 0003 2ab6 00ac 12ae b600 b4c0 00ae| 0x0000090: b800 b89a 0011 2cb8 00c3 9900 0ab8 00a2| 0x00000a0: 2ab6 00bf b1 | at java.lang.Class.getDeclaredConstructors0(Native Method) ... Investigation of the woven bytecode in _ajdump revealed that the woven classes were indeed missing their StackMapTables. After much searching, we found out that the root cause was the fact that the ServiceMix bundle did not include the renamed ASM library (aj.org.objectweb.asm.* packages). We logged a bug for this here: https://issues.apache.org/jira/browse/SM-2744 It took us a long time to find this, because instead of throwing an Exception (ClassNotFoundException or similar), AspectJ simply decides to not generate StackMapTables, thus generating bytecode that is completely invalid for Java 1.7 or higher. The relevant code snippets: org.aspectj.weaver.bcel.LazyClassGen: if (((myGen.getMajor() == Constants.MAJOR_1_6 && world.shouldGenerateStackMaps()) || myGen.getMajor() > Constants.MAJOR_1_6) && AsmDetector.isAsmAround) { wovenClassFileData = StackMapAdder.addStackMaps(world, wovenClassFileData); } org.aspectj.weaver.bcel.asm.AsmDetector: public class AsmDetector { public static boolean isAsmAround; static { try { Class<?> reader = Class.forName("aj.org.objectweb.asm.ClassReader"); Class<?> visitor = Class.forName("aj.org.objectweb.asm.ClassVisitor"); Method m = reader.getMethod("accept", new Class[] { visitor, Integer.TYPE }); isAsmAround = m != null; } catch (Exception e) { isAsmAround = false; } // System.out.println(isAsmAround?"ASM detected":"No ASM found"); } } As far as I can see, The LazyClassGen class should throw an Exception if myGen.getMajor() > Constants.MAJOR_1_6 && !AsmDetector.isAsmAround Also, I think AsmDetector could be more lenient and also accept a regular (non-included) ASM. If I've seen correctly, the aj-prefixed inlined version is simply a renamed copy of ASM 5.0.4, so using the regular ASM should work. I'm also not sure why this ASM needs to be renamed and embedded in the first place, but there is probably a reason that I'm not aware of.
I agree the error reporting should be better there. That code hasn't been touched for a long time and 1.7 or greater is now the norm rather than the unusual case. However, i'm leaning to keeping the embedded asm - it is very small and depending on whatever we find in the environment may not discover a version that is compatible. This version has been through all the AspectJ tests to verify it does the right thing. For error reports that come in I know what everyone must be running.
Exception will now be thrown if asm is missing.
Thanks for that quick reaction, that commit looks like it should fix it, I'll check tomorrow. Hopefully the ServiceMix guys will also change their bundle, but for now our problem is solved by inlining the aj.org.objectweb.asm packages in our own osgi bundle. Finding out what was wrong was most of the battle, and your commit will make that much easier for others. Any idea on when you'll be releasing 1.8.8?