Announcement Announcement Module
Collapse

Spring Dynamic Modules forum decommissioned in favor of Eclipse Gemini Blueprint

With the official first release of Eclipse Gemini Blueprint shipped, the migration of the Spring Dynamic Modules code base to the Eclipse Foundation, as part of the Gemini project, has been completed.

As such, this forum has been decommissioned in favour of the Eclipse Gemini forums.
See more
See less
Spring AOP advice as OSGi Service throws BeanCurrentlyInCreationException Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring AOP advice as OSGi Service throws BeanCurrentlyInCreationException

    I am trying to create an spring DM powered OSGi bundle (Bundle-A) which had an AOP advice and a client osgi bundle (Bundle-B) that would use this. In my Bundle-A I have an interface and its Impl in 2 differnet packages. For development, I have exported both the packages in its MANIFEST.MF.

    Now in my Bundle-B I am trying to use the exported class as an AOP advice. First I tried defining a bean with the class as the actual Impl class from Bundle-A(This export of impl is just for dev). When I use this as my aop:aspect for method-before, it works fine and the method in the Bundle-A gets called. But I understand that exposing the impl class is not the right way, so I exported the interface in Bundle-A as an osgi:service and tried refering to it as osgi:reference in Bundle-B. But This is throwing the below exception--

    Code:
    org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'loggerService': Requested bean is currently in creation: Is there an unresolvable circular reference?
    This is the spring file in Bundle-A--
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans ...>
    
    <!-- Expose the interface as a osgi service -->
    <osgi:service id="logger" ref="loggerBean" 		interface="ri.services.samples.aspect.LogService" />
    
    <bean id="loggerBean" class="ri.services.samples.aspect.advice.LogServiceImpl" />
    
    </beans>
    This is the spring file in Bundle-B--

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans ..>
    
    <!-- refer the IMPL class directly -->
    <bean id="aspectBean" class="ri.services.samples.aspect.advice.LogServiceImpl" />
    
    <!-- refer the interface as an osgi service -->
    <osgi:reference id="loggerService" interface="ri.services.samples.aspect.LogService" />
    	
    <!-- AOP config -->
    <aop:config>
    
    	<!-- Works if ref="aspectBean", Throws excpetion if ref="loggerService" -->
    	<aop:aspect id="myAspect" ref="loggerService">
    		<aop:pointcut id="anyPublicOperation" expression="execution(public *  
    
    ri.services.samples.aspect.services.*.dooA1(..))" />
    		<aop:before pointcut-ref="anyPublicOperation" method="justLog" />
    	</aop:aspect>
    </aop:config>
     
    </beans>
    Any help would be greatly appreciated!

    Thanks!

  • #2
    Try changing the mandatory reference to an optional one. Also could you attach the full stracktrace on the forum? Normally the problem occurs if the aspect is trying to apply onto itself.

    Comment


    • #3
      Interesting issue!!!
      Actually it is the expected behavior (unfortunately), although hard to track. I was confused myself and had to see it with my own eyes so I was able to replicate it and see what is going on.
      So here it is:
      The request to create your "logger" service is issued and is put into "singletonsCurrentlyInCreation" by the DefaultSingletonBeanRegistry which means your bean is currently in creation.
      Then the request is made to AbstractAutoProxyCreator via OSGiBundleXmlApplicationConext, as part of the OSGi name space processing logic for <osgi:reference element, to create "logger" bean which itself will be represented as Proxy. Remember, <osgi:reference is nothing more then a shortcut to lookup the service from the OSGi service registry wrapping it into a Proxy while exposing an interface..
      Then as part of the standard Spring Application Life-cycle the post processors are applied on this and every other bean. Since "logger" bean is referenced in the AOP configuration one of the post processors that is applied on it is AspectJAwareAdvisorAutoproxyCreator which attempts to post-process this bean BEFORE instantiation (which means that instantiation of "logger" bean is not finished and bean is still held in the "singletonsCurrentlyInCreation" list of DefaultSingletonBeanRegistry)
      As part of the post processing AspectJAwareAdvisorAutoproxyCreator attempts to find Candidate Advisors to assemble the proxy. This process essentially points to your "logger" service which is still in creation (since it is waiting for post-processors to finish their job) essentially creating circular reference (although dynamically, which means it is hard to spot).
      Code:
      if (!this.singletonsCurrentlyInCreation.add(beanName)) {
      	throw new BeanCurrentlyInCreationException(beanName);
      }
      Although I don't believe it should behave like this it is what is happening now.
      I'll open up a JIRA issue
      Last edited by oleg.zhurakousky; Mar 23rd, 2009, 05:23 PM.

      Comment


      • #4
        Oleg,

        Thanks for taking time to look into this issue! Can you please post the JIRA id so that we can track it? So, looks like we might have to change our design.

        Costin,
        The complete stackrace is too huge and crosses the message reply limit. But tere is the root cause in the stack trace ---

        Code:
        org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'loggerService': Requested bean is currently in creation: Is there an unresolvable circular reference?
        	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:296)
        	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:215)
        	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
        	at org.springframework.beans.factory.support.AbstractBeanFactory.getTypeForFactoryBean(AbstractBeanFactory.java:1198)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryBean(AbstractAutowireCapableBeanFactory.java:627)
        	at org.springframework.beans.factory.support.AbstractBeanFactory.getType(AbstractBeanFactory.java:493)
        	at org.springframework.aop.config.MethodLocatingFactoryBean.setBeanFactory(MethodLocatingFactoryBean.java:68)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1325)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
        	at java.security.AccessController.doPrivileged(AccessController.java:219)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
        	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:219)
        	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:122)
        	at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:479)
        	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:162)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:925)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:835)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:440)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
        	at java.security.AccessController.doPrivileged(AccessController.java:219)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
        	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:219)
        	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:122)
        	at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:495)
        	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:162)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:925)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:835)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:440)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
        	at java.security.AccessController.doPrivileged(AccessController.java:219)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
        	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
        	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:221)
        	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
        	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
        	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
        	at org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans(BeanFactoryAdvisorRetrievalHelper.java:87)
        	at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findCandidateAdvisors(AbstractAdvisorAutoProxyCreator.java:98)
        	at org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator.shouldSkip(AspectJAwareAdvisorAutoProxyCreator.java:105)
        	at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessBeforeInstantiation(AbstractAutoProxyCreator.java:281)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:791)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:762)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:399)
        	at java.security.AccessController.doPrivileged(AccessController.java:219)
        	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
        	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
        	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:221)
        	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
        	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
        	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
        	at org.springframework.osgi.extender.internal.dependencies.startup.MandatoryImporterDependencyFactory.getServiceDependencies(MandatoryImporterDependencyFactory.java:63)
        	at org.springframework.osgi.extender.internal.dependencies.startup.DependencyServiceManager.findServiceDependencies(DependencyServiceManager.java:233)
        	at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor.stageOne(DependencyWaiterApplicationContextExecutor.java:253)
        	at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor.refresh(DependencyWaiterApplicationContextExecutor.java:173)
        	at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.refresh(AbstractDelegatedExecutionApplicationContext.java:136)
        	at org.springframework.osgi.extender.internal.activator.ContextLoaderListener$2.run(ContextLoaderListener.java:741)
        	at java.lang.Thread.run(Thread.java:810)

        Comment


        • #5
          Also changing the reference to optional did not help.

          Comment


          • #6
            Well, if it did I'd be a bit surprised
            As I said the real issues is in AspectJAwareAdvisorAutoproxyCreator which attempts to post-process the Proxy bean that would represent your OSGi service BEFORE the creation of this bean is complete. So essentially it is in the locked state (in creation) but now its been referenced from another bean (AOP config) creation of which is a part of the Post-Processing routine of AspectJAwareAdvisorAutoproxyCreator resulting in a deadlock.

            Comment


            • #7
              Opened a JIRA issue--

              http://jira.springframework.org/browse/OSGI-730

              Comment

              Working...
              X