Hi,
When faced with this sort of problem, you can introduce the method to
the interface directly rather than creating an artificial subclass
inside your aspect.
In this example I target any class marked with @MyMarker. Then I
provide it with the dummy interface (that I declare in the aspect as a
nested class).
I then target that interface in order to add a data member foo and
getter and setter. So first the aspect:
public final aspect SampleAspect {
declare parents : (@MyMarker *) implements MyMarker.Interface;
private String MyMarker.Interface.foo;
public String MyMarker.Interface.getFoo() {
return foo;
}
public void MyMarker.Interface.setFoo(
String foo) {
this.foo = foo;
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public static @interface MyMarker {
public static interface Interface {
}
}
}
and here is an empty class that uses it but with comments showing what
the aspect adds in:
import SampleAspect.MyMarker;
@MyMarker
public class MyClass /* implements SampleAspect.Interface */{
/* private String MyMarker.Interface.foo; */
/* public String MyMarker.Interface.getFoo() {
return foo;
} */
/* public void MyMarker.Interface.setFoo(
String foo) {
this.foo = foo;
} */
}
My attempts to target just annotations for intertype declarations
don't seem to work which is why I add in the interface which I can
target.
- Ashley
On 16 Jun 2009, at 21:54, Jim Sellers wrote:
Thanks for the feedback Ramnivas. ;-)
Rather than try to do a threadlocal, I tried to use an inter-type
and add an attribute to all classes the implment HttpSession.
However, I'm having a bit of trouble with it. I don't know if my
problem is a result of trying to use an interface in the javax.*
package [1] or if it's because I'm trying to declare parents for an
interface.
Below is my aspect.
@Aspect
public class SessionIndicator {
public interface ClusterableHttpSession {
Map<String, Integer> getAttributesHash();
};
public static class ClusterableHttpSessionImpl implements
ClusterableHttpSession {
private HashMap<String, Integer> attributesHash = new
HashMap<String, Integer>();
public Map<String, Integer> getAttributesHash() {
return attributesHash;
}
}
@DeclareParents(value = "javax.servlet.http.HttpSession",
defaultImpl = ClusterableHttpSessionImpl.class)
private ClusterableHttpSession implementedInterface;
@Before("call(void
javax.servlet.http.HttpSession.setAttribute(..)) && this(m) ")
public void trackSessionAttributeHash(ClusterableHttpSession m) {
System.out.println("This is where we're going to look at the
session attribute" + m.getAttributesHash());
}
}
Am I trying to do something that's not supported? Or am I missing
something?
Thanks for your time!
Jim
[1] http://www.eclipse.org/aspectj/doc/next/devguide/ltw-specialcases.html
On Sat, Jun 13, 2009 at 10:56 AM, Ramnivas Laddad <[email protected]
> wrote:
Inline...
On Sat, Jun 13, 2009 at 10:02 AM, Jim Sellers<[email protected]>
wrote:
> Hello all.
>
> I'm new to writing AOP code and have only used it for common uses
like
> transactions (in spring). Please forgive me if I mess up the AOP
terms, but
> feel free to correct me. ;-)
>
> Now I'm trying to solve an issues and I wanted to see if you guys
have any
> advice about if I'm on the right track, "this is already done with
lib X",
> ... (aside: I use maven / eclipse for the projects)
>
> Background for the problem I'm trying to solve:
> I am trying to put in some AOP code that will intercept calls to
> HTTPSession.setAttribute(...). Using this we will be able to
verify that
> any code being put into session is serializable. Also, for any
object that
> implments HTTPSession, we'll trap the state of the object being
set (using
> HashcodeBuilder to generate a hash), and then at the end of the
test verify
> the the object in our mock session has not changed (has the same
hashcode).
> In this way we are hoping to be able to verify if an application is
> clusterable without a tedious class by class inspection.
>
> Here are the issues that I currently have:
> 1) I'm a little confused on what code should be "woven" - the
creating of a
> mock HTTPSession will only happen in testing code (src/test/java)
while the
> *calls* to setAttribute(..) that I care about will only happen in
prod code
> (src/main/java)
Which code is calling HttpSession.setAttribute()? If you control that
code (in production; in tests, you clearly control the calls).
Assuming that you control calls in production code as well, call seems
to be the correct join point in either case.
>
> 2) I only want to add this weaving for the tests, I don't want
these checks
> making it into code running in production or for the project to
have a
> non-test dependency on this code
You can have two build targets--one that includes aspects and other
that doesn't.
>
> 3) I think that I need to add a joinpoint (pointcut ?) to an
"after return"
> on my @Test methods in order to check the state of the session.
Most of the
> examples are done using method name matching. Can I mix a pattern
match
> (public void test*) and an annotation, or is that 2 seperate join
points?
>
http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations-pointcuts-and-advice.html
You can write a pointcut that can mix name patterns with annotations.
>
> 4) in order to check the state of the mock session at the end of
the test,
> I think that I will need to keep a reference to them in the
advice. Is this
> normally done or is there something wrong with this approach?
Would it need
> to be a static member variable of the advice (I'm not clear of the
lifecycle
> / state of the advice yet)
You could advise mock creation to keep references to those in a
ThreadLocal member of the aspect. You can also use the percflow()
association for the aspect (but, since you are just starting with
AspectJ, you may not want to venture into that area just yet). Then
you may advise the completion of test methods (an after returning
advice) to verify all mocks for which the aspect has a reference
(added by the earlier mentioned advice). It should also clear the
references as it checks.
>
> Thanks for your time in even reading this far. ;-) Any help would
be
> wonderful.
>
> Thanks for your time,
> Jim
>
> _______________________________________________
> aspectj-users mailing list
> [email protected]
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>
>
_______________________________________________
aspectj-users mailing list
[email protected]
https://dev.eclipse.org/mailman/listinfo/aspectj-users
_______________________________________________
aspectj-users mailing list
[email protected]
https://dev.eclipse.org/mailman/listinfo/aspectj-users
_______________________________________________
aspectj-users mailing list
[email protected]
https://dev.eclipse.org/mailman/listinfo/aspectj-users