Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
RE: [aspectj-dev] interfaces, pointcuts, and libraries

There has been enough interest that this language feature needs to be on the
table for 1.2.  To help our planning I've linked the key messages in
docs/developer/language.html (thanks for attaching the old messages Ron).

Mik

> -----Original Message-----
> From: aspectj-dev-admin@xxxxxxxxxxx [mailto:aspectj-dev-admin@xxxxxxxxxxx]
> On Behalf Of Ron Bodkin
> Sent: Monday, July 28, 2003 12:27 PM
> To: aspectj-dev@xxxxxxxxxxx
> 
> Hi Wes,
> 
> To clarify a bit, the original proposal _was_ to allow references to
> abstract pointcuts outside derived aspects. However, Jim made a good
> counterproposal of allowing extensible aspects rather than references to
> abstract pointcuts. As your note points out, references to abstract
> pointcuts would raise interesting questions.
> 
> Extensible pointcuts shouldn't require instantiation of any aspects that
> extend them. They aren't abstract pointcuts at all, which would require
> this. Instead, there is a single global definition of a concrete pointcut
> that is held in the defining aspect.
> 
> 
> Whenever another aspect extends it, the behavior is like for inter-type
> declarations: the pointcut in the original aspect is extended. You could
> use syntax like:
> 
> declare extension: AA.apc(): {pointcut};
> 
> so you'd have
> aspect AA {
>      extensible // required, or always allow inter-type extension?
>      pointcut apc() : {base definition};
> }
> 
> If AA were abstract, it would behave the same as if apc() were not
> extensible in concrete aspects derived from it.
> 
> Ron
> 
> Ron Bodkin
> Chief Technology Officer
> New Aspects of Security
> m: (415) 509-2895
> 
> > ------------Original Message-------------
> > From: Wes Isberg <wes@xxxxxxxxxxxxxx>
> > To: "aspectj-dev@xxxxxxxxxxx" <aspectj-dev@xxxxxxxxxxx>
> > Date: Mon, Jul-28-2003 12:10 PM
> > Subject: Re: [aspectj-dev] interfaces, pointcuts, and libraries
> >
> > Hi Arno -
> >
> > You point out that we often want to recompose a pointcut.
> > One way is to redefine a concrete pointcut:
> >
> > ------ SuperPointcut.java
> >
> > abstract aspect AA {
> >      pointcut publicMethodCalls() : call(public * *(..))
> >          && !within(AA+);
> >      before() : publicMethodCalls() {
> >          System.out.println("public method call: " +
> >                               thisJoinPointStaticPart);
> >      }
> > }
> >
> > //aspect A extends AA {}
> > aspect B extends AA {
> >      pointcut publicMethodCalls() : AA.publicMethodCalls()
> >          && !call(void java..*.*(..));
> > }
> >
> > public class SuperPointcut {
> >      public static void main(String[] a) {
> >          new C().run();
> >      }
> > }
> > class C {
> >      public void run(){
> >          System.out.println("run()"); // advise this?
> >      }
> > }
> >
> > ------
> > The aspect A would advise the call to System.out.println(String),
> > while the aspect B does not.
> >
> > Do you think that would help?  Your library aspects can have
> > concrete pointcuts which are referred to and qualified by
> > the subaspects for a particular configuration.
> >
> > Wes
> >
> > Arno Schmidmeier wrote:
> > > Hi all,
> > > Hello Wes,
> > >
> > > the current abstract pointcut behaviour is fine with me, asl long as I
> use it
> > > as a real abstract pointcut.
> > >
> > > However I often have to abuse abstract pointcuts to emulate something
> what I
> > > have named extensible pointcuts. (One of my requests for 1.1)
> > >
> > > I have the impression, that this feature would be give Adrian, all
> what he
> > > needs to implement and would fit more clearly into the language.
> Please tell
> > > me if I am wrong.
> > >
> > > Unfortunatly I can imagine, that this causes some headache with
> incremental
> > > compile, weave. ...
> > >
> > > Some motivations examples:
> > >
> > > 1. Exception logging.
> > > I found very often a general rule, that all caught runtimeexception,
> which
> > > might have caused some harm, should be logged to stderr, ...
> > >
> > > so following advice with pointcut would do it:
> > >
> > > before(Exception ex):handler(Exception)&&args(ex){
> > >    ex.printStackTrace(); // some other stuff...
> > > }
> > >
> > > It is pretty naturally to move this logic to a kind of library aspect.
> > > Unfortunatly, there are always some exceptions form the general rule
> in the
> > > code base. Places, where the advice should not be applied.
> > >
> > > So I would like to say:
> > >
> > > abstract aspect LogExceptions{
> > >
> > > abstract pointcut mustNotLog();
> > > before(Exception ex):handler(Exception)&&args(ex)&&!mustNotLog(){
> > >    ex.printStackTrace(); // some other stuff...
> > > }
> > >
> > > So I can have one aspect per project, where I limit the scope for the
> library
> > > aspect. (with a concrete aspect).
> > > In practical code, this causes a very ugly concrete aspect.
> > >
> > > What I would prefere to have is something like:
> > >
> > > abstract aspect LogExceptions{
> > >
> > > extensible pointcut mustNotLog();
> > > before(Exception ex):handler(Exception)&&args(ex)&&!mustNotLog(){
> > >    ex.printStackTrace(); // some other stuff...
> > > }
> > > }
> > >
> > > somewhere else:
> > > declare pointcut LogException() extends: &&within(SomeClasss);
> > >
> > > and somewhere else:
> > > declare pointcut LogException() extends: &&within(SomeClasss);
> > >
> > > This specific feature can be also used the other way round, motivated
> by my
> > > original post:
> > > To add some joinpoint to an aspect. For this case I have found some
> idioms to
> > > work around, however I find them everything else than handy.
> > > However for the case, where I want to exclude some joinpoints with
> extensible
> > > pointcuts I do not jet know a solution.
> > >
> > > kind regards
> > >    Arno
> > >
> > >
> > >
> > > }
> > >
> > >
> > >
> > >
> > >
> > > On Saturday 26 July 2003 23:09, Wes Isberg wrote:
> > >
> > >>Another question is whether abstract aspects could play the same role.
> > >>While extending aspects is less flexible, it has the property that
> > >>the implementation is determinate for incremental weaving.
> > >>
> > >>Here's some pseudo-code for a programmer using a library of J2EE
> > >>pointcuts that is implemented by different vendors.  The last step
> > >>can be the selection of the vendor, when deploying:
> > >>
> > >>------- pseudo-code...
> > >>---- AspectJ J2EE library
> > >>
> > >>abstract aspect EjbPointcuts {
> > >>    abstract pointcut ejbInit();
> > >>    abstract pointcut ejbActivation();
> > >>    abstract pointcut ejbPassivation();
> > >>    abstract pointcut ejbPersisting();
> > >>    abstract pointcut ejbMessage();
> > >>    ...
> > >>}
> > >>abstract aspect JmsPointcuts { ... }
> > >>abstract aspect ServletPointcuts { ... }
> > >>abstract aspect JSPPointcuts { ... }
> > >>
> > >>---- {vendor} J2EE library
> > >>
> > >>abstract aspect VendorEjbPointcuts extends EjbPointcuts {
> > >>     {define pointcuts}...
> > >>}
> > >>...
> > >>
> > >>---- programmer writes to AspectJ J2EE library
> > >>
> > >>abstract aspect BankTransactions extends EjbPointcuts {
> > >>     Object around() : ejbMessage()
> > >>         && call(void Account.deposit(int)) {
> > >>         ...
> > >>     }
> > >>     ...
> > >>}
> > >>
> > >>---- application assembler/deployer hooks everything up
> > >>
> > >>aspect BankTransactionsAssembly extends BankTransactions {
> > >>     declare parents: BankTransactions extends VendorEjbPointcuts;
> > >>}
> > >>
> > >>------- end of pseudo-code...
> > >>
> > >>This approach poses single-inheritance problems that might drive
> > >>towards a single abstract aspect and deter reuse of other
> > >>abstract aspects, so it's obviously not ideal.  It might lead to
> > >>a practice of using the library pointcuts from other aspects:
> > >>
> > >>----
> > >>-- programmer code
> > >>/** concretize the EjbPointcuts for use */
> > >>abstract aspect BankTransactionPoints extends EjbPointcuts {
> > >>     ...
> > >>     public pointcut depositTransaction() : ejbMessage()
> > >>          && call(void Account.deposit(int);
> > >>}
> > >>
> > >>aspect BankTransactions extends Transactions {
> > >>     /** concretize the abstract pointcuts in Transactions */
> > >>     pointcut transactionalMessage() :
> > >>         BankTransactionPoints.depositTransaction();
> > >>     ...
> > >>}
> > >>-- application assembler/deployer
> > >>
> > >>aspect BankTransactionsAssembly extends BankTransactions {
> > >>     declare parents: BankTransactionPoints extends
> VendorEjbPointcuts;
> > >>}
> > >>
> > >>----
> > >>
> > >>This approach localizes the pointcut definitions in the vendor aspect,
> > >>which is loaded before any aspect or class that is affected by
> > >>the aspect, so it preserves incremental load-time weaving.
> > >>(Indeed, a vendor controlling the weaver could implement custom
> > >>join points not based on the normal Java programming model without
> > >>affecting the AspectJ language.)
> > >>
> > >>So before I'd want to support interface pointcuts that prevented
> > >>implementations of AspectJ from doing incremental weaving, I'd like
> > >>to see a few libraries using abstract aspects and know that they
> > >>can't do what people would like to do with libraries.
> > >>
> > >>Wes
> > >>
> > >>Adrian Colyer wrote:
> > >>
> > >>>AspectJ lets us declare pointcuts within aspects, classes and
> interfaces.
> > >>>To create 'library' pointcuts I need to be able to declare pointcuts
> in
> > >>>an interface (and let users of the library program to the interface),
> and
> > >>>then have implementers of the interface provide concrete
> implementations
> > >>>of those pointcuts. Exploring the behaviour of AspectJ 1.1 I see that
> we
> > >>>are part of the way there, but not fully. What I am about to describe
> is
> > >>>partially bug and partially feature request...
> > >>>
> > >>>Today I can write:
> > >>>
> > >>>public interface Foo {
> > >>>
> > >>>   public pointcut bar();
> > >>>
> > >>>}
> > >>>
> > >>>This compiles happily, and I can refer to Foo.bar() in advice (it
> doesn't
> > >>>match any joinpoints).
> > >>>
> > >>>If I write
> > >>>
> > >>>class C implements Foo {}
> > >>>
> > >>>this does not cause a compilation error (I believe it should, since C
> > >>>does not define pointcut bar which it's interface contract says it
> > >>>should).
> > >>>
> > >>>If I write
> > >>>
> > >>>class C implements Foo {
> > >>>  public pointcut bar() : execution(... ...);
> > >>>}
> > >>>
> > >>>this compiles happily. Writing advice against Foo.bar does not match
> > >>>anything, writing advice against C.bar() matches the execution
> > >>>joinpoints. The desired behaviour is that writing advice against
> Foo.bar
> > >>>should match against the C definition.
> > >>>
> > >>>If I write
> > >>>
> > >>>aspect A implements Foo {}
> > >>>
> > >>>this does not cause a compilation error (I believe it should, since C
> > >>>does not define pointcut bar()).
> > >>>
> > >>>
> > >>>If I change the interface definition to
> > >>>
> > >>>public interface Foo {
> > >>>  public abstract pointcut bar();
> > >>>}
> > >>>
> > >>>then compilation of A fails with "inherited abstract pointcut
> Foo.bar()
> > >>>is not made concrete in A" (good, but tells me that the pointcut is
> not
> > >>>being implicitly made abstract when defined in an interface).
> Compilation
> > >>>of the empty C declaration still does not produce the compilation
> error.
> > >>>
> > >>>How I think I would like this to behave is that pointcuts declared in
> > >>>interfaces are implicitly abstract (just like method definitions in
> > >>>interfaces). If a class or aspect declares that it implements the
> > >>>interface without providing a concrete definition of the pointcut
> then
> > >>>this is a compilation error.  Clients should be able to write advice
> > >>>against the interface, and the advice will apply to joinpoints
> matching
> > >>>any of the  concrete implementations of interface in the system (same
> > >>>rules as for abstract / concrete aspect pairs).
> > >>>
> > >>>Why this is important:
> > >>>* I  can create a standard interface that clients program to
> > >>>* Multiple parties can implement the interface to provide concrete
> > >>>implementations that make sense within their system. These can even
> be
> > >>>binary so that implementation details are never exposed to clients.
> > >>>
> > >>>What do others think?
> > >>>
> > >>>-- Adrian
> > >>>Adrian_Colyer@xxxxxxxxxx
> > >>
> > >>_______________________________________________
> > >>aspectj-dev mailing list
> > >>aspectj-dev@xxxxxxxxxxx
> > >>http://dev.eclipse.org/mailman/listinfo/aspectj-dev
> > >
> > >
> >
> > _______________________________________________
> > aspectj-dev mailing list
> > aspectj-dev@xxxxxxxxxxx
> > http://dev.eclipse.org/mailman/listinfo/aspectj-dev
> >
> _______________________________________________
> aspectj-dev mailing list
> aspectj-dev@xxxxxxxxxxx
> http://dev.eclipse.org/mailman/listinfo/aspectj-dev



Back to the top