[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] LTW, inter-type fields and pertarget() aspects

What does -showWeaveInfo tell you when it is loading?

Here is my scenario:
----
public class C {
  public static void main(String[] argv) {
    C c = new C();
    c.setSomething();
  }

  public void setSomething() {
  }
}

aspect X {
  private boolean C.flag = false;

  pointcut setSomething(C c): target(c) && call(* C.set*(..));

  before(C c): setSomething(c) {
    if (c.flag) {
      System.out.println("Flag is true!");
    } else {
      System.out.println("Flag is false!");
    }
  }
}
----
ajc C.java -outjar code.jar
ajc X.java -classpath aspectjrt.jar;code.jar -d aspects.dir -outxml
alter aspects.dir/META-INF/aop-ajc.xml to include:
<weaver options="-verbose -showWeaveInfo -debug"/>

now run C:
aj5 -classpath code.jar;..\lib\aspectjweaver.jar;aspects.dir C
[AppClassLoader@1f12c4e] info AspectJ Weaver Version 1.6.2 built on Saturday Oct 4, 2008 at 05:47:07 GMT
[AppClassLoader@1f12c4e] info register classloader sun.misc.Launcher$AppClassLoader@1f12c4e
[AppClassLoader@1f12c4e] info using configuration /C:/aspectj162/JochenWuttke/aspects.dir/META-INF/aop-ajc.xml
[AppClassLoader@1f12c4e] info register aspect X
[AppClassLoader@1f12c4e] debug weaving 'C'
[AppClassLoader@1f12c4e] weaveinfo Type 'C' (C.java) has intertyped field from 'X' (X.java:'boolean C.flag')
[AppClassLoader@1f12c4e] weaveinfo Join point 'method-call(void C.setSomething())' in Type 'C' (C.java:4) advised by before advice from 'X' (X.java:6)
[AppClassLoader@1f12c4e] debug weaving 'X'
[AppClassLoader@1f12c4e] info processing reweavable type X: \X.java
Flag is false!

Do you see no messages related to weaving the ITD?  With -debug you will get the 'debug weaving' lines in the output.  Do you see the target for the ITD with a 'debug weaving' message occurring ahead of the weaving of your advice? 

Do you really need to use call() rather than execution() in your pointcuts?  call() with ltw tends to only be suitable for catching calls to system libraries that are not easy to weave with execution().

cheers,
Andy.


2008/10/15 Jochen Wuttke <jochen.wuttke@xxxxxx>
Thanks Andy and Simone,

I think I understand the basic idea now. But apparently something is not yet working for me.
Here's an aspect that uses two ITDs, which do not get woven using LTW and thus cause a NosuchField exception (I get weave info on the method advice, but not the ITDs). As you can see it is pretty much the same as the one using pertarget(), and I'd like to understand if I'm doing something wrong, or if there's some sort of bug that prevents me from using ITD fields.


public aspect JspIdConsumerUnique {
       
       private boolean UIComponentClassicTagBase.lumi_uniquePropertySet = false;
       private Object UIComponentClassicTagBase.uniqueProperty = null;

       pointcut instanceCreation( UIComponentClassicTagBase _consumer ): this(_consumer) && execution( UIComponentClassicTagBase+.new(..) );

               
       after(UIComponentClassicTagBase _consumer) : instanceCreation( _consumer ) {
               safeAddObject( _consumer );
       }
       
       pointcut setUniqueProperty( UIComponentClassicTagBase _consumer ): target(_consumer) &&
               call( * UIComponentClassicTagBase+.setJspId(..) );
       
// ITD USED HERE

       before( UIComponentClassicTagBase _consumer ): setUniqueProperty( _consumer ) {
               if ( _consumer.lumi_uniquePropertySet ) {
                       _consumer.uniqueProperty = _consumer.getJspId();
               }
       }
       
//AND HERE

       after( UIComponentClassicTagBase _consumer ): setUniqueProperty( _consumer ) {
               if ( propertyHasChanged( _consumer.uniqueProperty, _consumer.getJspId() ) ) {
                       _consumer.lumi_uniquePropertySet = true;
                       updateContainer( _consumer.uniqueProperty, _consumer );
               }
       }
       
       //private methods go here
}


Thanks again,
Jochen



On Oct 14, 2008, at 11:14 PM, Andy Clement wrote:


> - Shouldn't a pertarget/perthis aspect declare field pretty much the same way as an inter-type declaration in a singleton aspect?
Sometimes.  The instantiation model of the aspect won't affect the application of static crosscutting.  An intertype field declaration onto some type will apply for all instances of that type, not just a subset that might be selected by the instantiation model - so the fields will always be there, but when they are used depends on your advice.  perthis()/pertarget() allow for even finer grained control over the state lifecycle where you want some state to exist for just a subset of the join points that occur during execution.


Andy.

2008/10/14 Jochen Wuttke <jochen.wuttke@xxxxxx>
Hi,

I started playing with LTW, inter-type fields and pertarget() aspects and ran into an interesting problem.
I was trying to use inter-type fields to carry some information I need on a per-object basis. But every time the advice using these inter-type fields got executed I got a NoSuchFieldException (the compiler gave me a typeNotExposedToWeaver warning, but I think that's ok, because I use LTW). So I changed my aspect to be pertarget() and it behaves like expected (aspect code below).

Now here are my questions:
- Shouldn't a pertarget/perthis aspect declare field pretty much the same way as an inter-type declaration in a singleton aspect?
- I'm not sure if I should use a pertarget or perthis aspect for what I want to do. The content of the fields should be carried around with the advised object across the objects lifetime (which is why I originally wanted to use inter-types).
- When running the LTW with -showWeaveInfo I get a log message for every jointpoint that gets woven. What should the message look like for weaving inter-type fields. Or should there be a message at all?

Thanks,
Jochen

P.S.: My aspect looks like this:

public aspect JspIdConsumerUnique pertarget( instanceCreation(UIComponentClassicTagBase) || setUniqueProperty(UIComponentClassicTagBase) ) {

      private boolean lumi_uniquePropertySet = false;
      private Object lumi_uniqueProperty = null;

      pointcut instanceCreation( UIComponentClassicTagBase _consumer ): target(_consumer) && execution( UIComponentClassicTagBase+.new(..) );

      after(UIComponentClassicTagBase _consumer) : instanceCreation( _consumer ) {
              safeAddObject( _consumer );
      }

      pointcut setUniqueProperty( UIComponentClassicTagBase _consumer ): target(_consumer) &&
              call( * UIComponentClassicTagBase+.setJspId(..) );

      before( UIComponentClassicTagBase _consumer ): setUniqueProperty( _consumer ) {
              uniqueProperty = _consumer.getJspId();
      }

      after( UIComponentClassicTagBase _consumer ): setUniqueProperty( _consumer ) {
              if ( propertyHasChanged( _consumer.getJspId() ) ) {
                      lumi_uniquePropertySet = true;
                      updateContainer( uniqueProperty, _consumer );
              }
      }

      //private methods go here

}

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