Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
RE: [aspectj-users] Question about usingwithin/cflowpointcutswiththird-party jars

Hi Neil,

AspectJ does use a fast matching algorithm to avoid doing much of the work
of weaving for types that can't match some concrete "munger" (such as advice
or tracking cflows). Fast matching currently only helps if you "guard" your
pointcuts with a within pointcut: it doesn't infer possible types for other
constructs.

As you noted, advising the following pointcut would be expensive because
AspectJ has to look in every class to see if it has setters that match:

 	pointcut setterNotCalledByHibernate():
 		!calledByHibernate() && execution(* *.set*(..));

To improve performance of this, you'd want to use:

 	pointcut setterNotCalledByHibernate():
 		scope() && !calledByHibernate() && execution(* *.set*(..));
      pointcut scope() : within(org.foo.myapp.entity..*);

Then you could also limit your load-time weaving with an additional 
  <include within="org.foo.myapp.entity..*"/>

Note that it matters where advices (mungers) are triggered, not what
pointcuts are defined per se.

On the other point, why I suggest adding additional include clauses, I have
found there are cases where my aspects have PrivilegedAccessMungers that I
didn't expect, don't seem to be required and that add overhead unless I use
the include clauses. I haven't had time to investigate why this is
happening, but I have noted it's a source of overhead. 

There's another reason too: if you have fast matching on type patterns of
the form name..* AspectJ LTW uses simple matching on Strings to determine
whether to weave the class: otherwise it has to parse the bytecode to build
an internal representation, which also adds overhead.

Also, this is almost certainly not what you want:
	pointcut hibernate(): !within(org.hibernate..*);
	pointcut notCalledByHibernate(): cflow(hibernate());

This matches join points that in the cflow of any join point not in
hibernate (e.g., calls from your app or another library into Hibernate).

You surely meant something like:
	pointcut hibernate(): within(org.hibernate..*) && execution(*
*(..));
	pointcut notCalledByHibernate(): !cflow(hibernate());

This matches join points not in the cflow of execution of methods defined in
Hibernate.


-----Original Message-----
From: aspectj-users-bounces@xxxxxxxxxxx
[mailto:aspectj-users-bounces@xxxxxxxxxxx] On Behalf Of Neil Redding
Sent: Friday, August 18, 2006 12:13 PM
To: aspectj-users@xxxxxxxxxxx
Subject: RE: [aspectj-users] Question about
usingwithin/cflowpointcutswiththird-party jars


Also: Haven't inspected the preprocessor output for this, but why would
iajc need to weave into classes when their joinpoints are not specified
by any pointcuts? A relevant aside is that I tried this variation prior
to the one I posted earlier, but with the same result:

	pointcut hibernate(): !within(org.hibernate..*);
	pointcut notCalledByHibernate(): cflow(hibernate());

I suppose the first pointcut above would be very expensive, in the sense
that it specifies all joinpoints in the classpath/inpath other than
those within org.hibernate..* classes, yes? 

> -----Original Message-----
> From: aspectj-users-bounces@xxxxxxxxxxx 
> [mailto:aspectj-users-bounces@xxxxxxxxxxx] On Behalf Of Neil Redding
> Sent: Friday, August 18, 2006 2:39 PM
> To: aspectj-users@xxxxxxxxxxx
> Subject: RE: [aspectj-users] Question about using 
> within/cflowpointcutswiththird-party jars
> 
> 
> Thanks Ron - a couple followup questions below:
> 
> > To weave within the hibernate classes, you would need 
> Hibernate to be 
> > on your inpath (i.e., to weave the Hibernate jars). One way 
> you might 
> > do this without building a modified version of Hibernate would be 
> > load-time weaving.
> 
> I've been assuming LTW is expensive - is it not? I think I'll 
> give it a go, since I don't want to modify Hibernate unless I 
> have to. 
> 
> > Another option would be to use cflow of calls into Hibernate. 
> > The calls from your code into Hibernate can be woven 
> without weaving 
> > into Hibernate. E.g.,
> > 
> > 	pointcut callHibernate(): 
> > 		call(* org.hibernate..*(..)) ||
> > call(org.hibernate..*.new(..));
> > 	pointcut inHibernate(): cflow(callHibernate());
> > 
> > 	pointcut setterNotCalledByHibernate():
> > 		!calledByHibernate() && execution(* *.set*(..));
> 
> Right; the issue is that I need to exclude Hibernate 
> joinpoints regardless of where they're called from - it's not 
> always from "my code". 
> 
> > Also, note that your original pointcut is rather expensive 
> (it would 
> > weave into *all join points* in Hibernate such as field get/set, 
> > handler etc). If you were going to weave into Hibernate you'd want 
> > something like:
> > 
> > 	pointcut hibernate(): 
> > 		(execution(* *(..)) || execution(* new(..))) &&
> > 		within(org.hibernate..*);
> 
> Thanks, I was a bit method-invocation-myopic there for a 
> moment - didn't consider the other joinpoint types. :-)
> 
> Dumb question (?): Why "execution(* new(..))" in the pointcut 
> immediately above - isn't this covered by "execution(* *(..))"?
> 
> Cheers,
> Neil
> _______________________________________________
> 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



Back to the top