Community
Participate
Working Groups
This problem may only occur when Aspect/J tries to do a weaveAroundInline() on an instruction list that includes a Select. Our usage of Aspect/J only rarely causes it to use weaveAroundInline(), so I don't have any other cases for comparison. In ShadowRange:extractInstructionsInto(), my instruction list includes a Select. Each of the targets of the Select has a list of targetters that includes what appears to be a Select from some other instantiation of the instruction list, in addition to the local Select. The updateTarget() call on the bogus Select targetter causes the ClassGenException (stack trace attached below). My clumsy band-aid (also attached below) is to clean the bad state from the Select targets at the top of extractInstructionsInto(). However, I presume that the real fix needs to be done at the point the bad state was introduced into the instruction list. I noticed that a possibly similar problem was reported awhile back, but apparently not in a reliably reproducible way. From browsing through the top of the CVS tree, it appears that the weaver/bcel directory hasn't changed drastically since 1.2, so I assume that this problem may still be lurking there. Here's the stack trace: AspectJInstrumenter:weaveClass,org.apache.bcel.generic.ClassGenException: Not targeting 36: aload_0[42](1) AspectJInstrumenter:weaveClass, at org.apache.bcel.generic.Select.updateTarget(Select.java:213) AspectJInstrumenter:weaveClass, at org.aspectj.weaver.bcel.ShadowRange.extractInstructionsInto (ShadowRange.java:138) AspectJInstrumenter:weaveClass, at org.aspectj.weaver.bcel.BcelShadow.extractMethod(BcelShadow.java:2002) AspectJInstrumenter:weaveClass, at org.aspectj.weaver.bcel.BcelShadow.weaveAroundInline(BcelShadow.java:1436) AspectJInstrumenter:weaveClass, at org.aspectj.weaver.bcel.BcelAdvice.implementOn(BcelAdvice.java:151) AspectJInstrumenter:weaveClass, at org.aspectj.weaver.Shadow.implementMungers(Shadow.java:353) AspectJInstrumenter:weaveClass, at org.aspectj.weaver.Shadow.implement(Shadow.java:325) AspectJInstrumenter:weaveClass, at org.aspectj.weaver.bcel.BcelClassWeaver.implement(BcelClassWeaver.java:1161) AspectJInstrumenter:weaveClass, at org.aspectj.weaver.bcel.BcelClassWeaver.weave(BcelClassWeaver.java:367) AspectJInstrumenter:weaveClass, at org.aspectj.weaver.bcel.BcelClassWeaver.weave(BcelClassWeaver.java:80) AspectJInstrumenter:weaveClass, at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:724) AspectJInstrumenter:weaveClass, at org.aspectj.weaver.bcel.BcelWeaver.weaveWithoutDump(BcelWeaver.java:689) AspectJInstrumenter:weaveClass, at org.aspectj.weaver.bcel.BcelWeaver.weaveAndNotify(BcelWeaver.java:615) AspectJInstrumenter:weaveClass, at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:563) AspectJInstrumenter:weaveClass, at com.acsera.javaagent.AspectJWeavingAdaptor.getWovenBytes (AspectJWeavingAdaptor.java:244) AspectJInstrumenter:weaveClass, at com.acsera.javaagent.AspectJWeavingAdaptor.weaveClass (AspectJWeavingAdaptor.java:210) And here's the patch: void extractInstructionsInto(LazyMethodGen freshMethod, IntMap remap, boolean addReturn) { // XXX Darren // Find all the Select instructions in this list, and all of their targets. // Run through the targets and remove any Select targeters that aren't from this list. java.util.Set selectSet = new java.util.HashSet(); java.util.Set targetSet = new java.util.HashSet(); for ( InstructionHandle ih = start.getNext(); ih != end; ih = ih.getNext() ) { Instruction ii = ih.getInstruction(); if ( ii instanceof Select ) { Select si = (Select) ii; selectSet.add( si ); targetSet.add( si.getTarget() ); InstructionHandle[] targets = si.getTargets(); for ( int k = 0; k < targets.length; k++ ) { targetSet.add( targets[ k ] ); } } } java.util.Iterator it = targetSet.iterator(); while ( it.hasNext() ) { InstructionHandle ih = (InstructionHandle) it.next(); InstructionTargeter[] its = ih.getTargeters(); if ( its == null ) { continue; // XXX internal consistency error? } for ( int k = 0; k < its.length; k++ ) { if ( its[k] instanceof Select ) { Select si = (Select) its[k]; if ( ! selectSet.contains( si ) ) { // XXX System.out.println ( "ShadowRange:extractInstructionsInto: bogus Select " + si.toString() + " " + si.hashCode() ); ih.removeTargeter( si ); } } } } // XXX Darren
for M4 investigation
Is there any way you can supply a program that exhibits the incorrect behaviour when weaving? I'm trying to hack some up myself but can't get it to fail. I did change some Select related stuff recently in BCEL for another bug - I've no idea if it will affect this situation though. I'd like to have a test program before making a change like this. If you can't supply the program, can you at least tell me the pointcut/advice declaration involved? so I can continue trying to recreate. thanks.
We'd like to fix this for 1.5.0 - but don't want to make a change without being able to reproduce first. Do you have a test program that reproduces this we you could append please? Thanks.
Hmmm - as I re-read this bug this morning, I remember something in my murky past where I fixed something possibly related. Given that this was raised against 1.2, take a look at bug 104720 - that was a problem in bcel to do with extracting instructions containing a select. The problem there did manifest at runtime, rather than compile time as discussed in this bug, but it looks a similar problem to do with the targets getting messed up. "Exception in thread "main" java.lang.VerifyError: (class: Test, method:" "newTest_aroundBody2 signature: (I)LTest;) Illegal default target in switch" Can you possibly retry the failing scenario with a build of AspectJ 5?
not seen on 1.5 ... delaying for investigation in 1.5.1
bug not seen in the last few months - presumed fixed. please reopen if you see it again.