[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Pointcut based on field annotation

It seems that your use case may be implementable with existing AspectJ construct by keeping a journal of the fields. For example, you could advise the write access to keep track of @Weak objects:

WeakHashSet<Collection> weakReferencedCollections = ...

before(Collection obj) : set(@Weak * *) && args(obj) {
    weakReferencedCollections .add(obj)
}


before(Collection obj) : call(* Collection.*(..)) && target(obj) {
    if (weakReferencedCollections.get(obj) != null) {
        ...
    }
}

Granted, this is not as straightforward. With the above code, you get all cases implemented correctly. In fact, you may be able to detect if a reference is shared in an inconsistent manner (@Weak in one place but regular in others).

-Ramnivas

On Mon, Aug 4, 2008 at 11:29 PM, zeroorone <zeroorone@xxxxxxxxx> wrote:

Thank you for responding. I definitely understand the semantic gap. Probably
much to your dismay, I do actually want the 1 & 2 cases to be match.
Explaining the functionality I am trying to accomplish may help you
understand why I want this type of functional behavior.

I am working on a master's thesis that uses aspectj to invisibly provide a
memory management system by releasing memory into a persistent data store.
Adding an annotation like @Weak would cause all field access to be
monitored. Any set causes the value to be persisted to a database while
caching a weak reference to the value. This weak reference provides some
performance improvements as it effectively implements a cache for field
access (helping with locality of reference). Once all strong references to
the value are released, I let the garbage collector release the memory that
would normally be maintained by the field. Further access to the field
subsequently results in accessing the data from the database (or its cache).

As you astutely point out, I am having trouble when the caller of the field
get uses the reference, either through a subsequent invocation (case 1) or
through assignment to another variable (case 2). All three cases relate to
my inability to monitor modifications to the values through references,
which I currently am able to do only within the context of a field-set.

I understand how this is difficult, if not impossible, to implement with
aspects. However, it seems to me like this is a behavior that those who are
using aspectj may desire. In response to your scenarios, I believe one could
implement the following behavior:

// class-level variables
@Weak
public Collection<String> values; // annotated
public Collection<String> referenceValues; // not annotated

// 1, 2 - at compile time this seems plausible and pretty straight-forward
values.add("foo"); // match

...

// much more difficult, as the field referenceValues is not annotated;
// in this case I would expect the pointcut to NOT match because
// having the compiler understand referential assignment is a bit much
referenceValues = values;
referenceValues.add("bar"); // no match

...

// what about a local variable that is annotated? I believe this would match
// because the variable that has the function add() invoked is specifically
annotated

@Weak
Collection<String> refVals = values;
refVals.add("foobar"); // match

---------

// this would even work if the class-level variable was not annotated
// but the local variable was, like so:

refVals = referenceValues; // assign annotated variable to non-annotated
class field
refVals.add("hi"); // match
referenceValues.add("there"); // no match
values.add("bob"); // match


Although this seems difficult to get right (semantically), it seems within
reason. It all boils down to compile-time information--the context of the
function call. I would not expect for the pointcut to understand the
semantics of references, but it seem plausible to match the pointcut when
the target happens to be a field/variable annotated as desired. This is why
I see it as similar to @target, except that instead of saying the target
class is annotated, the target field/variable is annotated.

However, I do see a limitation to my suggested behavior, function chaining,
like such:

((Collection<String>)values.clone()).add("foo")

Given my semantics, the clone() would possibly match (as it is called on a
field that is annotated) but the add() in this case would not because the
add function is invoked on another reference, not values. Although rather
odd, this still seems acceptable semantically.

I'd appreciate any comments or feedback on this idea. Without this type of
behavior, I cannot implement my thesis using aspectj entirely, much to my
dismay :)

Thanks,
Mike



Ramnivas Laddad wrote:
>
> It is not currently possible with AspectJ.
>
> One problem with such potential pointcut is difficulty in supporting
> correct
> semantics. For example, consider what should happen in the following
> cases:
>
> 1. item.values.add("foo");           // should this be advised?
> 2. Collection<String> values = item.values;
>     ...
>     values.add("foo");                 // should this be advised?
> 3. Collection<String> values = item.values;
>     operationThatAddsString(values);
>
>     ...
>     public void operationThatAddsString(Collection<String> values) {
>         values.add("foo");           // should this be advised?
>     }
>
> The problem with 2 and 3 is that it is nearly impossible for the compiler
> to
> figure out that the target object is been a @Weak field in some object.
> Then
> supporting just one doesn't seem right as it won't survive even simple
> refactoring as done in 2. Things become more complex if an object is set
> as
> a field of two different objects with different annotations or no
> annotation
> in one case.
>
> -Ramnivas
>
> On Sat, Aug 2, 2008 at 10:17 PM, zeroorone <zeroorone@xxxxxxxxx> wrote:
>
>>
>> I've searched around and looked through the documentation but can't seem
>> to
>> find a way to create a pointcut for the following situation.
>>
>> Is there a way to match any calls when the target of a function call is a
>> field/member annotated with a particular annotation? I know this is very
>> simple if the type of the field is annotated, as I would just add an
>> @target
>> pointcut. I have tried to play around with the cflow poincuts, but the
>> function call I'd like to advise is not within the cflow of the field
>> access, but after.
>>
>> Here is the situation expressed in code:
>>
>> public class TestItem {
>>   @Weak public Collection<String> values;
>>   ...
>> }
>>
>>
>> TestItem item = new TestItem(...)
>> item.values.add("foo"); // want to advise this function call add
>>
>>
>> // my poor attempts thus far
>> 1. after() : call(* *.*(..)) && @annotation(Weak)
>> 2. after() : call(* *.*(..)) && @target(Weak)     // the type isn't
>> annotated, the field is
>> 3. after() : cflowbelow(get(@Weak Object+ *.*)) && call(* *.*(..))     //
>> the function call is not in the control flow of the field access
>>
>>
>> Is this behavior supported by aspectj in any way? Have I overlooked a
>> solution? It seems like another pointcut may be added, like @field(X),
>> which
>> matches join points where the target is a field/member annotated with X.
>>
>> Thanks in advance,
>> Mike
>> --
>> View this message in context:
>> http://www.nabble.com/Pointcut-based-on-field-annotation-tp18795275p18795275.html
>> Sent from the AspectJ - users mailing list archive at Nabble.com.
>>
>> _______________________________________________
>> 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
>
>

--
View this message in context: http://www.nabble.com/Pointcut-based-on-field-annotation-tp18795275p18823932.html
Sent from the AspectJ - users mailing list archive at Nabble.com.

_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users