Announcement Announcement Module
Collapse
No announcement yet.
AOP advices in conjuction with TX Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • AOP advices in conjuction with TX

    need a little mental help to get my brain oriented right with AOP/TX in spring....

    recently ran into an error that popped up while using a service inside an AOP advice. namely that the service might not be initialized prior to injecting into the advice/pointcut (typical allowInit warning). the service is proxied as transactional by using the autoproxy on a transactionManager pairing up methods with transaction types. assuming AOP is used behind the scenes. and that when I define my AOP advice the order of which advice (the spring ready made transaction AOP and my own) is unknown.

    to get around the problem i simply marked the service bean with lazy-init equal to true so that it is built only when needed. not at init time (i assume?).

    wondering when using the TX advices with spring 2.0 if one can specify order precedence so the there isn't a conflict of when the service is made into a transactional bean? or am i off the deep end? assuming that the root cause of my origal error was due to unknown order in kicking off AOP advices (trans/my own).

    guess i am looking for a general blueprint for how to configure transactional beans (services) and AOP advices acting on those services (beans).


    thanks in advance / matthew

  • #2
    Can you post your config, please, and the stack trace ?

    Comment


    • #3
      configuration

      below are clips from the Spring XML configuration files and the stack trace:

      service XML file
      Code:
      <bean 
      		id="installingSoftwareService" class="matrix.v.dataaccess.services.activity.InstallingSoftwareServiceImpl">  
                      <!-- adding lazy-init="true" fixes the advice problem -->
      		<property name="installingSoftwareDAO" ref="installingSoftwareDAO"/>
      </bean>

      AOP XML file
      Code:
      <aop:config>
      		<aop:aspect ref="statusControllerAOP">
      			<aop:pointcut id="persist" expression="execution(matrix.v.dataaccess.pojo.activity.InstallingSoftware matrix.v.dataaccess.services.activity.InstallingSoftwareService.setInstallingSoftware(..))"/>
      			<aop:after-returning pointcut-ref="persist" method="afterCompleting" returning="installingSoftware" arg-names="installingSoftware"/>
      		</aop:aspect>
      	</aop:config>
      
      	<aop:config>
      		<aop:aspect ref="statusControllerAOP">
      			<aop:pointcut id="transitory" expression="execution(matrix.v.dataaccess.pojo.activity.InstallingSoftware matrix.v.dataaccess.services.activity.InstallingSoftwareService.setInstallingSoftware(..)) and args(installingSoftware)"/>
      			<aop:before pointcut-ref="transitory" method="beforePersisting" arg-names="installingSoftware"/>
      			<aop:before pointcut-ref="transitory" method="beforeCompleting" arg-names="installingSoftware"/>
      		</aop:aspect>
      	</aop:config>
      
      	<bean id="statusControllerAOP" class="matrix.v.dataaccess.aop.activity.StatusController">
      		<property name="activityPrecedenceService" ref="activityPrecedenceService"/>
      		<property name="installingSoftwareService" ref="installingSoftwareService"/>
      		<property name="hostedSoftwareService" ref="hostedSoftwareService"/>
      		<property name="softwarePackageService" ref="softwarePackageService"/>
      		<property name="environmentService" ref="environmentService"/>
      </bean>

      stack trace
      Code:
      org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'installingSoftwareService': Bean with name 'installingSoftwareService' has been injected into other beans [statusControllerAOP] in its raw version as part of a circular reference, but has eventually been wrapped (for example as part of auto-proxy creation). This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.
      	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:435)
      	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:254)
      	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:144)
      	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:251)
      	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:163)
      	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:284)
      	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:352)
      	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:91)
      	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:75)
      	at matrix.v.dataaccess.utilities.SpringUtil.<init>(SpringUtil.java:13)
      	at matrix.v.dataaccess.utilities.SpringUtil.getInstance(SpringUtil.java:18)
      	at matrix.v.dataaccess.services.activity.InstallingSoftwareServiceTest.setUp(InstallingSoftwareServiceTest.java:21)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      	at java.lang.reflect.Method.invoke(Method.java:585)
      	at org.junit.internal.runners.BeforeAndAfterRunner.invokeMethod(BeforeAndAfterRunner.java:74)
      	at org.junit.internal.runners.BeforeAndAfterRunner.runBefores(BeforeAndAfterRunner.java:50)
      	at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:33)
      	at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75)
      	at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45)
      	at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:71)
      	at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:35)
      	at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42)
      	at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
      	at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52)
      	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
      	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
      	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
      	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
      	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
      	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

      hope this helps. just let me know if i need to supply more info (using spring 2.0.3, java 150_04 from Bea, hibernate 3.2, and testing on windows XP).

      Comment


      • #4
        forgot to post the most important part (transaction)

        forgot the most important configuration (namely the transaction advices):

        management XML file
        Code:
                <!-- Hibernate TM (active in non-container) *installation parameter -->
        	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        		<property name="sessionFactory" ref="sessionFactory"/>
        	</bean>
        	<!--:Transaction attributes for Services -->
        	<bean id="transactionAttributes" class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">
        		<property name="properties">
        			<props>
        				<prop key="get*">PROPAGATION_REQUIRED</prop>
        				<prop key="find*">PROPAGATION_REQUIRED</prop>
        				<prop key="set*">PROPAGATION_REQUIRED</prop>
        				<prop key="create*">PROPAGATION_REQUIRED</prop>
        				<prop key="page*">PROPAGATION_REQUIRED</prop>
        				<prop key="batch*">PROPAGATION_REQUIRED</prop>
        			</props>
        		</property>
        	</bean>
        	<!-- Transaction Interceptor for Services -->
        	<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
        		<property name="transactionManager">
        			<ref bean="transactionManager"/>
        		</property>
        		<property name="transactionAttributeSource">
        			<ref bean="transactionAttributes"/>
        		</property>
        	</bean>
        	<!-- AutoProxy for Services -->
        	<bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
        		<property name="interceptorNames">
        			<value>transactionInterceptor</value>
        		</property>
        		<property name="beanNames">
        			<value>*Service</value>
        		</property>
        	</bean>

        Comment


        • #5
          It is pretty unusual what are you doing there: using 'installingSoftwareService' to add custom behavior (using aop:aspect) to itself.
          As a suggestion, try using 'order' attribute of aop:aspect tag and also 'order' property from BeanNameAutoProxyCreator.

          Comment


          • #6
            suggestions for reworking

            any suggestions for reworking the configuration?

            thought at the Order interface might be the problem. but basically i want to apply business logic dynamically to the service without coding directly in the service implementation. ie. the extra logic that the advice adds against the service may not be necessary in 4/5 months so there is no point in adding it inside the service implementation.


            / matthew

            Comment


            • #7
              This may be too little too late, but...here is what I found to be the problem when I

              This may be too little too late, but...here is what I found to be the problem when I recieved this error....

              (you know which error I mean):

              Code:
              Error creating bean with name 'org.springframework.aop.aspectj.AspectJPointcutAdvisor': Cannot create inner bean '(inner bean)' while setting bean property 'advice'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': Cannot resolve reference to bean 'loggerInterceptor' while setting bean property 'aspectBean'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'loggerInterceptor': Bean with name 'loggerInterceptor' has been injected into other beans [(inner bean)#2, (inner bean)#4] in its raw version as part of a circular reference, but has eventually been wrapped (for example as part of auto-proxy creation). This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.
              I was matching the Interceptor itself when I received that error!
              I believe there is another word for this, it is called Circlular Reference

              Try placing the interceptor in a different package from the one you are matching. And DO NOT match it with a pointcut.

              Thank you,
              Andrew J. Leer

              Comment


              • #8
                P.s.

                I'm not trying to be rude with my large font and all....

                I'm just so happy that the error makes sense now.

                Thank you,
                Andrew J. Leer

                Comment

                Working...
                X