Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
RE: [aspectj-users] simple question

Wes's responses on this issue have been right on.  I just wanted
to emphasise one comment he had:

    [You can't access this in super/this constructor calls] Because 
    Java prohibits that, AspectJ should do so, even if bytecode 
    permitted otherwise.

And note that the bytecode does _not_ permit otherwise.  Indeed, 
one of the reasons bytecode verification is complicated is to catch
exactly these cases:  references to "this" before superclass
initialization.

So, in summary:

  * A constructor call is somewhat like a static method call. 
    No target.

  * A constructor execution encompasses the code of the constructor _not
    including_ the this/super constructor call.  "This" is available.  

sorta in between these join points is one more

  * The first thing that happens after a constructor call is a 
    preinitialization join point.  This encompasses the code that runs 
    before the this/super constructor call (i.e., the arguments to the
    this/super constructor).  No "this".  

It is very rare that AspectJ users care about the preinitialization 
join point, but it's something that Java requires.

-erik


-----Original Message-----
From: aspectj-users-admin@xxxxxxxxxxx [mailto:aspectj-users-admin@xxxxxxxxxxx] On Behalf Of Wes
Isberg
Sent: Tuesday, September 30, 2003 5:39 PM
To: aspectj-users@xxxxxxxxxxx
Subject: Re: [aspectj-users] simple question


(Ron pressed me more on this offline, so I'm not really replying to my own email...)

"this" is available in the body of the constructor, but not
in `this(..)` or `super(..)` calls at the start of the
constructor:

     class C
         String name;
         C() {
             this(this.name); // illegal
         }
     }

So, assuming AspectJ could provide a non-null target before
the constructor call (based on the result of the new
bytecode operator but before the invokespecial that
transfers control to the constructor) and ignoring
the possible mis-use of an uninitialized reference,
doing so would permit programmers to access
"this" before they are permitted to do so in
`this(..)` or `super(..)` calls at the start of
the constructor.  Because Java prohibits that, AspectJ
should do so, even if bytecode permitted otherwise.

my $.02 -

Wes

Wes Isberg wrote:

> To explain more fully, in case it helps people remember...
> 
> Join point context is determined by Java, not AspectJ.
> 
> In Java, there is no reference to an object-to-be-created
> at the point of a constructor call.
> 
> In Java, "this" is available in the body of a constructor.
> 
> A pointcut should match regardless of the kind of advice, except that 
> after returning and after throwing specify an additional 
> instanceof-type check on the result or the exception thrown, since in 
> both cases the checked reference only exists when exiting the join 
> point.  Rather than having target() behave inconsistently over the 
> lifetime of the join point, the language designers chose to
> use a separate form for this kind of post-hoc dynamic
> binding.  This can permit implementations to cache the
> result of the pointcut once for all advice affecting
> the join point, rather than re-evaluating it for each
> kind or instance of advice.
> 
> If there is anything in the production-aspects section
> of the programming guide that says otherwise, it's a bug.
> 
> The semantics appendix of the programming guide is the
> best source for understanding the language.  We should
> add a table listing for each join point the advice
> possible and the context available, since it's easy to believe that 
> all context is always available.
> 
> Wes
> 
> Ron Bodkin wrote:
> 
>> David,
>>
>> It's important to note that the target of a constructor call is 
>> always
>> null, even after the join point has executed. That's what I was saying 
>> parenthetically.
>>
>> I find this to be inconsistent because the value for "this" on a
>> constructor execution join point is non-null, after the join point has 
>> returned. But it's the language design, and is not considered a bug.
>>
>> Ron
>>
>> Ron Bodkin
>> Chief Technology Officer
>> New Aspects of Security
>> m: (415) 509-2895
>>
>>
>>> ------------Original Message-------------
>>> From: "Costakos,David" <costakod@xxxxxxxx>
>>> To: "'aspectj-users@xxxxxxxxxxx'" <aspectj-users@xxxxxxxxxxx>
>>> Date: Tue, Sep-30-2003 6:10 AM
>>> Subject: RE: [aspectj-users] simple question
>>>
>>> I agree that after returning advice should work.  I tested your code
>>> and it
>>> works for me.
>>>
>>> I think the discrepancy may be centered around "target" pointcuts.
>>>
>>> I've modified your example slightly in a way that breaks it using a
>>> target
>>> pointcut to capture the join point context.  Your example captured the
>>> JComponent object just using after returning advice.  As I read the
>>> Production Aspects section of the online documentation, this code should
>>> work.  Have I read it wrong or misunderstood something?
>>>
>>> import javax.swing.JTextField;
>>> import javax.swing.JComponent;
>>>
>>> public aspect AddToolTip  {
>>>   pointcut newJ(JComponent c):
>>>       call(JComponent+.new(..)) && target(c); // <-- This uses 
>>> target to capture context
>>>
>>>   after(JComponent c) returning : newJ(c) {
>>>       c.setToolTipText("OK");
>>>       System.out.println("set tool tip");
>>>   }
>>>
>>>   public static void main(String args[]) {
>>>       JTextField comp = new JTextField();
>>>       System.out.println("text is "+comp.getToolTipText());
>>>
>>>   }
>>> }
>>>
>>> Thanks in advance Ron (or whoever answers this post).
>>>
>>> -----Original Message-----
>>> From: Ron Bodkin [mailto:rbodkin@xxxxxxxxxxxxxx]
>>> Sent: Monday, September 29, 2003 7:38 PM
>>> To: aspectj-users@xxxxxxxxxxx
>>> Subject: RE: [aspectj-users] simple question
>>>
>>>
>>> David,
>>>
>>> After returning advice should work, if you bind the result using 
>>> after returning (JComponent c), rather than trying to use target 
>>> (which is always null for a ctor).
>>>
>>> Another possible problem could be if you had some other advice
>>> interacting
>>> with this one, though that seems less likely.
>>>
>>> If, in fact, the after returning approach didn't work, it would be a
>>> bug and
>>> it would be helpful to post a standalone example that illustrates it.
>>>
>>> Here's an example where after returning does work:
>>>
>>> import javax.swing.JTextField;
>>>
>>> public aspect AddToolTip {
>>>   pointcut newJ():
>>>       call(javax.swing.JComponent+.new(..));
>>>
>>>   after() returning (javax.swing.JComponent c) : newJ() {
>>>       c.setToolTipText("OK");              System.out.println("set 
>>> tool tip");
>>>   }
>>>
>>>   public static void main(String args[]) {
>>>       JTextField comp = new JTextField();
>>>       System.out.println("text is "+comp.getToolTipText());
>>>
>>>   }
>>> }
>>>
>>> Ron Bodkin
>>> Chief Technology Officer
>>> New Aspects of Security
>>> m: (415) 509-2895
>>>
>>>
>>>> ------------Original Message-------------
>>>> From: "Costakos,David" <costakod@xxxxxxxx>
>>>> To: "'aspectj-users@xxxxxxxxxxx'" <aspectj-users@xxxxxxxxxxx>
>>>> Date: Mon, Sep-29-2003 12:45 PM
>>>> Subject: RE: [aspectj-users] simple question
>>>>
>>>> Having tried this out, I wasn't about to make this happen with
>>>> before or
>>>> after or after returning advice.
>>>>
>>>> Around advice seemed to work though:
>>>>
>>>>  pointcut newJ():
>>>>    call(JComponent+.new(..));
>>>>
>>>>  Object around(): newJ() {
>>>>    Object o = proceed();
>>>>    ((JComponent)o).setToolTipText("My Tip");
>>>>    System.err.println("Set");
>>>>    return o;
>>>>  }
>>>>
>>>> If anyone could explain why only around advice seemed to work, I'd 
>>>> appreciate it!
>>>>
>>>> Thanks,
>>>>
>>>> Dave.
>>>>
>>>> -----Original Message-----
>>>> From: Ron Bodkin [mailto:rbodkin@xxxxxxxxxxxxxx]
>>>> Sent: Monday, September 29, 2003 1:16 PM
>>>> To: aspectj-users@xxxxxxxxxxx
>>>> Subject: Re: [aspectj-users] simple question
>>>>
>>>>
>>>> Hi Dmitry,
>>>>
>>>> You surely don't want before advice here; the given object hasn't 
>>>> been initialized at that point (and target is null). For a more 
>>>> complete discussion of the topic of construction join points and 
>>>> how to access
>>>
>>>
>>> newly
>>>
>>>> constructed objects, see the FAQ entries 10.6 and 10.7 at
>>>>
>>>
>>> http://dev.eclipse.org/viewcvs/indextech.cgi/~checkout~/aspectj-home
>>> /doc/faq
>>>
>>>
>>>> .html#q:initializationjoinpoints
>>>>
>>>> Here's a stab at how you might write your aspect. If you need to 
>>>> set
>>>> the
>>>> tool tip "during" construction and not after, you probably will want to
>>>> write a pointcut based on being withincode of your constructors.
>>>>
>>>> public aspect AddToolTip {
>>>>    pointcut newJ():
>>>>        call(javax.swing.JComponent+.new(..));
>>>>
>>>>    after() returning (javax.swing.JComponent c) : newJ(){
>>>>        c.setToolTipText("OK");           }
>>>> }
>>>>
>>>> Ron Bodkin
>>>> Chief Technology Officer
>>>> New Aspects of Security
>>>> m: (415) 509-2895
>>>>
>>>>
>>>>> ------------Original Message-------------
>>>>> From: =?koi8-r?Q?=22=E4=CD=C9=D4=D2=C9=CA=22=20?= <dmrzh@xxxxxxx>
>>>>> To: aspectj-users@xxxxxxxxxxx
>>>>> Date: Sun, Sep-28-2003 11:50 PM
>>>>> Subject: [aspectj-users] simple question
>>>>>
>>>>> I want write aspect for set ToolTip text for all comonents, but 
>>>>> this
>>>
>>>
>>> picks
>>>
>>>> out no  join points.
>>>>
>>>>> Help me please.
>>>>>
>>>>> import javax.swing.JComponent;
>>>>> public aspect AddToolTip {
>>>>>     pointcut newJ(javax.swing.JComponent c):
>>>>>         call(javax.swing.JComponent+.new(..))&& target(c);
>>>>>     before(javax.swing.JComponent c) : newJ(c){
>>>>>         c.setToolTipText("OK");       
>>>>>     }
>>>>> }
>>>>>
>>>>>
>>>>> import javax.swing.*;
>>>>> import java.awt.*;
>>>>> public class MyFrame extends JFrame{
>>>>>     public static void main(String[] args){
>>>>>         MyFrame f=new MyFrame();       
>>>>>         f.setSize(300,300);
>>>>>         JPanel cp=new JPanel(new FlowLayout());
>>>>>         JButton b=new JButton("Ok");
>>>>>         cp.add(b);
>>>>>         f.setContentPane(cp);
>>>>>         f.show();
>>>>>     }
>>>>>
>>>>> }
>>>>>
>>>>> Dmitriy.




Back to the top