Community
Participate
Working Groups
AspectJ load-time weaving can add a duplicate copy of ITD's if an ITD affects a base class and a derived class and the derived class is loaded first. This may only affect storage space and programs that use reflection (in a few basic tests, the semantics of the ITDs look ok). Consider the difference between running the following program using Sample as the main class or Derived (in the latter case you get the extra ITD, although the counter is behaving in a similar way: the ITD field on the superclass is just not being used). It would be better to not have this extra state and I'm also nervous that subtle semantics bugs lurk here. public class Sample implements SubMarker { public void print() { for (Class clazz = getClass(); clazz!=null; clazz=clazz.getSuperclass()) { System.out.print("Fields for "+clazz.getName()+":"); for (java.lang.reflect.Field f : clazz.getDeclaredFields()) { System.out.print(" "+f.getName()+"="); f.setAccessible(true); try { System.out.print(f.get(this)); } catch (Exception e) { throw new RuntimeException("failure",e); } } System.out.println(); } } public static void main(String args[]) { test(new Derived()); test(new Sample()); } private static void test(Sample b) { System.out.println("Testing "+b.getClass().getName()); b.foo(); b.print(); b.bar(); } public void foo() {} public void bar() {} } interface Marker {} interface SubMarker extends Marker {} public class Derived extends Sample implements Marker { public void foo() { super.foo(); } } public aspect ItdOnMarker { private static interface Holder {} declare parents: Marker+ && !Holder+ implements Holder; public int Holder.x; before(Holder holder) : execution(public * Holder+.*(..)) && this(holder) { System.out.print(thisJoinPoint+" "+ (++holder.x)); if (holder instanceof Marker) { System.out.print(" & m: "+((Marker)holder).x); } System.out.println(); } } ajc -5.0 -outjar sample.jar Sample.java Derived.java ajc -classpath sample.jar;%CLASSPATH% -outjar itd.jar -outxml ItdOnMarker.aj C:\devel\glassbox\test>java -javaagent:\devel\aspectj\dev\20070129\lib\aspectjwe aver.jar -classpath sample.jar;itd.jar;%CLASSPATH% Derived Testing Derived execution(void Derived.foo()) 1 & m: 1 execution(void Sample.foo()) 2 & m: 2 execution(void Sample.print()) 3 & m: 3 Fields for Derived: ajc$interField$ItdOnMarker$ItdOnMarker$Holder$x=3 ajc$tjp_0= execution(void Derived.foo()) Fields for Sample: ajc$interField$ItdOnMarker$ItdOnMarker$Holder$x=0 ajc$tjp_0=e xecution(void Sample.print()) ajc$tjp_1=execution(void Sample.foo()) ajc$tjp_2=e xecution(void Sample.bar()) Fields for java.lang.Object: execution(void Sample.bar()) 4 & m: 4 Testing Sample execution(void Sample.foo()) 1 & m: 1 execution(void Sample.print()) 2 & m: 2 Fields for Sample: ajc$interField$ItdOnMarker$ItdOnMarker$Holder$x=2 ajc$tjp_0=e xecution(void Sample.print()) ajc$tjp_1=execution(void Sample.foo()) ajc$tjp_2=e xecution(void Sample.bar()) Fields for java.lang.Object: execution(void Sample.bar()) 3 & m: 3 C:\devel\glassbox\test>java -javaagent:\devel\aspectj\dev\20070129\lib\aspectjwe aver.jar -classpath sample.jar;itd.jar;%CLASSPATH% Sample Testing Derived execution(void Derived.foo()) 1 & m: 1 execution(void Sample.foo()) 2 & m: 2 execution(void Sample.print()) 3 & m: 3 Fields for Derived: ajc$tjp_0=execution(void Derived.foo()) Fields for Sample: ajc$interField$ItdOnMarker$ItdOnMarker$Holder$x=3 ajc$tjp_0=e xecution(void Sample.print()) ajc$tjp_1=execution(void Sample.foo()) ajc$tjp_2=e xecution(void Sample.bar()) Fields for java.lang.Object: execution(void Sample.bar()) 4 & m: 4 Testing Sample execution(void Sample.foo()) 1 & m: 1 execution(void Sample.print()) 2 & m: 2 Fields for Sample: ajc$interField$ItdOnMarker$ItdOnMarker$Holder$x=2 ajc$tjp_0=e xecution(void Sample.print()) ajc$tjp_1=execution(void Sample.foo()) ajc$tjp_2=e xecution(void Sample.bar()) Fields for java.lang.Object: execution(void Sample.bar()) 3 & m: 3
raised a while ago, need to determine what the current state of things here is before proceeding
Having a bit of trouble understanding that output. But basically it seems when I compare the output when the bug was raised, if you run Sample: Fields for Derived: ajc$tjp_0=execution(void Derived.foo()) Fields for Sample: ajc$interField$ItdOnMarker$ItdOnMarker$Holder$x=3 And if you run Derived: Fields for Derived: ajc$interField$ItdOnMarker$ItdOnMarker$Holder$x=3 ajc$tjp_0=execution(void Derived.foo()) Fields for Sample: ajc$interField$ItdOnMarker$ItdOnMarker$Holder$x=0 So when running the subtype there are two fields called x. This appears to still happen with AspectJ 1.6.4. Although I'm trimming down the testcase to show the actual problem more clearly... ok, now it is more clear, ignore extraneous jp messages and ajc$tjp fields: F:\workspaces\aspectj16_1\AA\src>java -javaagent:f:\aspectj164-dev\lib\aspectjweaver.jar -classpath "sample.jar;itd.jar;%CLASSPATH%" Derived Testing Derived Fields for Derived: ajc$interField$ItdOnMarker$ItdOnMarker$Holder$x Fields for Sample: ajc$interField$ItdOnMarker$ItdOnMarker$Holder$x Testing Sample Fields for Sample: ajc$interField$ItdOnMarker$ItdOnMarker$Holder$x F:\workspaces\aspectj16_1\AA\src>java -javaagent:f:\aspectj164-dev\lib\aspectjweaver.jar -classpath "sample.jar;itd.jar;%CLASSPATH%" Sample Testing Derived Fields for Derived: Fields for Sample: ajc$interField$ItdOnMarker$ItdOnMarker$Holder$x Testing Sample Fields for Sample: ajc$interField$ItdOnMarker$ItdOnMarker$Holder$x In the case of launching Derived first, it gets the ITD field, as does Sample, the top most implementor. Now try with ltw debugging
ok, I've turned on showWeaveInfo and verbose mode in aop.xml Running Derived: info AspectJ Weaver Version DEVELOPMENT built on Monday Feb 9, 2009 at 19:43:46 GMT info register classloader sun.misc.Launcher$AppClassLoader@1f12c4e info using configuration file:/F:/workspaces/aspectj16_1/AA/src/itd.jar!/META-INF/aop-ajc.xml info using configuration /F:/workspaces/aspectj16_1/AA/src/META-INF/aop-ajc.xml info register aspect ItdOnMarker info register aspect ItdOnMarker weaveinfo Extending interface set for type 'Derived' (Derived.java) to include 'ItdOnMarker$Holder' (ItdOnMarker.java) weaveinfo Type 'Derived' (Derived.java) has intertyped field from 'ItdOnMarker' (ItdOnMarker.java:'int ItdOnMarker$Holder.x') weaveinfo Join point 'method-execution(void Derived.foo())' in Type 'Derived' (Derived.java:2) advised by before advice from 'ItdOnMarker' (ItdOnMarker.java:7) weaveinfo Extending interface set for type 'Marker' (Marker.java) to include 'ItdOnMarker$Holder' (ItdOnMarker.java) info processing reweavable type ItdOnMarker$Holder: \ItdOnMarker.java info successfully verified type ItdOnMarker exists. Originates from F:\workspaces\aspectj16_1\AA\src\ItdOnMarker.java weaveinfo Type 'ItdOnMarker$Holder' (ItdOnMarker.java) has intertyped field from 'ItdOnMarker' (ItdOnMarker.java:'int ItdOnMarker$Holder.x') weaveinfo Type 'Sample' (Sample.java) has intertyped field from 'ItdOnMarker' (ItdOnMarker.java:'int ItdOnMarker$Holder.x') weaveinfo Join point 'method-execution(void Sample.print())' in Type 'Sample' (Sample.java:3) advised by before advice from 'ItdOnMarker' (ItdOnMarker.java:7) weaveinfo Join point 'method-execution(void Sample.foo())' in Type 'Sample' (Sample.java:28) advised by before advice from 'ItdOnMarker' (ItdOnMarker.java:7) weaveinfo Join point 'method-execution(void Sample.bar())' in Type 'Sample' (Sample.java:31) advised by before advice from 'ItdOnMarker' (ItdOnMarker.java:7) info processing reweavable type ItdOnMarker: \ItdOnMarker.java Testing Derived Fields for Derived: ajc$interField$ItdOnMarker$ItdOnMarker$Holder$x Fields for Sample: ajc$interField$ItdOnMarker$ItdOnMarker$Holder$x Testing Sample Fields for Sample: ajc$interField$ItdOnMarker$ItdOnMarker$Holder$x Running Sample: info AspectJ Weaver Version DEVELOPMENT built on Monday Feb 9, 2009 at 19:43:46 GMT info register classloader sun.misc.Launcher$AppClassLoader@1f12c4e info using configuration file:/F:/workspaces/aspectj16_1/AA/src/itd.jar!/META-INF/aop-ajc.xml info using configuration /F:/workspaces/aspectj16_1/AA/src/META-INF/aop-ajc.xml info register aspect ItdOnMarker info register aspect ItdOnMarker weaveinfo Extending interface set for type 'Sample' (Sample.java) to include 'ItdOnMarker$Holder' (ItdOnMarker.java) weaveinfo Type 'Sample' (Sample.java) has intertyped field from 'ItdOnMarker' (ItdOnMarker.java:'int ItdOnMarker$Holder.x') weaveinfo Join point 'method-execution(void Sample.print())' in Type 'Sample' (Sample.java:3) advised by before advice from 'ItdOnMarker' (ItdOnMarker.java:7) weaveinfo Join point 'method-execution(void Sample.foo())' in Type 'Sample' (Sample.java:28) advised by before advice from 'ItdOnMarker' (ItdOnMarker.java:7) weaveinfo Join point 'method-execution(void Sample.bar())' in Type 'Sample' (Sample.java:31) advised by before advice from 'ItdOnMarker' (ItdOnMarker.java:7) weaveinfo Extending interface set for type 'SubMarker' (SubMarker.java) to include 'ItdOnMarker$Holder' (ItdOnMarker.java) weaveinfo Extending interface set for type 'Marker' (Marker.java) to include 'ItdOnMarker$Holder' (ItdOnMarker.java) info processing reweavable type ItdOnMarker$Holder: \ItdOnMarker.java info successfully verified type ItdOnMarker exists. Originates from F:\workspaces\aspectj16_1\AA\src\ItdOnMarker.java weaveinfo Type 'ItdOnMarker$Holder' (ItdOnMarker.java) has intertyped field from 'ItdOnMarker' (ItdOnMarker.java:'int ItdOnMarker$Holder.x') weaveinfo Join point 'method-execution(void Derived.foo())' in Type 'Derived' (Derived.java:2) advised by before advice from 'ItdOnMarker' (ItdOnMarker.java:7) info processing reweavable type ItdOnMarker: \ItdOnMarker.java Testing Derived Fields for Derived: Fields for Sample: ajc$interField$ItdOnMarker$ItdOnMarker$Holder$x Testing Sample Fields for Sample: ajc$interField$ItdOnMarker$ItdOnMarker$Holder$x Here is is reduced down: Running Derived info register aspect ItdOnMarker weaveinfo Extending interface set for type 'Derived' (Derived.java) to include 'ItdOnMarker$Holder' (ItdOnMarker.java) weaveinfo Type 'Derived' (Derived.java) has intertyped field from 'ItdOnMarker' (ItdOnMarker.java:'int ItdOnMarker$Holder.x') weaveinfo Extending interface set for type 'Marker' (Marker.java) to include 'ItdOnMarker$Holder' (ItdOnMarker.java) info processing reweavable type ItdOnMarker$Holder: \ItdOnMarker.java weaveinfo Type 'ItdOnMarker$Holder' (ItdOnMarker.java) has intertyped field from 'ItdOnMarker' (ItdOnMarker.java:'int ItdOnMarker$Holder.x') weaveinfo Type 'Sample' (Sample.java) has intertyped field from 'ItdOnMarker' (ItdOnMarker.java:'int ItdOnMarker$Holder.x') info processing reweavable type ItdOnMarker: \ItdOnMarker.java Running Sample info register aspect ItdOnMarker weaveinfo Extending interface set for type 'Sample' (Sample.java) to include 'ItdOnMarker$Holder' (ItdOnMarker.java) weaveinfo Type 'Sample' (Sample.java) has intertyped field from 'ItdOnMarker' (ItdOnMarker.java:'int ItdOnMarker$Holder.x') weaveinfo Extending interface set for type 'SubMarker' (SubMarker.java) to include 'ItdOnMarker$Holder' (ItdOnMarker.java) weaveinfo Extending interface set for type 'Marker' (Marker.java) to include 'ItdOnMarker$Holder' (ItdOnMarker.java) info processing reweavable type ItdOnMarker$Holder: \ItdOnMarker.java weaveinfo Type 'ItdOnMarker$Holder' (ItdOnMarker.java) has intertyped field from 'ItdOnMarker' (ItdOnMarker.java:'int ItdOnMarker$Holder.x') info processing reweavable type ItdOnMarker: \ItdOnMarker.java it looks like the existence of the Marker interfaces is also interfering as this message: weaveinfo Extending interface set for type 'SubMarker' (SubMarker.java) to include 'ItdOnMarker$Holder' (ItdOnMarker.java) doesn't come out when running Derived
unsetting the target field which is currently set for something already released