Community
Participate
Working Groups
The program below only reports a join point at the set of y, and not of x, which seems clearly wrong. I get the same behaviour when I make foo() return false instead of true. I'm using 'DEVELOPMENT built on Monday Aug 16, 2004 at 13:50:47 GMT' public class FieldInit { public static final int x=foo() ? bar(): 2; public static final int y=!foo() ? 2: bar(); static boolean foo() { return true; } static int bar() { return 3; } public static void main(String[] args) { } } aspect FIAspect { before() : set(int FieldInit.*) { System.out.println(thisJoinPointStaticPart); } }
Yep, this is a bug. There's a bit of weirdness in AspectJ relating to constant fields, but clearly by JLS 15.28, neither x nor y is a constant field due to the static method call. I'll take a look at this; it's possible that someone (the Eclipse front end) is overoptimizing and marking x constant.
Is the precise specification that the initialization of a final variable with a constant expression should not be treated as a join point? If so, how is this detected in bytecode which contains such an initialization?
We assume that fields with ConstantValueAttributes are constant. Existing java compilers are pretty good about NOT generating a PUTSTATIC for such fields. Check for yourself by decompiling class Test { public static int i = 3; }
That's true for static fields, but it doesn't seem to be for non-static fields, and the new/FieldInitializerJoinPoints.java file in the ajc tests seems to suggest that they should also not be treated as join points if they have a constant initializer.
My initial take on this is that new/FieldInitializerJoinPoints.java may just be wrong. The problem comes from this really cool bit o' code: public class Test { public final int x= 3; public static void main(String[] args) { Test t = new Test(); t.foo(); } void foo() { System.err.println(x); // a constant reference System.err.println(this.x); // NOT a constant reference } } the field x, in this case, is a weird thing in Java: a field that, when referred to by plain name, must be inlined, but must also have a runtime value for when it is referred to by qualified name. For some reason we decided that this was a "constant field" and should have no set join point. I'm starting to believe that this should have a set join point. The semantics appendix currently (under the "join points" section) only defines constant fields as static final fields whose initializer is a constant string object or primitive value, and I _think_ we should probably migrate the compiler to this behavior as well. (Not that we're sure any of this has to do with the actual bug we're dealing with... Hmm. Maybe we should create a new bug report crying foul at new/FieldInitializerJoinPoints.java and move some of the discussion over there)
Discussion about instance field join points moved to bug 72335.