Skip to main content

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

In speaking with a coworker, we also came up with a similar "wildcard"
solution. In order to capture all modifications to the references, I'd have
to expand the scope to many more situations beyond collection. Although this
will likely lead to performance losses, it would functionally implement my
solution. Since my project aims at lowering the memory footprint of an
application at runtime, this performance cost might be acceptable. I'll give
this solution a try and assess the performance impacts and tradeoffs and go
from there.

Thank you very much,
Mike



Ramnivas Laddad wrote:
> 
> 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
>>
> 
> _______________________________________________
> 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-tp18795275p18834515.html
Sent from the AspectJ - users mailing list archive at Nabble.com.



Back to the top