Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Please help getting started - load time weaving (LTW) doesn't work

> The classes Test and MyEntity are not available to the aspectj-compiler
> (iajc) at compile time and I get the warning "advice defined in MyAspect
> has not been applied [Xlint:adviceDidNotMatch]".
> Does that mean that all classes to be woven, even with the
> load-time-weaver, must be kind of "prepared" by the AspectJ compiler? If
> yes, is there any way around this, as it would make AspectJ useless for
> my case (thus I cannot imagine that this is required).

No it is not required.  When building your application for LTW, the
only types that need to be around to satisfy compilation of the aspect
are those you directly reference.  For example in your aspect you
explicitly refer to the type 'Entity' - so that needs to be around on
the classpath, the types Test and MyEntity do not need to be.  You can
suppress the messages about advice not matching if you like by
attaching an AspectJ annotation to the advice declarations.

Here is how your application behaves for me.  I have created all the
source files: Entity, Test, MyAspect and MyEntity.  First lets do it
all on the command line.

$ ajc -1.5 -showWeaveInfo *.java
Join point 'field-get(java.lang.String MyEntity.ajField)' in Type
'MyEntity' (MyEntity.java:5) advised by around advice from 'MyAspect'
(MyAspect.java:9)

Join point 'method-execution(java.lang.String MyEntity.testGet())' in
Type 'MyEntity' (MyEntity.java:5) advised by around advice from
'MyAspect' (MyAspect.java:5)

Join point 'method-execution(void MyEntity.testSet(java.lang.String))'
in Type 'MyEntity' (MyEntity.java:6) advised by around advice from
'MyAspect' (MyAspect.java:5)

Join point 'method-execution(java.lang.String MyEntity.ajMethod())' in
Type 'MyEntity' (MyEntity.java:8) advised by around advice from
'MyAspect' (MyAspect.java:5)

Join point 'method-execution(java.lang.Object MyEntity.indirectM2())'
in Type 'MyEntity' (MyEntity.java:13) advised by around advice from
'MyAspect' (MyAspect.java:5)

Join point 'method-execution(java.lang.Object MyEntity.ajMethod2())'
in Type 'MyEntity' (MyEntity.java:17) advised by around advice from
'MyAspect' (MyAspect.java:5)

Join point 'method-execution(void Test.main(java.lang.String[]))' in
Type 'Test' (Test.java:2) advised by around advice from 'MyAspect'
(MyAspect.java:5)

$ java Test
JOINPOINT testMethod() called

So what has happened here is that your advice matched on the execution
of Test.main() in your test program - and because the advice did not
contain a proceed, you just got one message out from the advice and
the body of the main method never ran.  If I change your pointcut
from:

 pointcut testMethod() : execution(* *.*(..));

to
 pointcut testMethod() : execution(* *.*(..)) && !within(Test);

then after compiling and running it works as you probably expected.

$ java Test
Calling ajMethod()
JOINPOINT testMethod() called
ajMethod() returned 'ASPECTVALUE'
Calling ajMethod2() via indirectM2()
JOINPOINT testMethod() called
ajMethod2() via indirectM2() returned 'ASPECTVALUE'
Calling testGet()
JOINPOINT testMethod() called
testGet() returned 'ASPECTVALUE'
Calling testSet(...)
JOINPOINT testMethod() called
Calling testGet()
JOINPOINT testMethod() called
testGet() returned 'ASPECTVALUE'
Exiting

However, that is only because I'm playing with everything being
compiled up front.  Let's switch to a loadtime weaving setup and build
things separately

ajc -1.5 -d outputFolder MyAspect.java Entity.java

export CLASSPATH=outputFolder:$CLASSPATH

javac -d outputFolder MyEntity.java Test.java

(I include outputFolder on the classpath there so that MyEntity can refer to it)

Now we have in outputFolder:
MyAspect.class - built aspect
Entity.class - compiled annotation
MyEntity.class - compiled class, not yet woven
Test.class - compiled class, not yet woven

I have also put your aop.xml file in a META-INF folder alongside
outputFolder, so it looks like this
META-INF/aop.xml
outputFolder/MyEntity.class
outputFolder/MyAspect.class
outputFolder/Test.class
outputFolder/Entity.class

Now I run it:
t$ java -javaagent:../../lib/aspectjweaver.jar Test
[AppClassLoader@a39137] info AspectJ Weaver Version DEVELOPMENT built
on Monday Jun 11, 2007 at 16:05:11 GMT
[AppClassLoader@a39137] info register classloader
sun.misc.Launcher$AppClassLoader@a39137
[AppClassLoader@a39137] info using configuration
/Users/99/aspectj1.5/mailinglist/bernhard_messerer/META-INF/aop.xml
[AppClassLoader@a39137] info register aspect MyAspect
[AppClassLoader@a39137] debug weaving 'Test'
[AppClassLoader@a39137] weaveinfo Join point 'method-execution(void
Test.main(java.lang.String[]))' in Type 'Test' (Test.java:3) advised
by around advice from 'MyAspect' (MyAspect.java:5)
[AppClassLoader@a39137] debug generating class 'Test$AjcClosure1'
[AppClassLoader@a39137] debug weaving 'MyAspect'
[AppClassLoader@a39137] info processing reweavable type MyAspect: MyAspect.java
[AppClassLoader@a39137] debug cannot weave
'org.aspectj.lang.NoAspectBoundException'
JOINPOINT testMethod() called

And it works the same as full compilation on the command line.  your
advice in the aspect is applying to the testMethod() and without a
proceed that is all it does, so lets modify the aop.xml, change this
section:
    <weaver options="-verbose -debug -showWeaveInfo">
        <!-- no includes/excludes means "weave to all classes (visible
to the weaver)" -->
    </weaver>

to:
    <weaver options="-verbose -debug -showWeaveInfo">
        <exclude within="Test"/>
    </weaver>

so that we don't weave Test at loadtime.  Now just rerun:

$ java -javaagent:../../lib/aspectjweaver.jar Test
[AppClassLoader@a39137] info AspectJ Weaver Version DEVELOPMENT built
on Monday Jun 11, 2007 at 16:05:11 GMT
[AppClassLoader@a39137] info register classloader
sun.misc.Launcher$AppClassLoader@a39137
[AppClassLoader@a39137] info using configuration
/Users/99/aspectj1.5/mailinglist/bernhard_messerer/META-INF/aop.xml
[AppClassLoader@a39137] info register aspect MyAspect
[AppClassLoader@a39137] debug not weaving 'Test'
[AppClassLoader@a39137] debug weaving 'MyEntity'
[AppClassLoader@a39137] weaveinfo Join point
'field-get(java.lang.String MyEntity.ajField)' in Type 'MyEntity'
(MyEntity.java:5) advised by around advice from 'MyAspect'
(MyAspect.java:9)
[AppClassLoader@a39137] weaveinfo Join point
'method-execution(java.lang.String MyEntity.testGet())' in Type
'MyEntity' (MyEntity.java:5) advised by around advice from 'MyAspect'
(MyAspect.java:5)
[AppClassLoader@a39137] weaveinfo Join point 'method-execution(void
MyEntity.testSet(java.lang.String))' in Type 'MyEntity'
(MyEntity.java:6) advised by around advice from 'MyAspect'
(MyAspect.java:5)
[AppClassLoader@a39137] weaveinfo Join point
'method-execution(java.lang.String MyEntity.ajMethod())' in Type
'MyEntity' (MyEntity.java:9) advised by around advice from 'MyAspect'
(MyAspect.java:5)
[AppClassLoader@a39137] weaveinfo Join point
'method-execution(java.lang.Object MyEntity.indirectM2())' in Type
'MyEntity' (MyEntity.java:14) advised by around advice from 'MyAspect'
(MyAspect.java:5)
[AppClassLoader@a39137] weaveinfo Join point
'method-execution(java.lang.Object MyEntity.ajMethod2())' in Type
'MyEntity' (MyEntity.java:18) advised by around advice from 'MyAspect'
(MyAspect.java:5)
[AppClassLoader@a39137] debug generating class 'MyEntity$AjcClosure1'
[AppClassLoader@a39137] debug generating class 'MyEntity$AjcClosure3'
[AppClassLoader@a39137] debug generating class 'MyEntity$AjcClosure5'
[AppClassLoader@a39137] debug generating class 'MyEntity$AjcClosure7'
[AppClassLoader@a39137] debug generating class 'MyEntity$AjcClosure9'
[AppClassLoader@a39137] debug generating class 'MyEntity$AjcClosure11'
Calling ajMethod()
[AppClassLoader@a39137] debug weaving 'MyAspect'
[AppClassLoader@a39137] info processing reweavable type MyAspect: MyAspect.java
[AppClassLoader@a39137] debug cannot weave
'org.aspectj.lang.NoAspectBoundException'
JOINPOINT testMethod() called
ajMethod() returned 'ASPECTVALUE'
Calling ajMethod2() via indirectM2()
JOINPOINT testMethod() called
ajMethod2() via indirectM2() returned 'ASPECTVALUE'
Calling testGet()
JOINPOINT testMethod() called
testGet() returned 'ASPECTVALUE'
Calling testSet(...)
JOINPOINT testMethod() called
Calling testGet()
JOINPOINT testMethod() called
testGet() returned 'ASPECTVALUE'
Exiting

This was all done on a Mac running Java1.5.0.  Can you try the steps
above and tell me which doesn't work for you?

cheers,
Andy


Back to the top