Community
Participate
Working Groups
I am attempting to use AspectJ and output all classes in debug mode (required by our code coverage instrumentor). However any code introduced by our aspects to production classes does not include debug line information. Our ant script uses the iajc task as follows: <iajc ... debug="true" .. /> We have an aspect that introduces a public, no-arguments constructor into various classes. If I enable this aspect, then do a clean build, I get the following error from our code coverage tool: [jblanket] java.lang.UnsupportedOperationException: No line numbers detected in com.abmuk.oms.core.model.core.XMLObject.<init>. Either remove the 'oneLineFile' tag or turn debug on when compiling. If I remove that aspect, we get no errors about debug line information. I've tried debug="true" or debugLevel="lines,vars,source", with no success. This issue is preventing our Unit Test suite from executing. If you require any further information, please don't hesitate to email me. Cheers, Chris Nappin.
We don't currently create line number information for members created in a target type to support ITDs. The reason is that the methods/ctors added to the target type are simply forwarding methods that delegate to the aspect to execute the intended behavior. Here is a decompiled class that had a method and ctor ITD'd upon it: public A(); Code: Stack=1, Locals=2, Args_size=1 0: invokestatic #30; //Method X.ajc$preInterConstructor$X$A:()[Ljava/lang/Object; 3: astore_1 4: aload_0 5: invokespecial #11; //Method java/lang/Object."<init>":()V 8: aload_0 9: invokestatic #33; //Method X.ajc$postInterConstructor$X$A:(LA;)V 12: return public void sayhi(); Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1: invokestatic #25; //Method X.ajc$interMethod$X$A$sayhi:(LA;)V 4: return You can see in each case the body of the member in the class simply forwards the request to an ajc$XXX method in the aspect (called X in this case). So, any line number information we did add to the members added to a class for ITDs would be 'fake' - as it wouldn't refer to anything that really existed in the source file for the class. However, we can do this - there is a precedent in that we already do create fake line number tables for methods to support inlined around advice. I'm just not sure that I want to create too much 'fake' information in everything the weaver creates just to support this use case - I think we'd get a lot of push back about unnecessary code bloat. But I'm keen to help you if we can - I'm currently right in the midst of our debug support so you raised this bug at the right time :) Is there no way the tool can be tailored to be a little less strict on what should have debug info attached? After all, coverage information for these delegator methods would simply be measuring coverage of AspectJ 'generated' code - coverage of the actual body of the ctor would count when the delegated ctor (in the aspect) was executed. Andy.
Thanks for looking into this so quickly! I'm not sure about your comment on code bloat, if compiling classes in debug mode then I'd certainly expect to get larger class files? I will try to see if I can get the coverage tool we're using (JBlanket) to side-step these constructors as a special case. I couldn't get it to ignore methods previously, although it should be able to, and I'm not sure it supports ignoring constructors. It may be that we have to move to a different coverage tool, but I believe a lot of them instrument code in a very similar way, using classes built in debug mode, and the CGLIB or bcel libraries. Chris.
Hi, I've had a play with JBlanket's exclusion mechanism and unfortunately it seems to work by filtering the results, rather than reducing which blocks of code it adds instrumentation to. I imagine that other tools work in a similar way. Is there any possibility that AspectJ can be updated to honour the "debug" flag for introduced code? Chris.
I've just tried a comparable case that occurs in pure java - to see what happens for generated code like this. Here is a simple program: public class Test { private int i; private class Inner { public void aMethod() { System.err.println(i); } } } So that 'Inner' can see 'i', an accessor method for it is generated when you compile this program, on javap -verbose I see this: public Test(); Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1: invokespecial #2; //Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0 line 6: 4 static int access$000(Test); Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1: getfield #1; //Field i:I 4: ireturn LineNumberTable: line 1: 0 Synthetic: true } So, there is a line number table with just one entry in for the generated method (and it is marked synthetic) - I guess we should do the same for AspectJ generated methods !
Fix checked in - we add a single line number table entry if one does not exist for the generated methods. This adds 12bytes per method that previously didn't have a table. Creation of it could be made conditional on the value of the -g: flag - but after some minimal testing we don't seem to respect -g:none correctly so I'm leaving someone else to fix that in a separate bug. I've not added extra logic to add extra synthetic markers here and there - it doesn't seem necessary to ensure the tests pass, but I hope debuggers don't start having problems with these unusual tables around. Waiting for build ...
BUILD COMPLETE - build.439 Date of build: 01/19/2005 11:53:40 Time to build: 112 minutes 16 seconds Last changed: 01/19/2005 09:36:48 Last log entry: Fix for Bug 82570: Weaved code does not include debug lines Latest good AspectJ jar available at: download.eclipse.org/technology/ajdt/dev/aspectj-DEVELOPMENT.jar
Hi, I'm now trying again to introduce AspectJ into our project, but am hitting against this same issue again. I'm now using AspectJ 1.5.0, JDK 1.4.2 and Windows XP. This time I have one simple Aspect that has a single "around" advice added to various classes in our project. I'm compiling using iajc with debug set to "true", but I get the following error from JBlanket: [jblanket] java.lang.UnsupportedOperationException: No line numbers detected in com.abmuk.oms.core.common.logging.Timer.ajc$around$com_abmuk_oms_core_common_lo gging_Timer$1$e548cc5bproceed. Either remove the 'oneLineFile' tag or turn debug on when compiling. [jblanket] at csdl.jblanket.modifier.MethodModifier.processMethod(MethodMod ifier.java:121) [jblanket] at csdl.jblanket.modifier.ClassModifier.modifyMethods(ClassModif ier.java:123) [jblanket] at csdl.jblanket.modifier.Modifier.processIncludeClasses(Modifie r.java:282) [jblanket] at csdl.jblanket.modifier.Modifier.modify(Modifier.java:520) [jblanket] at csdl.jblanket.modifier.Modifier.main(Modifier.java:662) [jblanket] at csdl.jblanket.ant.JBlanketModifierTask.execute(JBlanketModifi erTask.java:366)
you could try compiling with -XnoInline to see if that helps...
Thanks for the suggestion. Unfortunately this has no affect, I still get the same error about missing line numbers: [jblanket] java.lang.UnsupportedOperationException: No line numbers detected in com.abmuk.oms.core.common.logging.Timer.ajc$around$com_abmuk_oms_core_common_lo gging_Timer$1$e548cc5bproceed. Either remove the 'oneLineFile' tag or turn debug on when compiling. [jblanket] at csdl.jblanket.modifier.MethodModifier.processMethod(MethodMod ifier.java:121) ... To clarify, the ant entry I'm using is as follows: <iajc sourceroots="${core.java}" destdir="${build.classes}" deprecation="true" debug="true" xlintwarnings="true" classpathref="build.path" source="1.4" target="1.4" x="noInline"/>
Hi, I've just re-tested with AspectJ 1.5.1a and unfortunately the fault is still present. Is there any chance the priority of this issue can be increased? At the moment it means that none of the code executed in a Unit test environment can include any AOP code. Thanks, Chris.
let me give it some kind of priority for 1.5.2 ... not sure what I'll do for it yet tho: - adding line number info for generated code is a bogus as the code never existed in source.... - adding synthetic attribute to the code may be something we have to look into again, or ... maybe the bridge flag makes sense actually for some of these ... - asking jblanket to respect the ajsynthetic attribute in addition to the synthetic attribute would be another option...
Hi, thanks for considering to resolve this issue. > - adding line number info for generated code is a bogus as the code > never existed in source.... I thought the result of your investigation on the Sun javac compiler (comment #4 below) was that it generates "bogus" line numbers if in debug mode, and aspectj should merely do the same? > - asking jblanket to respect the ajsynthetic attribute in addition to the > synthetic attribute would be another option... I have tried out a few other Code Coverage tools and they also suffer from the same problem. Rather than changing every code coverage tool on the market it might be easier to change aspectj? If you require any further info to help you out, please just let me know. Thanks, Chris Nappin.
I just committed a change to add blank line number tables for the XXXproceed() method you are hitting and aspectOf/hasAspect methods - we should investigate proper use of synthetic but this is a suitable temporary workaround as we dont have the time to do that investigation right now. When the dev build is available I will close this bug report.
dev build is available with the proposed changes in. There may be other methods that exhibit this problem .. please reopen this if you come across them.
Thanks, downloading the latest development build that seems to have resolved all our use of Aspects so far. Do you know when the 1.5.2 release is expected to be available?
from our plans page : http://www.eclipse.org/aspectj/plans.php we are looking at end of June 2006 for 1.5.2