Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] A transaction question

The code is as below. The Main class is the starting point.
AbstracTransaction is the aspect to capture EntityManager instance, which
will create transaction covering the method executed e.g. process().

It seems like the the advice of `obtainEntityManager(..)&&cflow(..)' is not
executed because the terminal does not output related information. 

Whilst reading the AspectJ in Action, the percflow indicates that
per-control-flow will create a new instance. So I suppose the specified
percflow(scope()) would only cause an aspect  instance created (because in
the Main class process() is only executed once), wouldn't it? 

Thanks for your help.

I appreciate it. 

package example;

public abstract aspect AbstractTransaction percflow(scope()){

	private EntityManager manager;
	
	protected abstract pointcut tx(); // concreated joint point specified in
AccountTransaction.aj

	protected pointcut obtainEntityManager(EntityManager manager): call(public
void example.AccountDao.setEntityManager(EntityManager)) && args(manager) ;

	protected pointcut scope(): tx() && !cflowbelow(tx());

	Object around(): scope(){
System.out.println("===========> EntityManager:"+manager); // null
		Object result = proceed();
		return result;
	}

	
	void around(EntityManager manager): obtainEntityManager(manager) &&
cflow(tx()){
		this.manager = manager;
System.out.println(">>>>>>>>>>>>>>>  EntityManager:"+this.manager); // seems
not run because console does not print anything related to this line. 
		proceed(manager);
	}
}

//  concrete class specifying the join point to be captured.
package example;

public aspect AccountTransaction extends AbstractTransaction{

        protected pointcut tx(): execution(* example.Main.process());
}

// main class want to be monitored
package example;

import example.EntityManager;

public class Main{
	private AccountDao dao;
	public static void main(String args[]){
		AccountDao d = new AccountDao();
	
d.setEntityManager(PersistenceCreator.createEntityManagerFactory().createEntityManager());
		Main m = new Main(d);
		m.process();
		m.print();
	}

	public Main(AccountDao dao){
		this.dao = dao;
	}

	void process(){
		User u = new User("1", "Smith");
		u.setAddress("7 Unkown Road, London, U.K.");
		dao.save(u);
	}
	void print(){
		dao.list();	
	}
}




Simone Gianni-2 wrote:
> 
> Hi Neo,
> it should work, if you don't find the manager there it could be because 
> two different instances of AbstractTransaction aspect are intercepting 
> the two methods. This happens if you declared your aspect with a 
> specific instantiation rule.
> 
> By default, aspects are singletons. That means that there will be only 
> one instance of AbstractTransaction in your application (well, in your 
> classloader). Since this is sometimes a limit, AspectJ supports 
> different instantiation systems, like perthis, pertarget, percflow 
> etc... If you use one of these construct, then a new instance of your 
> aspect will be created for each "this", each "target" etc.. in this 
> case, when you use this.manager inside your aspect, it could be null 
> cause it is actually a different instance.
> 
> Could you post the complete aspect declaration, so that we can see which 
> instantiation rule you are using?
> 
> 
> Hope this helps,
> Simone
> 
> neo anderson wrote:
>> Thank you very much. Now I am able to obtain EntityManager whilst method
>> setEntityManager get called. 
>>
>> But a new question: how can I assign the captured variable e.g.
>> EntityManager to the variable in an Aspect? For instance, 
>>
>> ... aspect AbstractionTransaction ...{
>>         private EntityManager manager;
>>         void around(EntityManager manager): obtainEntityManager(manager)
>> &&
>> cflow(tx()){
>> System.out.println("manager:"+manager); // manager instance is not null
>>                 this.manager = manager; // but assign to the member of
>> aspect seemingly does not work
>>
>>                 proceed(manager);
>>         }
>>
>> }
>>
>> My AbstractTransaction aspect contains a variable manager and I would
>> like
>> to assign when the setEntityManager get called. Because in the example of
>> Aspectj in Action, the method intercepted will return Connection, which
>> is
>> different from the method I have. Is there any chance to assign the
>> variable
>> so that I can apply entitymanager to the pointcut when scope() is
>> executed?
>> Or what is the right way to do this?
>>
>>        Object around(): scope(){
>> System.out.println("===========> EntityManager:"+manager); // after
>> assigned, it is still null
>>                 Object result = proceed();
>>                 return result;
>>         }
>>
>> Sorry if this question is too newbie. I search on the internet and read
>> again the book Aspectj in Action, but seems there is no such explain. 
>>
>> Thanks for patiently answer my question. 
>>
>> I appreciate it. 
>>
>>
>>
>>
>> Andy Clement wrote:
>>   
>>> The method you are intercepting (setEntityManager) has a void return
>>> type, so your advice should too.  The proceed() call you are using
>>> will ensure your replacement is passed to the setEntityManager call.
>>>
>>> Andy
>>>
>>> 2009/11/4 neo anderson <javadeveloper999@xxxxxxxxxxx>:
>>>     
>>>> Hi Mark & Andy. Thanks for your reply. I really appreciate your help.
>>>>
>>>> I change to use args, but now it thorws message:
>>>>
>>>> [error] incompatible return type applying to method-call(void
>>>> example.AccountDao.setEntityManager(example.EntityManager))
>>>>
>>>> [error] incompatible return type applying to method-call(void
>>>> example.AccountDao.setEntityManager(example.EntityManager))
>>>> dao.setEntityManager(PersistenceCreator.createEntityManagerFactory().createEntityManager());
>>>>
>>>> [warning] advice defined in example.AbstractTransaction has not been
>>>> applied
>>>> [Xlint:adviceDidNotMatch]
>>>>
>>>> I check the syntax and read the example in e.g.
>>>> http://books.google.com.tw/books?id=AKuBlJGl7iUC&pg=PA54&lpg=PA54&dq=aspectj+call+args&source=bl&ots=58KGnyCZiN&sig=5gNdHoekFrDXJne3pVe6UO5tiYQ&hl=zh-TW&ei=kNbxSqTEBumgjAfdnp2WAQ&sa=X&oi=book_result&ct=result&resnum=6&ved=0CB0Q6AEwBQ#v=onepage&q=4-2%20capturing%20the%20parameter%20values%20passed%20on%20a%20method%20call&f=false
>>>>
>>>> The way to capture the EntityManager looks correct.
>>>>
>>>> public pointcut(EntityManager manager): call(*
>>>> AccountDao.setEntityManager(EntityManger)) && args(manager);
>>>>
>>>> Is there any place I may go wrong? I test to move the .aj files and
>>>> compile
>>>> .java source. Everthing works fine. I am confused.
>>>>
>>>> I appreciate any suggestion.
>>>>
>>>> Thank you very much.
>>>>
>>>>
>>>> Mark Cooke-6 wrote:
>>>>       
>>>>> Hi,
>>>>> It's been a while since I've used AspectJ in anger but as no-one else
>>>>> has
>>>>> replied yet...
>>>>>
>>>>> I'd say you probably want "args(manager)" instead of "target(manager)"
>>>>> in
>>>>> the obtainEntityManager pointcut.
>>>>> The target of the call will be an AccountDAO, not an EntityManager.
>>>>>
>>>>> See
>>>>> http://www.eclipse.org/aspectj/doc/released/progguide/semantics-joinPoints.html
>>>>>
>>>>> HTH!
>>>>> Mark.
>>>>>
>>>>> --- On Wed, 4/11/09, neo anderson <javadeveloper999@xxxxxxxxxxx>
>>>>> wrote:
>>>>>
>>>>>         
>>>>>> From: neo anderson <javadeveloper999@xxxxxxxxxxx>
>>>>>> Subject: [aspectj-users] A transaction question
>>>>>> To: aspectj-users@xxxxxxxxxxx
>>>>>> Date: Wednesday, 4 November, 2009, 12:09
>>>>>>
>>>>>> I am learning how to modulize transaction using aspectj,
>>>>>> but encounter a
>>>>>> problem that EntityManager I try to capture is always null.
>>>>>> The compiler
>>>>>> issues message saying that the advice can not be applied.
>>>>>> as below:
>>>>>>
>>>>>> ... advice defined in example.AbstractTransaction has not
>>>>>> been applied
>>>>>> [Xlint:adviceDidNotMatch]
>>>>>>
>>>>>> What should I change so that I can capture the
>>>>>> EntityManager while it is
>>>>>> created (whilst calling to
>>>>>> AccountDao.setEntityManager(..))?
>>>>>>
>>>>>> Thanks for help.
>>>>>>
>>>>>> Main.java
>>>>>>
>>>>>> package example;
>>>>>>
>>>>>> public class Main{
>>>>>>     public static void main(String args[]){
>>>>>>         Main m = new Main();
>>>>>>         m.process();
>>>>>>     }
>>>>>>     void process(){
>>>>>>         AccountDao dao = new
>>>>>> AccountDao();
>>>>>>
>>>>>> dao.setEntityManager(PersistenceCreator.createEntityManagerFactory().createEntityManager());
>>>>>>         User u = new
>>>>>> User("1", "Smith");
>>>>>>         u.setAddress("123
>>>>>> Test Road, London.");
>>>>>>         dao.save(u);
>>>>>>
>>>>>>
>>>>>> dao.list();
>>>>>>     }
>>>>>> }
>>>>>>
>>>>>> AccountDao.java
>>>>>>
>>>>>> package example;
>>>>>>
>>>>>> import java.util.List;
>>>>>> import java.util.ArrayList;
>>>>>>
>>>>>>
>>>>>> public class AccountDao{
>>>>>>
>>>>>>     private EntityManager manager;
>>>>>>
>>>>>>     private static List<User> database
>>>>>> = new ArrayList<User>();
>>>>>>
>>>>>>     public void
>>>>>> setEntityManager(EntityManager manager){
>>>>>>         this.manager =
>>>>>> manager;
>>>>>>     }
>>>>>>
>>>>>>     public void save(User user){
>>>>>>
>>>>>> database.add(user);
>>>>>>     }
>>>>>>
>>>>>>     public void list(){
>>>>>>         for(User u :
>>>>>> database){
>>>>>>
>>>>>> System.out.println(">>>[AccountDao.java]"+u);
>>>>>>
>>>>>>         }
>>>>>>     }
>>>>>> }
>>>>>>
>>>>>> User.java
>>>>>>
>>>>>> package example;
>>>>>>
>>>>>> public class User{
>>>>>>     private String id;
>>>>>>     private String name;
>>>>>>     private String address;
>>>>>>     public User(String id, String name){
>>>>>>         this.id = id;
>>>>>>         this.name = name;
>>>>>>     }
>>>>>>
>>>>>>     public String getId(){
>>>>>>         return this.id;
>>>>>>     }
>>>>>>
>>>>>>     public String getName(){
>>>>>>         return this.name;
>>>>>>     }
>>>>>>
>>>>>>     public String getAddress(){
>>>>>>         return this.address;
>>>>>>     }
>>>>>>
>>>>>>     public void setAddress(String address){
>>>>>>         this.address =
>>>>>> address;
>>>>>>     }
>>>>>>
>>>>>>     public String toString(){
>>>>>>         return "<User
>>>>>> [id:"+id+"][name:"+name+"][address:"+address+"]>";
>>>>>>     }
>>>>>> }
>>>>>>
>>>>>>
>>>>>> PersistenceCreator.java
>>>>>>
>>>>>> package example;
>>>>>>
>>>>>> public class PersistenceCreator{
>>>>>>     private static EntityManagerFactory
>>>>>> factory;
>>>>>>
>>>>>>     public static EntityManagerFactory
>>>>>> createEntityManagerFactory(){
>>>>>>         if(null == factory)
>>>>>>
>>>>>> factory = new EntityManagerFactory();
>>>>>>         return factory;
>>>>>>     }
>>>>>> }
>>>>>>
>>>>>> EntityManagerFactory.java
>>>>>>
>>>>>> package example;
>>>>>>
>>>>>> public class EntityManagerFactory{
>>>>>>
>>>>>>     private static EntityManager manager;
>>>>>>
>>>>>>     public static EntityManager
>>>>>> createEntityManager(){
>>>>>>         if(null == manager){
>>>>>>
>>>>>> manager = new EntityManager();
>>>>>>         }
>>>>>>         return manager;
>>>>>>     }
>>>>>> }
>>>>>>
>>>>>> EntityManager.java
>>>>>>
>>>>>> package example;
>>>>>>
>>>>>> public class EntityManager{
>>>>>> }
>>>>>>
>>>>>> AbstractTransaction.aj
>>>>>>
>>>>>> package example;
>>>>>>
>>>>>> public abstract aspect AbstractTransaction
>>>>>> percflow(scope()){
>>>>>>
>>>>>>     private EntityManager manager;
>>>>>>
>>>>>>     protected abstract pointcut tx();
>>>>>>
>>>>>>     protected pointcut
>>>>>> obtainEntityManager(EntityManager manager): call(*
>>>>>> example.AccountDao.setEntityManager(EntityManager))
>>>>>> && target(manager);
>>>>>>
>>>>>>     protected pointcut scope(): tx()
>>>>>> && !cflowbelow(tx());
>>>>>>
>>>>>>     Object around(): scope(){
>>>>>>
>>>>>> System.out.println("EntityManager:"+manager);// always null
>>>>>>
>>>>>>         Object result =
>>>>>> proceed();
>>>>>>         return result;
>>>>>>     }
>>>>>>
>>>>>>     EntityManager around(EntityManager
>>>>>> manager): obtainEntityManager(manager)
>>>>>> && cflow(tx()){
>>>>>>         if(null == manager){
>>>>>>
>>>>>> manager = proceed(manager);
>>>>>>
>>>>>>         }
>>>>>>           
>>>>>>         return manager;
>>>>>>     }
>>>>>> }
>>>>>>
>>>>>> AccountTransaction.aj
>>>>>>
>>>>>> package example;
>>>>>>
>>>>>> public aspect AccountTransaction extends
>>>>>> AbstractTransaction{
>>>>>>
>>>>>>     protected pointcut tx(): execution(*
>>>>>> example.Main.process());
>>>>>> }
>>>>>> --
>>>>>> View this message in context:
>>>>>> http://old.nabble.com/A-transaction-question-tp26195112p26195112.html
>>>>>> Sent from the AspectJ - users mailing list archive at
>>>>>> Nabble.com.
>>>>>>
>>>>>> _______________________________________________
>>>>>> 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
>>>>>
>>>>>
>>>>>         
>>>> --
>>>> View this message in context:
>>>> http://old.nabble.com/A-transaction-question-tp26195112p26203290.html
>>>> Sent from the AspectJ - users mailing list archive at Nabble.com.
>>>>
>>>> _______________________________________________
>>>> 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
>>>
>>>
>>>     
>>
>>   
> 
> 
> -- 
> Simone Gianni            CEO Semeru s.r.l.           Apache Committer
> http://www.simonegianni.it/
> 
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
> 
> 

-- 
View this message in context: http://old.nabble.com/A-transaction-question-tp26195112p26251917.html
Sent from the AspectJ - users mailing list archive at Nabble.com.



Back to the top