Announcement Announcement Module
Collapse
No announcement yet.
Application event listeners don't seem ever to be removed Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Application event listeners don't seem ever to be removed

    org.springframework.context.event.ApplicationEvent Multicaster interface declares 3 methods for removing application event listeners but they don't seem ever to be called. I think this is root cause of following exception I'm getting when application context gets closed and event multicaster tries to notify all listeners which are being destroyed:

    Code:
    Nov 8, 2010 3:54:30 PM org.apache.catalina.core.StandardService stop
    INFO: Stopping service Catalina
    Nov 8, 2010 3:54:30 PM org.apache.catalina.core.ApplicationContext log
    INFO: Destroying Spring FrameworkServlet 'sample'
    Nov 8, 2010 3:54:30 PM org.apache.catalina.core.ApplicationContext log
    INFO: Closing Spring root WebApplicationContext
    913888 [main] WARN  org.springframework.context.support.AbstractApplicationContext - Exception thrown from ApplicationListener handling ContextClosedEvent
    org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'sampleAuthenticationSuccessEventListener': Singleton bean creation not allowed while the singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:209) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288) ~[spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.context.event.AbstractApplicationEventMulticaster.getApplicationListeners(AbstractApplicationEventMulticaster.java:148) ~[spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:86) ~[spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:303) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:305) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1007) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:970) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.webflow.engine.Flow.destroy(Flow.java:597) [spring-webflow-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    	at org.springframework.webflow.engine.builder.DefaultFlowHolder.destroy(DefaultFlowHolder.java:100) [spring-webflow-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    	at org.springframework.webflow.definition.registry.FlowDefinitionRegistryImpl.destroy(FlowDefinitionRegistryImpl.java:114) [spring-webflow-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    	at org.springframework.webflow.config.FlowRegistryFactoryBean.destroy(FlowRegistryFactoryBean.java:161) [spring-webflow-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    	at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:184) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:487) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:463) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:431) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1048) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1022) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:970) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.web.context.ContextLoader.closeWebApplicationContext(ContextLoader.java:378) [spring-web-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.web.context.ContextLoaderListener.contextDestroyed(ContextLoaderListener.java:78) [spring-web-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:4011) [catalina.jar:6.0.26]
    	at org.apache.catalina.core.StandardContext.stop(StandardContext.java:4615) [catalina.jar:6.0.26]
    	at org.apache.catalina.core.ContainerBase.removeChild(ContainerBase.java:924) [catalina.jar:6.0.26]
    	at org.apache.catalina.startup.HostConfig.undeployApps(HostConfig.java:1319) [catalina.jar:6.0.26]
    	at org.apache.catalina.startup.HostConfig.stop(HostConfig.java:1290) [catalina.jar:6.0.26]
    	at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:323) [catalina.jar:6.0.26]
    	at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119) [catalina.jar:6.0.26]
    	at org.apache.catalina.core.ContainerBase.stop(ContainerBase.java:1086) [catalina.jar:6.0.26]
    	at org.apache.catalina.core.ContainerBase.stop(ContainerBase.java:1098) [catalina.jar:6.0.26]
    	at org.apache.catalina.core.StandardEngine.stop(StandardEngine.java:448) [catalina.jar:6.0.26]
    	at org.apache.catalina.core.StandardService.stop(StandardService.java:587) [catalina.jar:6.0.26]
    	at org.apache.catalina.core.StandardServer.stop(StandardServer.java:744) [catalina.jar:6.0.26]
    	at org.apache.catalina.startup.Catalina.stop(Catalina.java:648) [catalina.jar:6.0.26]
    	at org.apache.catalina.startup.Catalina.start(Catalina.java:615) [catalina.jar:6.0.26]
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_22]
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.6.0_22]
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_22]
    	at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_22]
    	at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289) [bootstrap.jar:6.0.26]
    	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414) [bootstrap.jar:6.0.26]

  • #2
    This seems to be Spring Webflow 2(.2.1) - Spring Framework 3(.0.5) integration bug.

    Attached is very simple project which reproduces this unwanted behavior. Web app has a flow and a bean implementing ApplicationListener (it seems it doesn't matter which event it listens to). When flow is first accessed, it gets instantiated and gets applicationContext set, all by FlowModelFlowBuilder.createFlow method.

    When application is stopped, AbstractApplicationContext publishes ContextClosedEvent event, then singleton references are cleared and disposable beans get destroyed (in DefaultSingletonBeanRegistry's destroySingletons method). FlowRegistryFactoryBean implements DisposableBean so its destroy method gets called, which as a consequence calls destroy on flow registry and flow definitions it holds.

    Destroying loaded flow definition as consequence tries to close flow's referenced application context. Flow's application context tries to signal ContextClosedEvent, and bubbles up that event to it's parent. Parent context when requested for listeners of ContextClosedEvent, tries to access by name and type listener bean which has been destroyed thus triggering its new instantiation which is forbidden since parent context is in singletonsCurrentlyInDestruction state resulting in this nasty warning with stack trace from thrown BeanCreationNotAllowedException being printed.

    Maybe this would not happen if DefaultSingletonBeanRegistry's destroySingletons, when destroying listener singletons would remove them from collection of listener beans registered in AbstractApplicationEventMulticaster (by calling AbstractApplicationEventMulticaster's removeApplicationListener).

    To reproduce this with the attached app, both listener and flow have to instantiated, and they are lazily instantiated so:
    0) deploy and start the application
    1) go to http://localhost:8080/foo.bar/j_spring_security_logout
    2) go to http://localhost:8080/foo.bar/dummy.htm
    3) at login screen submit dummy/dummy as username/password
    4) stop the application server

    you should get something like this:

    Code:
    INFO: Stopping service Catalina
    [2011-01-03 02:58:10.340] 88227 [main] INFO  org.springframework.context.support.AbstractApplicationContext - Closing WebApplicationContext for namespace 'Spring MVC Dispatcher Servlet-servlet': startup date [Mon Jan 03 02:56:46 CET 2011]; parent: Root WebApplicationContext
    [2011-01-03 02:58:12.121] 90008 [main] INFO  org.springframework.beans.factory.support.DefaultSingletonBeanRegistry - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@10def14f: defining beans []; parent: org.springframework.beans.factory.support.DefaultListableBeanFactory@5b25d568
    [2011-01-03 02:58:27.683] 105570 [main] INFO  org.springframework.context.support.AbstractApplicationContext - Closing Root WebApplicationContext: startup date [Mon Jan 03 02:56:42 CET 2011]; root of context hierarchy
    [2011-01-03 02:58:45.763] 123650 [main] INFO  org.springframework.beans.factory.support.DefaultSingletonBeanRegistry - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5b25d568: defining beans [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0,org.springframework.format.support.FormattingConversionServiceFactoryBean#0,org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#0,org.springframework.web.servlet.handler.MappedInterceptor#0,viewResolver,org.springframework.binding.convert.service.DefaultConversionService#0,org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser#0,org.springframework.webflow.mvc.builder.MvcViewFactoryCreator#0,org.springframework.webflow.engine.builder.support.FlowBuilderServices#0,flowRegistry,flowExecutor,org.springframework.binding.convert.service.DefaultConversionService#1,org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser#1,flowBuilderServices,org.springframework.webflow.mvc.servlet.FlowHandlerAdapter#0,org.springframework.webflow.mvc.servlet.FlowHandlerMapping#0,mvcViewFactoryCreator,org.springframework.security.web.PortMapperImpl#0,org.springframework.security.web.context.HttpSessionSecurityContextRepository#0,org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy#0,org.springframework.security.authentication.ProviderManager#0,org.springframework.security.access.vote.AffirmativeBased#0,org.springframework.security.web.access.intercept.FilterSecurityInterceptor#0,org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator#0,org.springframework.security.authentication.AnonymousAuthenticationProvider#0,org.springframework.security.web.savedrequest.HttpSessionRequestCache#0,org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint#0,org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0,org.springframework.security.config.http.UserDetailsServiceInjectionBeanPostProcessor#0,org.springframework.security.filterChainProxy,org.springframework.security.core.userdetails.memory.InMemoryDaoImpl#0,org.springframework.security.authentication.dao.DaoAuthenticationProvider#0,org.springframework.security.authentication.DefaultAuthenticationEventPublisher#0,org.springframework.security.authenticationManager,dummyApplicationListener,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor]; root of factory hierarchy
    [2011-01-03 02:58:55.791] 133678 [main] INFO  org.springframework.context.support.AbstractApplicationContext - Closing Flow ApplicationContext [dummy]: startup date [Mon Jan 03 02:57:04 CET 2011]; parent: Root WebApplicationContext
    [2011-01-03 03:19:54.631] 1392518 [main] WARN  org.springframework.context.support.AbstractApplicationContext - Exception thrown from ApplicationListener handling ContextClosedEvent
    org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'dummyApplicationListener': Singleton bean creation not allowed while the singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:209) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288) ~[spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.context.event.AbstractApplicationEventMulticaster.getApplicationListeners(AbstractApplicationEventMulticaster.java:148) ~[spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:86) ~[spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:303) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:305) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1007) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:970) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.webflow.engine.Flow.destroy(Flow.java:597) [spring-webflow-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    	at org.springframework.webflow.engine.builder.DefaultFlowHolder.destroy(DefaultFlowHolder.java:100) [spring-webflow-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    	at org.springframework.webflow.definition.registry.FlowDefinitionRegistryImpl.destroy(FlowDefinitionRegistryImpl.java:114) [spring-webflow-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    	at org.springframework.webflow.config.FlowRegistryFactoryBean.destroy(FlowRegistryFactoryBean.java:161) [spring-webflow-2.2.1.RELEASE.jar:2.2.1.RELEASE]
    	at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:184) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:487) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:463) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:431) [spring-beans-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1048) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1022) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:970) [spring-context-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    	at org.springframework.web.context.ContextLoader.closeWebApplicationContext(ContextLoader.java:378) [spring-web-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    ..

    Comment


    • #3
      Having The Same Problem

      sslavic, I have just diagnosed the exact same problem in our application.

      We had just upgraded to Framework 3.0.5 and SWF 2.2.1 as well.

      I wasn't sure if the child AbstractApplicationContext.publishEvent() should be calling its parent's .publishEvent() [lines 304-306] or if (as you've described) the issue is the fact that the listeners should be removed after they've been notified.

      After reading your description, I'm inclined to think it's the latter.

      FWIW, my "Flow ApplicationContext" is a child of my "Root WebApplicationContext" (not sure how transferable those names are, but it's what comes from the .toString() on the ApplicationContext objects).

      Have you created a JIRA issue for this? I think you've got grounds for it.

      Comment


      • #4
        Yes I have https://jira.springsource.org/browse/SPR-7856

        Not sure if it's issue with spring core, webflow, or just the listeners.

        Comment


        • #5
          I've posted a comment on the issue which identifies where the issue arose (changes to the AbstractApplicationEventMulticaster).

          Unfortunately, I wasn't able to connect it with a prior JIRA issue (either because there wasn't one or the commit comments didn't indicate it).

          The changes were first released under the tag "spring-framework-3.0.0.M2".

          Comment


          • #6
            I have the same problem with spring-3.0.5 and spring-webflow-2.3.0

            As a workaround and following the example in the second patch you can register your own DestructionAwareBeanPostProcessor in the appropiate context.

            Attached there is an example of the bean, just register it as you usally register your beans in your application context.
            Last edited by fmarmar; Jan 11th, 2012, 06:53 AM.

            Comment

            Working...
            X