Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Annotations AspectJ questions

Hi Ron -

> Is there a prescription (at least by enforcing
> conventions) for being able to annotate Class C,such
> that: 
...

Something like this?:
  after() returning : pc() && aspectsPermitted() &&
    codeExecutionPermittingAfterReturning() { ... }

where the *Permit* pointcuts are defined in terms of
annotations
scattered through the possibly-affected code.  That's
doable (code below) 
but perhaps not desirable.

Your question is whether clients should be oblivious or
unwilling,
and more generally the steps to take when adopting AspectJ
in the
face of doubt and a restricted tool environment.

Just to be clear, AspectJ takes a three-step approach:
(a) aspects should see and be able to affect everything,
because
    crosscutting by nature affects other modules;

(b) it's essential when working with crosscutting to have
    proper tool/IDE support for navigating the
crosscutting,
    in order to understand any interactions (usually to
convince
    oneself that there are no bad interactions).

(c) the crosscutting language is expressive enough to be
able to 
    protect anything it can affect (but does not possess a 
    macro-style ability to affect the language itself,
because
    that adds too much complexity)

So we took the path of believing clients are neither
unwilling
or oblivious when the programmer has notice and can change
the aspect.
You instead are requiring notice and consent, not for the
aspect 
programmer in the aspect, but for the programmer of the
affected code
in the affected code.

By hypothesis in your case, the programmer of the affected
code is 
permitting *some* crosscutting (but wants to control it?),
is
unable/unwilling to use the tool support to get notice,
and wants control via annotations.  This comes largely from
the
promise of annotation-style aspects to make it easier to
integrate
AspectJ, and shows that we have not provided the tool
support necessary
for annotation-style, particularly for people not using
AJDT.  We
are working in AJDT to provide the same support for
annotation-style
as code style, and should offer command-line tools for
those not
able/willing to use Eclipse.

Outside of AJDT, you can get some notice by using ajdoc.
 But what
you'd want is a tool which, given a specification (e.g.,
don't 
affect classes X, Y, or Z; don't use after-throwing
advice), could
signal when the rules were violated.  Ideally, for each
violation
you'd want a reference to the violating advice or ITD,
which 
likely means you'd build it on the crosscutting map
generated by
the compiler/weaver.  (Helen's recent updates to the AST
might
make this a lot easier.)  But the key benefit of this tool
would be
being able to write the (crosscutting) specification once
and
enforce it whenever and whereever.  You'd still have the
option of
allowing the programmer of the affected code to scatter
annotations
by way of specification if that made them more comfortable,
but
you wouldn't have to litter the aspects with corresponding
guards.

Annotation guards are limited because they are not as
expressive as
pointcuts.  They basically only help for policies applying
class-wide 
or per-method or constructor execution or call or field get
or set,
and you still have to decide, e.g., whether to permit
advice on a 
(anonymous?) subclass of a class annotated to refuse
advice.

So, now that you've suffered my lecture on why you don't
want to do
this, here's a sample of what you'd have to do:

--------------------------------------------
package stuff;

public class ExecPlus {
	public static void main(String[] args) {
		new C().foo(0);
		new D().foo(0);
	}
}
@interface AfterOK{}
@interface NoAspects{}

abstract class B { abstract void foo(int i); }
class C extends B { public void foo(int i) {} }
class D extends B { @AfterOK public void foo(int i) {} }
@NoAspects class E extends B { @AfterOK public void foo(int
i) {} }
aspect A {
    pointcut pc() : execution(void B.foo(int));
    pointcut codeExecutionPermittingAfterReturning() :
        execution(@AfterOK *.new(..)) 
        || execution(@AfterOK * *(..));   

    // have to add guards to each advice     
    after() returning : pc() && aspectsPermitted() &&
      codeExecutionPermittingAfterReturning() {
        System.out.println("here: " + thisJoinPoint);
    }
    // implementing @NoAspects - could be in execution,
like
    //    !execution(* (@NoAspects *).*(..))
    // but we'd like to define aspectsPermitted() for other
join points
    // (have to work around "type patterns not permitted in
target()")
    private interface NA {}
    declare parents: (@NoAspects *) implements NA;
    pointcut aspectsPermitted() :
        !within(NA+) && !target(NA);
        // could be !within(@NoAspect *)
}
-------------------------------------------------------

This is basically your solution:

>     @BeforeOnly @AfterOnly
>     public void doIt() {...}

If you just want a way to state class- or package-level
control 
without littering the code with annotations, you can
instead use 
declare parents or repeat a type pattern:

  interface NIMBY {}
  declare parents: (com.co.special..*) implements NIMBY;

Then use NIMBY as NA was used above.  In this case, the
rule
holds even if someone forgets to add or remove an
annotation.

But your requirements here are a bit broader:

> A) The developer of C will know that an aspect has been
> applied 
> B) The developer of C will know (and by convention limit)
> the style of aspect applied 
> C) The developer of A can not add a pointcut unbeknownst
> to the owner of C (without at least violating
> conventions)

(A) There is no way to meet (A) given your tool setup. For
C to know, 
s/he has to use some of our tools.

(B) We satisfy the C-developer's knowledge in AJDT, and
could do
more in another reporting tool, but to permit the
C-developer to
limit the A-developer (without A's knowledge?) involves
creating a
whole new language about the AspectJ crosscutting language.
 As you
suggest, you can go down this road with some
annotation-based
conventions, but annotations are not powerful enough.
 Again, a tool
might help.  (And what would drive a tool would be a nice
clean
specification of what it's supposed to do and why - a good
use case.)

(C) *Restricting* A-developer means getting AspectJ
language support
for not using the AspectJ language - it's just weird.  You
can do that
by not using the language, i.e, not weaving the class.
You're welcome
to adopt the annotation conventions, but they won't be
enforced.

There have been proposals that extending a pointcut be
limited to
restricting the original pointcut; that would enable
abstract aspects
to enforce a policy against subaspects.  There's also a
proposal to 
not weave final classes by default.  But that's not how it
works now,
in part because the solutions are partial and just confuse
the clear 
rule that aspects see/do everything.

I suspect the requirements are over-broad.  C-developers
have a vague
concern that the aspect -- i.e., some other developer --
might do 
something-they-know-not-what.  If C-developers don't trust
the 
A-developers, there's not much the tool can do.  If they
are just 
concerned about accidents, then they might be convinced by
showing
that AspectJ offers basically the same protections as Java
wrt type- 
and exception- safety and checking. 

C-developers might also gain confidence against accidents
and
incompetence if A-developers can use AJDT to double-check
their work.
So I'm curious why you can't use binary aspects written in
code style.  
Annotation-style aspects do use the AspectJ syntax, but
they just defer 
the processing until they are woven.  With either
code-style or 
annotation-style, you need to do a weave (so the build or 
class-loading process has to change).  Code style has much
better
support in AJDT, and AJDT also helps new developers learn
AspectJ,
leading to better A-developers.

enough said!

hth - Wes

On Thu, 02 Feb 2006 08:50:28 -0500
 Ronald J Mann <Ron.Mann@xxxxxxx> wrote:
> Hi all!
> 
> Another newbie question.  After scanning the docs, I'm a
> little confused
> on the capabilities of annotations.  I'm trying to employ
> aspects as a
> part of a broader project, some of whom's members are
> quite suspicious
> of granting the ability to crosscut their code without
> they're explicit
> knowledge embodied in their code.  Equally,  I've been
> required to use
> the annotation style for my poincuts and advice as the
> result of the
> build process issues around utilizing the aspectJ syntax
> directly. 
> 
> I've successfully used the  annotation style for the
> pointcuts and
> advice declarations themselves, but I'm teetering on the
> brink of
> understanding as to the use of annotations in the body of
> the code that
> is to be cut.  Before I proceed down this road, I wanted
> to confirm that
> one can concurrently employ annotations for both the
> advice declaration
> as well as pointcut discrimination.  So given something
> that currently
> looks like this:
> 
> class C {
>     public void doIt() {...}
> }
> 
> @Aspect class A {
>     @Before("call(void C.doIt())") { ... }
> }
> 
> Is there a prescription (at least by enforcing
> conventions) for being able to annotate Class C,such
> that: 
> 
> A) The developer of C will know that an aspect has been
> applied 
> B) The developer of C will know (and by convention limit)
> the style of aspect applied 
> C) The developer of A can not add a pointcut unbeknownst
> to the owner of C (without at least violating
> conventions)
> 
> thus if I had created a BeforeOnly & AfterOnly
> annotation: 
> class C {
>     @BeforeOnly @AfterOnly
>     public void doIt() {...}
> }
> 
> What would the syntax for the aspect look like?
> @Aspect class A {
>     @Before("???????") { ... }
> }
> 
> Would there be a methodology to actually restrict the
> application of an @AfterReturning? 
> I recognize that some of these notions might be outside
> the spirit of AOP/aspectJ, but having to deal with real
> world resistence to AOP is a part of the equation.
> 
> Thanks in advance for the 'advice'  ;-) !
> 
> =Ron=
> 
> 
> 
> 
> 
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/aspectj-users



Back to the top