Skip to main content

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

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

}



Back to the top