| Thanks for bringing this up for discussion, Matthew.  Some comments 
and code below; I do think the current behavior is correct, i.e., it's what the user 
should  expect based on how the programming guide describes initialization and 
handling interface initializers.   First, > One thing I am sure of: we should not return null [from 
getConstructor()]   That seems like the correct behavior to me if there is no constructor for 
an interface (this assumes we have an interface-specific initializer, which I think we 
do).     Second, wrt interface initialization, even though Java does not permit 
interfaces to have  
constructors, AspectJ permits interfaces to have fields that have 
initialization statements,  so I think users should be able to expect those to be sequestered in 
an interface initializer, i.e., "initialization(Interface.new(..)) && ! 
initialization(Instance.new(..))"  Indeed, in the example of an instance with superclass and superinterface, there should be 
three initialization join points: the instance, the superclass, and the 
superinterface.  This is  what the code below shows.  With care, each join point can be picked 
out.   Third, wrt declaring type,  the programming guide says    "At object initialization and pre-initialization join points, the 
signature is the constructor   signature for the constructor that started this initialization: the 
first constructor entered   during this type's initialization of this object."   On one hand, I think we'd want AspectJ's reflective access to follow this 
model, so the  declaring type of the (reflective) signature indeed should reflect the 
specific instance type,  "Test" in your program and "Initializer" in mine below.  On the other 
hand, if the pointcut really is only picking out the interface or superclass initialization join 
point, it seems  weird to say that it picks up the declaring type of the initiating 
constructor.  That would mean  the declaring type of the interface-initializer join point enclosed by the 
subtype-initializer join point would be the subtype, and it would thus get as many declaring 
types as there are implementing types, and it becomes not static data associated 
with the join point but dynamic data associated with the enclosing join point.  
So perhaps we should qualify the programming guide to say the declaring type for 
purposes of matching or some such language.  In any case, the code below shows 
what I think is the correct declaring type, Interface for the interface-initialization 
and Initializer for  the subtype.   Fourth, one might think that initialization of an instance starts 
the instance-initialization join  point and then starts the instance-initialization join point of any parent, 
since this is what Java leads us to believe is the order of execution for constructors.  
However, AspectJ defines constructor-execution for the subtype to start when the code for 
the constructor starts, which is after any explicit or implicit call to this(..) or super(..) in 
the constructor.  That means the supertype constructor-execution join point is not enclosed by the 
subtype constructor execution.  Initialization follows this even though 
initialization is intended to pick out the initiating constructor.  So even though the 
initialization join point matches based  on the subtype-type, the first initialization join point run is not the 
subtype-being-initialized but the supertype.  That's reflected in the code below and should probably 
be explained to users. (There is a faq entry on point, as well as a definition of the order of 
initialization for interfaces.)   hth - Wes   -------  Initializer.javaimport 
org.aspectj.lang.Signature;
 import org.aspectj.lang.JoinPoint;
 import 
org.aspectj.lang.reflect.ConstructorSignature;
   interface Interface { void m();}   public class Initializer extends Parent implements Interface {           public static void main(String[] 
args) 
{new Initializer();
 }
   }   class Parent { public void m(){}}
   aspect Aspect {static int 
counting() 
{
 System.err.println("COUNTING"); return ++COUNT; 
}
 static int COUNT;
           public int Interface.count = 
counting();   before () : 
initialization(Initializer.new()) 
{
 print(thisJoinPoint, " 
Interface");
 }
 before () : 
initialization(Interface.new()) 
{
 print(thisJoinPoint, " 
Interface");
 }
 before () : 
initialization(Interface.new())
 && !initialization(Parent.new()) 
{
 print(thisJoinPoint, 
"=Interface");
 }
 before() : 
initialization(Parent.new()) 
{
 print(thisJoinPoint, "    
Parent");
 }
 before() : 
initialization(Parent.new())
 && !initialization(Initializer.new()) 
{
 print(thisJoinPoint, "   
=Parent");
 }
 before() : 
initialization(Parent+.new()) 
{
 print(thisJoinPoint, "   
Parent+");
 }
 void print(JoinPoint jp, String 
label) 
{
 Signature signature = 
jp.getSignature();
 int line = 
jp.getStaticPart().getSourceLocation().getLine();
 System.err.println(label
 + " ["  + 
line
 + "] tjp=" + 
jp.hashCode()
 + "] this=" + 
jp.getThis()
 + ", declaringType=" + 
signature.getDeclaringTypeName()
 + ", " + 
((ConstructorSignature)signature).getConstructor());
 }
   }   
  ------------Original Message------------ From: Matthew Webster <matthew_webster@xxxxxxxxxx> To: aspectj-dev@xxxxxxxxxxx Date: Tue, Sep-19-2006 6:14 AM Subject: [aspectj-dev] AspectJ Runtime: Signatures for interface 
  initialization and type staticinitialization This discussion relates to 
  https://bugs.eclipse.org/bugs/show_bug.cgi?id=157054. I have also found 
  https://bugs.eclipse.org/bugs/show_bug.cgi?id=49295 and 
  https://bugs.eclipse.org/bugs/show_bug.cgi?id=60936 which concern the removal 
  from the language of the interface constructor execution pcd. Unfortunately 
  the documentation for this part of the API is terse and the tests almost 
  non-existent so it is very difficult to determine the intended behaviour. One 
  thing I am sure of: we should not return null.
 
 There seems to be a discrepancy between classes and 
  interfaces when it comes to the initialization join point. In the example 
  below we advise the initialization of a single class both as an extender of 
  Parent and an implementer of Interface:
 
 public class Test extends Parent implements 
  Interface {
 
 public static void main(String[] args) 
  {
 new Test();
 }
 
 }
 
 public interface Interface 
  {
 }
 
 public class Parent {
 }
 
 public 
  aspect Aspect {
 
 _______________________________________________before () : (initialization(Interface.new()) || initialization(Parent+.new())) 
  && !within(Parent) {
 Signature signature = thisJoinPoint.getSignature();
 System.err.println("Aspect.before() this=" + 
  thisJoinPoint.getThis()
 + ", 
  signature=" + signature.getClass()
 + ", 
  declaringType=" + thisJoinPoint.getSignature().getDeclaringTypeName()
 + ", 
  " + 
  ((ConstructorSignature)signature).getConstructor());
 }
 
 }
 
 However the output in each case is different:
 
 Aspect.before() this=Test@1833955, 
  signature=class org.aspectj.runtime.reflect.ConstructorSignatureImpl, 
  declaringType=Test, public Test()
 Aspect.before() this=Test@1833955, signature=class 
  org.aspectj.runtime.reflect.ConstructorSignatureImpl, declaringType=Interface, 
  null
 
 Firstly while the declaring 
  type for a class initializer is the target class in the case of the interface 
  it is not. Secondly an interface cannot have a constructor. There are two 
  possible solutions:
 1. Make the 
  implementing type the declaring type and remove the discrepancy between class 
  and interface.
 2. Return an 
  InitializerSignature instead of a ConstructorSignature. Unfortunately this 
  interface has getInitializer() which also returns a 
  java.lang.reflect.Constructor. What is slightly bizarre is that this interface 
  is also used for staticinitializer join points and in this case the interface 
  returns the signature for the default constructor of the target class!
 
 Matthew Webster
 AOSD 
  Project
 Java Technology Centre, MP146
 IBM Hursley Park, Winchester, 
   SO21 2JN, England
 Telephone: +44 196 2816139 (external) 246139 
  (internal)
 Email: Matthew Webster/UK/IBM @ IBMGB, 
  matthew_webster@xxxxxxxxxx
 http://w3.hursley.ibm.com/~websterm/
 aspectj-dev mailing list
 aspectj-dev@xxxxxxxxxxx
 https://dev.eclipse.org/mailman/listinfo/aspectj-dev
 
 |