Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-8471

Performance bottleneck and potential thread deadlock in DefaultSingletonBeanRegistry

    Details

    • Last commented by a User:
      false

      Description

      A less significant version of this problem has already been raised under SPR-5360 - a performance bottleneck affecting Wicket. However, the same issue causes a serious thread deadlock in our application, occasionally preventing application startup.

      The basic issue seems to be that DefaultSingletonBeanRegistry takes a global synchronization lock when creating a singleton bean. Here is the code in that class:

      	public Object getSingleton(String beanName, ObjectFactory singletonFactory) {
      		Assert.notNull(beanName, "'beanName' must not be null");
      		synchronized (this.singletonObjects) {
      			Object singletonObject = this.singletonObjects.get(beanName);
      			if (singletonObject == null) {
      			... stuff ...
      					singletonObject = singletonFactory.getObject();
      			... stuff ...
      	}

      The synchronized block (the same this.singletonObjects reference is used by all threads entering the method) means that Spring can only create singleton beans one at a time, regardless of their type (beanName). This clearly introduces a performance penalty if an application has a large number of singleton beans to construct, e.g. at startup.

      That is not the issue affecting our code, though. We see a deadlock, caused by the following two sets of behaviour:

      1. We have Spring-managed singleton beans which perform database access in their constructor (basically loading and caching configuration sets from the database). In order to do this they obtain database connections, which are pooled, with relatively small pool sizes. If a pooled connection is not available, the calling thread blocks and waits until one becomes free. This is usually not a problem since queries are small and rapid, so pool wait times are low, and the maximum pool size is sufficient to work the databasea at full capacity anyway.

      2. We also have non-Spring code doing database access. Such code obtains a database connection from the same pool, purely for the lifetime of running a query and processing a result set, so again very quick for almost cases in our system. But sometimes, whilst processing the result set, we need to use a Spring-managed bean, which may have singleton scope.

      You now have a deadlock - thread number one is trying to get a Spring-managed singleton bean, which is waiting for a JDBC connection in its constructor; thread number two is running database code which has the JDBC connection and is waiting to create a Spring-managed singleton of a completely different type. Both thread own the resource needed by the other, so will wait forever. (OK, if the database pool size is two or higher you need two or more threads in the second state, but this has happened to us in customer environments, in production).

      Obviously our application code is almost certainly less than ideal in how we use Spring, but it seems to me that we ought to be able to use Spring-managed beans which do database access in the manner I've described, without encountering unpleasant deadlocks such as this. Note that the problem is actually much more general than this particular example of database connections: if your singleton beans require any kind of global monitor, which is also used outside of the context of Spring, you have a deadlock condition.

      Both the originally-reported performance problem, and this deadlock, could be solved by a simple improvement to DefaultSingletonBeanRegistry. The getSingleton() method should not synchronize on a global monitor, but instead a monitor specific to the beanName you are instantiating. This is the correct level at which to lock - what you are trying to do is prevent a bean of a certain type being created more than once, but allowing two beans of different types to construct at the same time is perfectly reasonable. Of course you have to synchronize access to the underlying collections with a global lock, but the construction of the singleton bean does not need to be protected with the same global monitor. For instance I believe this kind of thing would do it:

      	public Object getSingleton(String beanName, ObjectFactory singletonFactory) {
      		Object bean;
      		Object perBeanMonitor;
      		synchronized (GLOBAL_MONITOR) {
      			perBeanMonitor = getPerBeanMonitor(beanName);
      		}
      		synchronized (perBeanMonitor) {
      			synchronized (GLOBAL_MONITOR) {
      				bean = getBeanFromRegistry(beanName);
      			}
      			if (bean==null) {
      				Object bean = doConstructBean(beanName, singletonFactory);
      				synchronized (GLOBAL_MONITOR) {
      					addToRegistry(beanName, bean);
      				}
      			}
      		}
      		return bean;
      	}

      It would be extremely helpful if this approach could be implemented in this core part of the Spring framework. We rely on singleton construction to be performant and thread-safe; the fact that DefaultSingletonBeanRegistry behaves as it currently does is causing us serious production problems at client sites, and, whilst we can modify our application code to work around the issue, I do see this as a fundamental flaw in Spring - would be nice to get a quick fix please.

        Issue Links

          Activity

          Hide
          yesnault Yvonnick Esnault added a comment - - edited

          It's a deadlock :

          "schedulerFactory_Worker-7":
            waiting to lock monitor 0x00007f6830034ca8 (object 0x000000076a3a02f0, a org.apache.cxf.bus.extension.Extension),
            which is held by "HTTP-20"
          "HTTP-20":
            waiting to lock monitor 0x00007f688c001ca8 (object 0x00000007683f4fc8, a java.util.concurrent.ConcurrentHashMap),
            which is held by "schedulerFactory_Worker-7"
          

          with schedulerFactory_Worker-7 like that :

          "schedulerFactory_Worker-7":
            at org.apache.cxf.bus.extension.ExtensionManagerImpl.loadBeansOfType(ExtensionManagerImpl.java:346)
            - waiting to lock <0x000000076a3a02f0> (a org.apache.cxf.bus.extension.Extension)
            at org.apache.cxf.bus.spring.SpringBeanLocator.loadBeansOfType(SpringBeanLocator.java:235)
            at org.apache.cxf.transport.TransportFinder.loadDefaultURIs(TransportFinder.java:212)
            at org.apache.cxf.transport.TransportFinder.findTransportForURI(TransportFinder.java:81)
            at org.apache.cxf.bus.managers.ConduitInitiatorManagerImpl.getConduitInitiatorForUri(ConduitInitiatorManagerImpl.java:149)
            at org.apache.cxf.transport.TransportURIResolver.resolve(TransportURIResolver.java:102)
            at org.apache.cxf.catalog.CatalogWSDLLocator.getImportInputSource(CatalogWSDLLocator.java:112)
            at org.apache.cxf.wsdl11.AbstractWrapperWSDLLocator.getImportInputSource(AbstractWrapperWSDLLocator.java:85)
            at com.ibm.wsdl.xml.WSDLReaderImpl.parseImport(WSDLReaderImpl.java:388)
            at com.ibm.wsdl.xml.WSDLReaderImpl.parseDefinitions(WSDLReaderImpl.java:312)
            at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(WSDLReaderImpl.java:2352)
            at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(WSDLReaderImpl.java:2338)
            at org.apache.cxf.wsdl11.WSDLManagerImpl.loadDefinition(WSDLManagerImpl.java:261)
            at org.apache.cxf.wsdl11.WSDLManagerImpl.getDefinition(WSDLManagerImpl.java:206)
            at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.isEmptywsdl(ReflectionServiceFactoryBean.java:2607)
            at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.isFromWsdl(ReflectionServiceFactoryBean.java:543)
            at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.initializeServiceModel(ReflectionServiceFactoryBean.java:547)
            at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.create(ReflectionServiceFactoryBean.java:265)
            - locked <0x0000000760d89360> (a org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean)
            at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.create(JaxWsServiceFactoryBean.java:215)
            at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpoint(AbstractWSDLBasedEndpointFactory.java:102)
            at org.apache.cxf.frontend.ClientFactoryBean.create(ClientFactoryBean.java:91)
            at org.apache.cxf.frontend.ClientProxyFactoryBean.create(ClientProxyFactoryBean.java:157)
            - locked <0x00000007652d5470> (a org.apache.cxf.jaxws.spring.JaxWsProxyFactoryBeanDefinitionParser$JAXWSSpringClientProxyFactoryBean)
            at org.apache.cxf.jaxws.JaxWsProxyFactoryBean.create(JaxWsProxyFactoryBean.java:142)
            - locked <0x00000007652d5470> (a org.apache.cxf.jaxws.spring.JaxWsProxyFactoryBeanDefinitionParser$JAXWSSpringClientProxyFactoryBean)
            at org.apache.cxf.jaxws.spring.JaxWsProxyFactoryBeanDefinitionParser$JAXWSSpringClientProxyFactoryBean.create(JaxWsProxyFactoryBeanDefinitionParser.java:79)
            at org.apache.cxf.jaxws.spring.JaxWsProxyFactoryBeanDefinitionParser$JAXWSSpringClientProxyFactoryBean.getObject(JaxWsProxyFactoryBeanDefinitionParser.java:83)
            - locked <0x00000007652d5470> (a org.apache.cxf.jaxws.spring.JaxWsProxyFactoryBeanDefinitionParser$JAXWSSpringClientProxyFactoryBean)
            at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142)
            at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:102)
            - locked <0x00000007683f4fc8> (a java.util.concurrent.ConcurrentHashMap)
            at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1468)
            at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:249)
            at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
            at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:444)
            at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:418)
            at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:546)
            at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150)
            at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
            at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:303)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1146)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
            at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
            at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
            - locked <0x00000007683f4fc8> (a java.util.concurrent.ConcurrentHashMap)
            at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
            at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
            at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:444)
            at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:418)
            at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:546)
            at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150)
            at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
            at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:303)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1146)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
            at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
            at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
            - locked <0x00000007627c2780> (a java.util.concurrent.ConcurrentHashMap)
            at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
            at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
            at org.springframework.aop.target.LazyInitTargetSource.getTarget(LazyInitTargetSource.java:67)
            - locked <0x000000076713cf48> (a org.springframework.aop.target.LazyInitTargetSource)
            at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.getTarget(CglibAopProxy.java:663)
            at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:614)
          [...]
          

          and HTTP-20 :

          "HTTP-20":
          	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:181)
          	- waiting to lock <0x00000007683f4fc8> (a java.util.concurrent.ConcurrentHashMap)
          	at org.springframework.beans.factory.support.AbstractBeanFactory.isSingleton(AbstractBeanFactory.java:386)
          	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:356)
          	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:326)
          	at org.springframework.context.support.AbstractApplicationContext.getBeanNamesForType(AbstractApplicationContext.java:1178)
          	at org.apache.cxf.bus.spring.SpringBeanLocator.getBeansOfType(SpringBeanLocator.java:155)
          	at org.apache.cxf.transports.http.internal.QueryHandlerRegistryImpl.setBus(QueryHandlerRegistryImpl.java:68)
          	at org.apache.cxf.transports.http.internal.QueryHandlerRegistryImpl.<init>(QueryHandlerRegistryImpl.java:43)
          	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
          	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
          	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
          	at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
          	at org.apache.cxf.bus.extension.Extension.load(Extension.java:208)
          	at org.apache.cxf.bus.extension.ExtensionManagerImpl.loadAndRegister(ExtensionManagerImpl.java:214)
          	- locked <0x000000076a3a02f0> (a org.apache.cxf.bus.extension.Extension)
          	at org.apache.cxf.bus.extension.ExtensionManagerImpl.getBeansOfType(ExtensionManagerImpl.java:335)
          	- locked <0x000000076a3a02f0> (a org.apache.cxf.bus.extension.Extension)
          	at org.apache.cxf.bus.spring.SpringBeanLocator.getBeansOfType(SpringBeanLocator.java:163)
          	at org.apache.cxf.bus.CXFBusImpl.getExtension(CXFBusImpl.java:108)
          	at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:203)
          	at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:153)
          	at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:167)
          	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:286)
          	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:211)
          	at javax.servlet.http.HttpServlet.service(HttpServlet.java:734)
          	at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:262)
          	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295)
          	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
          	at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:180)
          	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
          	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
          	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
          [...]
          

          Show
          yesnault Yvonnick Esnault added a comment - - edited It's a deadlock : "schedulerFactory_Worker-7": waiting to lock monitor 0x00007f6830034ca8 (object 0x000000076a3a02f0, a org.apache.cxf.bus.extension.Extension), which is held by "HTTP-20" "HTTP-20": waiting to lock monitor 0x00007f688c001ca8 (object 0x00000007683f4fc8, a java.util.concurrent.ConcurrentHashMap), which is held by "schedulerFactory_Worker-7" with schedulerFactory_Worker-7 like that : "schedulerFactory_Worker-7": at org.apache.cxf.bus.extension.ExtensionManagerImpl.loadBeansOfType(ExtensionManagerImpl.java:346) - waiting to lock <0x000000076a3a02f0> (a org.apache.cxf.bus.extension.Extension) at org.apache.cxf.bus.spring.SpringBeanLocator.loadBeansOfType(SpringBeanLocator.java:235) at org.apache.cxf.transport.TransportFinder.loadDefaultURIs(TransportFinder.java:212) at org.apache.cxf.transport.TransportFinder.findTransportForURI(TransportFinder.java:81) at org.apache.cxf.bus.managers.ConduitInitiatorManagerImpl.getConduitInitiatorForUri(ConduitInitiatorManagerImpl.java:149) at org.apache.cxf.transport.TransportURIResolver.resolve(TransportURIResolver.java:102) at org.apache.cxf.catalog.CatalogWSDLLocator.getImportInputSource(CatalogWSDLLocator.java:112) at org.apache.cxf.wsdl11.AbstractWrapperWSDLLocator.getImportInputSource(AbstractWrapperWSDLLocator.java:85) at com.ibm.wsdl.xml.WSDLReaderImpl.parseImport(WSDLReaderImpl.java:388) at com.ibm.wsdl.xml.WSDLReaderImpl.parseDefinitions(WSDLReaderImpl.java:312) at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(WSDLReaderImpl.java:2352) at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(WSDLReaderImpl.java:2338) at org.apache.cxf.wsdl11.WSDLManagerImpl.loadDefinition(WSDLManagerImpl.java:261) at org.apache.cxf.wsdl11.WSDLManagerImpl.getDefinition(WSDLManagerImpl.java:206) at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.isEmptywsdl(ReflectionServiceFactoryBean.java:2607) at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.isFromWsdl(ReflectionServiceFactoryBean.java:543) at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.initializeServiceModel(ReflectionServiceFactoryBean.java:547) at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.create(ReflectionServiceFactoryBean.java:265) - locked <0x0000000760d89360> (a org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean) at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.create(JaxWsServiceFactoryBean.java:215) at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpoint(AbstractWSDLBasedEndpointFactory.java:102) at org.apache.cxf.frontend.ClientFactoryBean.create(ClientFactoryBean.java:91) at org.apache.cxf.frontend.ClientProxyFactoryBean.create(ClientProxyFactoryBean.java:157) - locked <0x00000007652d5470> (a org.apache.cxf.jaxws.spring.JaxWsProxyFactoryBeanDefinitionParser$JAXWSSpringClientProxyFactoryBean) at org.apache.cxf.jaxws.JaxWsProxyFactoryBean.create(JaxWsProxyFactoryBean.java:142) - locked <0x00000007652d5470> (a org.apache.cxf.jaxws.spring.JaxWsProxyFactoryBeanDefinitionParser$JAXWSSpringClientProxyFactoryBean) at org.apache.cxf.jaxws.spring.JaxWsProxyFactoryBeanDefinitionParser$JAXWSSpringClientProxyFactoryBean.create(JaxWsProxyFactoryBeanDefinitionParser.java:79) at org.apache.cxf.jaxws.spring.JaxWsProxyFactoryBeanDefinitionParser$JAXWSSpringClientProxyFactoryBean.getObject(JaxWsProxyFactoryBeanDefinitionParser.java:83) - locked <0x00000007652d5470> (a org.apache.cxf.jaxws.spring.JaxWsProxyFactoryBeanDefinitionParser$JAXWSSpringClientProxyFactoryBean) at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142) at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:102) - locked <0x00000007683f4fc8> (a java.util.concurrent.ConcurrentHashMap) at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1468) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:249) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:444) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:418) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:546) at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:303) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1146) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) - locked <0x00000007683f4fc8> (a java.util.concurrent.ConcurrentHashMap) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:444) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:418) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:546) at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:303) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1146) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) - locked <0x00000007627c2780> (a java.util.concurrent.ConcurrentHashMap) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) at org.springframework.aop.target.LazyInitTargetSource.getTarget(LazyInitTargetSource.java:67) - locked <0x000000076713cf48> (a org.springframework.aop.target.LazyInitTargetSource) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.getTarget(CglibAopProxy.java:663) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:614) [...] and HTTP-20 : "HTTP-20": at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:181) - waiting to lock <0x00000007683f4fc8> (a java.util.concurrent.ConcurrentHashMap) at org.springframework.beans.factory.support.AbstractBeanFactory.isSingleton(AbstractBeanFactory.java:386) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:356) at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:326) at org.springframework.context.support.AbstractApplicationContext.getBeanNamesForType(AbstractApplicationContext.java:1178) at org.apache.cxf.bus.spring.SpringBeanLocator.getBeansOfType(SpringBeanLocator.java:155) at org.apache.cxf.transports.http.internal.QueryHandlerRegistryImpl.setBus(QueryHandlerRegistryImpl.java:68) at org.apache.cxf.transports.http.internal.QueryHandlerRegistryImpl.<init>(QueryHandlerRegistryImpl.java:43) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:526) at org.apache.cxf.bus.extension.Extension.load(Extension.java:208) at org.apache.cxf.bus.extension.ExtensionManagerImpl.loadAndRegister(ExtensionManagerImpl.java:214) - locked <0x000000076a3a02f0> (a org.apache.cxf.bus.extension.Extension) at org.apache.cxf.bus.extension.ExtensionManagerImpl.getBeansOfType(ExtensionManagerImpl.java:335) - locked <0x000000076a3a02f0> (a org.apache.cxf.bus.extension.Extension) at org.apache.cxf.bus.spring.SpringBeanLocator.getBeansOfType(SpringBeanLocator.java:163) at org.apache.cxf.bus.CXFBusImpl.getExtension(CXFBusImpl.java:108) at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:203) at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:153) at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:167) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:286) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:211) at javax.servlet.http.HttpServlet.service(HttpServlet.java:734) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:262) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:180) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [...]
          Hide
          juergen.hoeller Juergen Hoeller added a comment -

          Hmm that seems to be a deadlock between Spring's singleton lock in the bean factory and some related lock behind a CXF FactoryBean... I'm afraid it's no good idea to wrap Spring bean lookup calls in a custom lock there in CXF, when CXF is currently within a Spring-driven bean creation attempt itself!

          Juergen

          Show
          juergen.hoeller Juergen Hoeller added a comment - Hmm that seems to be a deadlock between Spring's singleton lock in the bean factory and some related lock behind a CXF FactoryBean... I'm afraid it's no good idea to wrap Spring bean lookup calls in a custom lock there in CXF, when CXF is currently within a Spring-driven bean creation attempt itself! Juergen
          Show
          yesnault Yvonnick Esnault added a comment - Some information from the CXF mailing list here http://mail-archives.apache.org/mod_mbox/cxf-users/201311.mbox/%3CA0BA72E3-9696-45EE-BA2D-916F76420769@apache.org%3E
          Hide
          juergen.hoeller Juergen Hoeller added a comment -

          That sounds like they'll relax their custom lock in CXF which is definitely worthwhile.

          I'm afraid we can't relax the singleton lock on our side, otherwise we'd immediately expose ourselves to a deadlock potential during the creation of lazy singletons with dependencies on other lazy singletons...

          So I wonder: What specifically could we do on our side still, while keeping our factory-wide singleton lock?

          Juergen

          Show
          juergen.hoeller Juergen Hoeller added a comment - That sounds like they'll relax their custom lock in CXF which is definitely worthwhile. I'm afraid we can't relax the singleton lock on our side, otherwise we'd immediately expose ourselves to a deadlock potential during the creation of lazy singletons with dependencies on other lazy singletons... So I wonder: What specifically could we do on our side still, while keeping our factory-wide singleton lock? Juergen
          Hide
          juergen.hoeller Juergen Hoeller added a comment -

          I'll keep this marked as resolved for 3.2 then, since I don't see any further changes that we could make without sacrificing our singleton guarantees...

          Juergen

          Show
          juergen.hoeller Juergen Hoeller added a comment - I'll keep this marked as resolved for 3.2 then, since I don't see any further changes that we could make without sacrificing our singleton guarantees... Juergen

            People

            • Assignee:
              juergen.hoeller Juergen Hoeller
              Reporter:
              harloshmark Mark Davies
              Last updater:
              Juergen Hoeller
            • Votes:
              19 Vote for this issue
              Watchers:
              25 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Days since last comment:
                38 weeks, 3 days ago