Spring Framework
  1. Spring Framework
  2. SPR-9388

Regression: javax.inject.Provider resolution too agressive

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Critical Critical
    • Resolution: Duplicate
    • Affects Version/s: 3.1.1
    • Fix Version/s: None
    • Component/s: Core
    • Labels:
      None
    • Last commented by a User:
      true

      Description

      It appears something changed between 3.1.0 and 3.1.1 with regards to Provider resolution.

      • I have a request scoped bean injected into a singleton using a Provider.
      • When multiple instance of my singleton are created I get the exception below.

      This code works fine in 3.1.0.Final. Fails when I upgrade to 3.1.1.

      I've included a test case based on the STS MVC project template.

      To duplicate:
      1. Import project into STS
      2. Deploy with Tomcat 7.
      3. Notice Error.
      4. Change spring version in pom.xml to 3.1.0
      5. Restart. Notice No Error.

      ERROR: org.springframework.web.servlet.DispatcherServlet - Context initialization failed
      org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'someSingleton2': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: javax.inject.Provider com.test.provider.SomeSingleton.someRequestBean; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'someRequestBean': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
      	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
      	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
      	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
      	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
      	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
      	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
      	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
      	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
      	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
      	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
      	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
      	at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:631)
      	at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:588)
      	at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:645)
      	at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:508)
      	at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:449)
      	at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:133)
      	at javax.servlet.GenericServlet.init(GenericServlet.java:160)
      	at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1266)
      	at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1185)
      	at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1080)
      	at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5015)
      	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5302)
      	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
      	at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3908)
      	at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:426)
      	at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1350)
      	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1537)
      	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1547)
      	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1547)
      	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1526)
      	at java.lang.Thread.run(Thread.java:722)
      Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: javax.inject.Provider com.test.provider.SomeSingleton.someRequestBean; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'someRequestBean': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
      	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:506)
      	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
      	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
      	... 31 more
      Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'someRequestBean': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
      	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:342)
      	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
      	at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:848)
      	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:790)
      	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707)
      	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.resolvedCachedArgument(AutowiredAnnotationBeanPostProcessor.java:439)
      	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.access$0(AutowiredAnnotationBeanPostProcessor.java:435)
      	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:472)
      	... 33 more
      Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
      	at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
      	at org.springframework.web.context.request.AbstractRequestAttributesScope.get(AbstractRequestAttributesScope.java:40)
      	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:328)
      	... 40 more
      

        Issue Links

          Activity

          Hide
          Mike Youngstrom added a comment -

          A bit of uneducated analysis.

          This error only happens if I have 2 instances of "SomeSingleton".

          Debugging through the problem it appears that AutowiredAnnotationBeanPostProcessor is attempting to cache the processing it does to this class. That is all well and good but when AutowiredAnnotationBeanPostProcessor attempts to use the cached result it appears to send the code down a different resolution path that eventually causes this error.

          If you remove the second "SomeSingleton" bean everything works fine.

          Show
          Mike Youngstrom added a comment - A bit of uneducated analysis. This error only happens if I have 2 instances of "SomeSingleton". Debugging through the problem it appears that AutowiredAnnotationBeanPostProcessor is attempting to cache the processing it does to this class. That is all well and good but when AutowiredAnnotationBeanPostProcessor attempts to use the cached result it appears to send the code down a different resolution path that eventually causes this error. If you remove the second "SomeSingleton" bean everything works fine.
          Hide
          Mike Youngstrom added a comment -

          It appears this is a duplicate of SPR-9181.

          However, because this is a regression from 3.0 and 3.1.0 I think this should be fixed in 3.1.2 not just 3.2. I have projects that cannot upgrade from 3.1.0 because of this regression.

          Show
          Mike Youngstrom added a comment - It appears this is a duplicate of SPR-9181 . However, because this is a regression from 3.0 and 3.1.0 I think this should be fixed in 3.1.2 not just 3.2. I have projects that cannot upgrade from 3.1.0 because of this regression.

            People

            • Assignee:
              Chris Beams
              Reporter:
              Mike Youngstrom
              Last updater:
              Trevor Marshall
            • Votes:
              1 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Days since last comment:
                1 year, 50 weeks, 1 day ago