Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] Re: Kudos, J2EE pointcuts, and Dynamic AOP

Cedric,

I just posted this reply to the TSS thread in question:

I've enjoyed the discussion on pointcuts and metdata and their uses in
AOP. I think the well-designed pointcuts should describe something
fairly abstract that is happening in the system. These should not be
describing how they will be used.

The implementation should be the most robust way to capture the
design, i.e., minimizing the maintenance effort and reducing the risk
of incorrectness. In descending order of robustness, I believe the
implementation options are:

1) precisely capturing the definition. Today, this fits where
   properties public methods or all subtypes of a class match the
   concept. As AOP matures, I believe there will be richer pointcuts
   so this category grows. E.g., a readOnly method is one that does
   not set any (non-transient) fields, nor call any non readOnly
   methods.
2) reliant on stable frameworks (e.g., in a servlet response or a
   Struts action) or organizing principles (e.g., package organization
   conventions).
3) reliant on widespread naming conventions. This approach is already
   commonly used in component development (e.g., JavaBeans naming
   pattern matching resulting in automatic behavior enforcement, or
   Weblogic Workshop or VB using method naming for event handling).
   Indeed, (static) AOP improves on this by providing good tools
   support to see matches and track changes. There is also the promise
   of refactoring support that will alert the developer to potential
   problems, unlike traditional approaches with specialized tooling.

These first three are all highly stable and avoid the fragility of marking every
instance of something.

4a) inline annotation through attributes (metadata). This is best for
    general-purpose concepts that are closely coupled to the core
    design. In this case, the use of attributes will be the best
    option. Forcing the use of an obscure naming convention is the
    worst option (it's better to use the participant pattern or
    external enumeration in the absence of attributes).

4b) external enumeration of matching points. If the concept is
    special-purpose, or really a choice about configuration or
    deployment (i.e., orthogonal), then the enumeration should be done
    separately to avoid tangling concerns.

To me the choice between 4a and 4b is parallel to that between
attributes and deployment descriptors for J2EE 1.5. For items that are
core to the design, adding a generally descriptive attribute is
preferable. For choices that should be bound after the code is
written, the external enumeration is preferable. Whether this
enumeration should be made in aspect code or XML is a separate debate.

5) To be avoided: "tricky" regexp's, including naming patterns that
   are obscure or unexpected. I think it is cases like this that
   critics of regexp pointcuts have in mind.

In some cases, the general-purpose definitions are only "mostly
right", and one can use enumeration or attributes to identify
exceptions to the rule (e.g., Timer.settings() isn't a setter). This
can be done by configuring abstract aspects for a particular component
or system. E.g.,

public abstract aspect TransactionManagement {
    /** defines executions of read only methods */
    public pointcut readOnlyExecutions(): 
        (execution(* get*(..)) || execution(* is*(..))) &&
        !readOnlyExceptions() && inScope();

    /** defines exclusions to the normal rules for
        read only methods */
    abstract pointcut readOnlyExceptions();

    /** defines the scope of application of the instantiation of
        this pointcut */
    abstract pointcut inScope();
}

I also think that AOP support for JSR-175 should include static
crosscutting.  E.g., adding declare attribute to AspectJ, to be
used in a superset of cases of when one uses declare parents
with marker interfaces today. Cedric: I agree that marker interfaces
will be obsolete when we have real attributes. This provides an
interesting opportunity to allow developers to mix and match
enumeration and in line descriptions, as Adrian Colyer pointed out.

Cedric and others raised the question of good examples of robust
concepts for pointcuts ("annotated concerns"). Here are a few
suggestions that represent interesting points on the spectrum:

1. Security: sensitive information (objects), personally identifiable
information (objects), restricted function (methods). These are
meaningful concepts independent of the security policy in effect. One
can write very different advice for them (access control, audit
trails, personalization to filter unentitled links, statistics on
access, etc.).

Sometimes these items can be identified by package structure, but they
often need to be identified explicitly. In this case, external
enumeration is preferable to inline annotation because classification
of information can change more frequently and independently of
application logic, and because it's highly desirable to separate
specification of security from business logic.

Methods that access sensitive data are very much like transactional or
readonly methods: ideally it would be handled by tracking methods that
handle a given type of data. Today, these are best
enumerated. However, with AOP, it is more feasible to defer
enforcement to the point of access rather than pre-emptively
restricting access, logging, etc. (i.e., this derivative concept may
not be required for correct policy implementation).

2. Error handling: Policies for logging, converting, displaying, and
   resolving exceptions typically use very stable well-defined
   concepts. E.g., convert exceptions when exiting a tier (a top-level
   public methods within a group of packages) or log and handle within
   framework elements (e.g., Action classes or other controllers or
   Runnables).

3. Template classes. This is a domain-specific example from a project
   where we need to persist historical values of certain "template"
   objects (but not the derived objects). Tracking which classes are a
   template is a more general idea than object versioning. The concern itself
   would be natural to annotate inline with attributes.

4. Framework operations. E.g., J2EE pointcuts. This kind of pointcut
   is very robust and is applicable for a wide variety of concerns
   (e.g., to define accesses to session information while servicing a
   servlet).

5. Testing. There are a number of different kinds of pointcuts that
   are interesting for testing when enhanced by AOP. It's often
   important to test whether one is in test code (to enable tracing,
   change behavior, or not affect the test code itself).

   a) In a test case: This can be defined structurally (e.g., a
   subtype of a TestCase).

   b) In a testing stub: This can be defined robustly with clear,
   common naming standards (Test* or *Stub), with specific packages
   (*.test).

   c) Operations to be replaced with mock processing. If one is using
   "virtual mock objects", it's important to define where mock
   processing applies. This is basically a combination of a structural
   property (in the control flow of a test case) and external
   configuration information (within a given test case, affect
   processing of these specific objects). So these should use
   pointcuts that combine universal definitions with ones that provide
   specific enumeration.
   This seems like a natural use for dynamic AOP; eventually I'd like to
   see a combination of the configuration capabilities of a Polygenix
   with the power of AOP.

8. Development instrumentation (debugging, profiling, tracing): This
   needs to be defined externally from the code. It's
   deployment information, not intrinsic to the design.

Ron

Ron Bodkin
Chief Technology Officer
New Aspects of Security
m: (415) 509-2895

> ------------Original Message-------------
> From: Cedric Beust <cbeust@xxxxxxx>
> To: Ron Bodkin <rbodkin@xxxxxxxxxxxxxx>
> Cc: sam@xxxxxxx, Adrian Colyer <adrian_colyer@xxxxxxxxxx>, AspectJ Users <aspectj-users@xxxxxxxxxxx>
> Date: Sat, Jul-26-2003 11:00 AM
> Subject: Re: Kudos, J2EE pointcuts, and Dynamic AOP
> 
> Ron Bodkin wrote:
> 
> >One can also write AspectJ aspects to address a handful of system-wide dynamic concerns that many POJOs might implement. If you made them all implement a _marker_ interface like Advisable (as JBoss does), then you can write advice with a test for whether this object is affected (using introductions or a hash map).
> >
> Note that marker interfaces are very likely to become discouraged when 
> JSR 175 (i.e. JDK 1.5) becomes final.  The recommended way to do this 
> will then become metadata.
> 
> I posted a few thoughts on TheServerSide thread about annotated 
> concerns, which I pasted below.  Any comments?
> 
> The thread (Gregor's interview) can be found at:  
> http://www.theserverside.com/home/thread.jsp?thread_id=20583&article_count=9
> 
> -- 
> Cédric
> http://beust.com/weblog
> 
> 
> 
> 
> <http://www.theserverside.com/home/thread.jsp?thread_id=20583&article_count=9#90621> 
> Annotated concerns
> Posted By: Cedric Beust 
> <http://www.theserverside.com/home/myThreads.jsp?user_id=60459> on July 
> 26, 2003 @ 12:18 PM in response to Message #90610 
> <http://www.theserverside.com/home/thread.jsp?thread_id=20583&article_count=9#90610>. 
> 
> I notice that both of you use the same example to illustrate pointcuts 
> with annotations: readonly (or changestate).
> 
> Intuitively, I feel that an AOP framework should support all types of 
> pointcuts (both external and internal) but except for the above example, 
> I can't find another convincing use case.
> 
> Like Gregor, I have the feeling that annotated pointcuts should tell 
> something generic about the method they are annotating, and not describe 
> what it does. They should be conceptual. ChangeState is a good example, 
> and I was thinking that something like Idempotent is another one: this 
> indicates that this method can be called several times (stateless). An 
> application could typically make use of that information to implement 
> failover and retry a call that has just failed, knowing that it is not 
> going to cause an inconsistency in the state of the application.
> 
> How do you identify what a good "Annotated concern" is? Maybe a good 
> hint is: it can be represented by very different implementations. An 
> "annotated concern" like "ChangeState" is very broad indeed. A method 
> can be one line long or a hundred lines long and still fall in this 
> category. It can be called setPoint() or foo() and still deserve the 
> annotation ChangeState.
> 
> With this definition, UpdateDisplay immediately comes out as suspicious: 
> it is way too specific and tied to the implementation. As would 
> something like UpdateDatabase (how about the more generic "SaveState" 
> instead?).
> 
> But I am still annoyed at the poverty of examples to support this 
> assertion. It's a bit like trying to advocate AOP by implementing 
> logging in an aspect... if you repeat the same example over and over, 
> you lose your ability to convince.
> 
> I am also worried by the fragility of the regexp approach. If ever a 
> developer renames a method or moves it to a different class, the 
> pointcut might no longer find it. Worse: you can imagine a situation 
> where you have two different developers: one who wrote the business code 
> (let's call him B) and one wrote the aspect (A). And in the purest 
> illustration of separation of concerns, B has no idea what aspects have 
> been written around his code, so he doesn't even have the possibility to 
> modify the aspect in parallel (which should raise concerns of coupling 
> anyway).
> 
> I think this is a real concern (no pun intended) in taking AOP to a big 
> scale, especially since IDE's nowadays make it so easy to do major 
> refactorings.
> 
> *1 replies in this thread 
> <http://www.theserverside.com/home/thread.jsp?thread_id=20583&article_count=9#top>
> 
> *
> 
> 


Back to the top