Community
Participate
Working Groups
Here is a small test case that illustrates the problem I'm seeing with the AspectJ in CVS HEAD (it also affects 1.5.0 M2): The program should output 1 but it outputs null instead. public aspect AspectStatic { public interface Iface { } private static Class[] managedInterfaces = { Iface.class }; private static Object assembler = initAssembler(); private static Object initAssembler() { return new Integer(1); } public static void main(String args[]) { System.out.println("test = "+assembler); } } aspect StopsInit pertypewithin(AspectStatic) { before() : staticinitialization(*) { } }
for investigation in M4
Hmmm... if you compile this program 'ajc AspectStatic.aj' and run it, you get 'null'. If you compile this program 'ajc -1.5 AspectStatic.aj' and run it, you get '1'.
It is this line that causes us to fail when compiling without -1.5: private static Class[] managedInterfaces = { Iface.class }; commenting *out* that line and compiling 'ajc AspectStatic.aj', it runs OK. (or, as the bug suggests, commenting out the advice in the sub-aspect, also makes it work). managedInterfaces is obviously initialized via a static initializer block.
yuck. Modified program: --- public aspect A { interface I { } static Class[] classes = { I.class }; static Object f = new Integer(1); public static void main(String args[]) { System.out.println("test = "+f); System.err.println("A:"+A.aspectOf()); } } aspect StopsInit pertypewithin(A) { before() : staticinitialization(*) {} } --- Compiling and running this (no -1.5) will fail with: test = null Exception in thread "main" org.aspectj.lang.NoAspectBoundException: Exception while initializing A: java.lang.IncompatibleClassChangeError at A.aspectOf(A.aj) at A.main(A.aj:10) Caused by: java.lang.IncompatibleClassChangeError at A$I.<clinit>(A.aj:1) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:164) at A.<clinit>(A.aj:4) If you change the declaration of the inner type from 'interface I' to 'class I' then it compiles and runs OK ! The 'bang' that occurs during initialization prevents us executing the code that sets the field (hence it is null). The aspectOf() call enables us to see the exception that occurred during initialization.
The difference when the code is compiled with '-1.5' is the bytecode for initializing: private static Class[] managedInterfaces = { Iface.class }; When it fails (no -1.5): static {}; Code: Stack=5, Locals=1, Args_size=0 0: ldc #104; //String A 2: invokestatic #135; //Method StopsInit.ajc$createAspectInstance:(Ljava/lang/String;)LStopsInit; 5: putstatic #122; //Field ajc$StopsInit$ptwAspectInstance:LStopsInit; 8: invokestatic #126; //Method ajc$StopsInit$localAspectOf:()LStopsInit; 11: invokevirtual #131; //Method StopsInit.ajc$before$StopsInit$1$ee91c721:()V 14: iconst_1 15: anewarray #20; //class java/lang/Class 18: dup 19: iconst_0 20: getstatic #22; //Field class$0:Ljava/lang/Class; 23: dup 24: ifnonnull 52 27: pop 28: ldc #24; //String A$I 30: invokestatic #28; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class; 33: dup 34: putstatic #22; //Field class$0:Ljava/lang/Class; 37: goto 52 40: new #30; //class java/lang/NoClassDefFoundError 43: dup_x1 44: swap 45: invokevirtual #36; //Method java/lang/Throwable.getMessage:()Ljava/lang/String; 48: invokespecial #40; //Method java/lang/NoClassDefFoundError."<init>":(Ljava/lang/String;)V 51: athrow 52: aastore 53: putstatic #42; //Field classes:[Ljava/lang/Class; 56: new #44; //class java/lang/Integer 59: dup 60: iconst_1 61: invokespecial #47; //Method java/lang/Integer."<init>":(I)V 64: putstatic #49; //Field f:Ljava/lang/Object; 67: invokestatic #52; //Method ajc$postClinit:()V 70: goto 78 73: astore_0 74: aload_0 75: putstatic #54; //Field ajc$initFailureCause:Ljava/lang/Throwable; 78: return when it works (-1.5): static {}; Code: Stack=4, Locals=1, Args_size=0 0: ldc #89; //String A 2: invokestatic #121; //Method StopsInit.ajc$createAspectInstance:(Ljava/lang/String;)LStopsInit; 5: putstatic #108; //Field ajc$StopsInit$ptwAspectInstance:LStopsInit; 8: invokestatic #112; //Method ajc$StopsInit$localAspectOf:()LStopsInit; 11: invokevirtual #117; //Method StopsInit.ajc$before$StopsInit$1$ee91c721:()V 14: iconst_1 15: anewarray #19; //class java/lang/Class 18: dup 19: iconst_0 20: ldc #21; //class A$I 22: aastore 23: putstatic #23; //Field classes:[Ljava/lang/Class; 26: new #25; //class java/lang/Integer 29: dup 30: iconst_1 31: invokespecial #29; //Method java/lang/Integer."<init>":(I)V 34: putstatic #31; //Field f:Ljava/lang/Object; 37: invokestatic #34; //Method ajc$postClinit:()V 40: goto 48 43: astore_0 44: aload_0 45: putstatic #36; //Field ajc$initFailureCause:Ljava/lang/Throwable; 48: return when Iface is a class rather than an interface (it works): static {}; Code: Stack=5, Locals=1, Args_size=0 0: ldc #104; //String A 2: invokestatic #135; //Method StopsInit.ajc$createAspectInstance:(Ljava/lang/String;)LStopsInit; 5: putstatic #122; //Field ajc$StopsInit$ptwAspectInstance:LStopsInit; 8: invokestatic #126; //Method ajc$StopsInit$localAspectOf:()LStopsInit; 11: invokevirtual #131; //Method StopsInit.ajc$before$StopsInit$1$ee91c721:()V 14: iconst_1 15: anewarray #20; //class java/lang/Class 18: dup 19: iconst_0 20: getstatic #22; //Field class$0:Ljava/lang/Class; 23: dup 24: ifnonnull 52 27: pop 28: ldc #24; //String A$I 30: invokestatic #28; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class; 33: dup 34: putstatic #22; //Field class$0:Ljava/lang/Class; 37: goto 52 40: new #30; //class java/lang/NoClassDefFoundError 43: dup_x1 44: swap 45: invokevirtual #36; //Method java/lang/Throwable.getMessage:()Ljava/lang/String; 48: invokespecial #40; //Method java/lang/NoClassDefFoundError."<init>":(Ljava/lang/String;)V 51: athrow 52: aastore 53: putstatic #42; //Field classes:[Ljava/lang/Class; 56: new #44; //class java/lang/Integer 59: dup 60: iconst_1 61: invokespecial #47; //Method java/lang/Integer."<init>":(I)V 64: putstatic #49; //Field f:Ljava/lang/Object; 67: invokestatic #52; //Method ajc$postClinit:()V 70: goto 78 73: astore_0 74: aload_0 75: putstatic #54; //Field ajc$initFailureCause:Ljava/lang/Throwable; 78: return
test and fix checked in. waiting on build.
fix available in latest dev build.