Skip to main content

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

Here's a much shorter but far less comprehensive tip:

Passing the "-showWeaveInfo" option to the compiler/weaver will cause
it to emit information messages concerning exactly which join points
were woven and on behalf of which aspects. It should be possible to
use some basic awk/grep style processing on that list to detect
unwanted entries!

On 02/02/06, Wes Isberg <wes@xxxxxxxxxxxxxx> wrote:
> 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
>
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>


--
-- Adrian
adrian.colyer@xxxxxxxxx


Back to the top