Announcement Announcement Module
Collapse
No announcement yet.
Destroy method of session scoped bean cannot access other session scoped bean Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Destroy method of session scoped bean cannot access other session scoped bean

    Hi,
    I have two beans, whose implementation is session scoped. One of them gets the other autowired via its interface, and registers itself as a listener for a particular event. When it is disposed (@PreDestroy), the bean removes the listener to avoid memory leaks.

    The problem: When the session expires, and Spring disposes all session scoped beans, the session is not bound to the current thread (there is no request running).

    Code:
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.eventBus': Scope 'session' 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) ~[spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) ~[spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    	at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:33) ~[spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    	at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.getTarget(Cglib2AopProxy.java:654) ~[spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    	at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:605) ~[spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    	at com.google.common.eventbus.EventBus$$EnhancerByCGLIB$$fd92a9c4.unregister(<generated>) ~[cglib-nodep-2.2.jar:na]
    	at com.siemens.goos.sikmobile.manager.navigation.NextStepManagerImpl.dispose(NextStepManagerImpl.java:190) ~[NextStepManagerImpl.class:na]
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_29]
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.6.0_29]
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_29]
    	at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_29]
    	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:346) ~[spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeDestroyMethods(InitDestroyAnnotationBeanPostProcessor.java:311) ~[spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeDestruction(InitDestroyAnnotationBeanPostProcessor.java:150) ~[spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    	at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:193) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    	at org.springframework.beans.factory.support.DisposableBeanAdapter.run(DisposableBeanAdapter.java:187) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    	at org.springframework.web.context.request.DestructionCallbackBindingListener.valueUnbound(DestructionCallbackBindingListener.java:51) [spring-web-3.1.2.RELEASE.jar:3.1.2.RELEASE]
    	at org.apache.catalina.session.StandardSession.removeAttributeInternal(StandardSession.java:1800) [catalina.jar:7.0.27.A]
    	at org.apache.catalina.session.StandardSession.expire(StandardSession.java:865) [catalina.jar:7.0.27.A]
    	at org.apache.catalina.session.StandardSession.isValid(StandardSession.java:658) [catalina.jar:7.0.27.A]
    	at org.apache.catalina.session.ManagerBase.processExpires(ManagerBase.java:534) [catalina.jar:7.0.27.A]
    	at org.apache.catalina.session.ManagerBase.backgroundProcess(ManagerBase.java:519) [catalina.jar:7.0.27.A]
    	at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1357) [catalina.jar:7.0.27.A]
    	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1537) [catalina.jar:7.0.27.A]
    	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1547) [catalina.jar:7.0.27.A]
    	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1547) [catalina.jar:7.0.27.A]
    	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1526) [catalina.jar:7.0.27.A]
    	at java.lang.Thread.run(Thread.java:662) [na:1.6.0_29]
    I did not find a solution so far. I'm sure that Spring should handle this, so I have created a Jira issue https://jira.springsource.org/browse/SPR-9672

    My current work-around is not removing the listener, and adding a comment that it is not required, as the event source is also session scoped. Of course, this is dirty, as the interface of the bean does not give any clue about the scope, and I do assumptions which may be wrong when implementations change.

    I'm wondering if anyone else has encountered this scenario. A Google search has not revealed a clean work-around.

    Regards, Sebastian Paul

  • #2
    The problem is quite ambiguous. You've registered two beans and both of them are in session scope. Why and how are you able to access a request? If you're using RequestContextHolder in this case with in any of your classes, then this is more of design issue as you're declaring your bean in session scope but still want to use request object. Either both of your beans have to be request scoped or singletons but not session scoped, if you keep using RequestContextHolder from with in code of the two beans. Otherwise, don't use this class RequestContextHolder in your beans at all and then there should not be any issue.

    Comment


    • #3
      The two beans are not interested in the request. They are session scoped, because they are stateful and the state must not be shared among users. I think this scenario is quite common.
      As these beans are always accessed from a request, the session will always be present and the scope can be resolved.
      Except from session end event. Here, the beans are accessed without a request. Spring must still be able to resolve the scope.

      Comment

      Working...
      X