[xwiki-devs] [VOTE/IDEA] Introduce ApplicationContextInitializer
Hi Devs, I was working on openoffice server auto-start feature and faced a few problems with it. To start the openoffice server when XE is started, I need to send a notification to openoffice server manager when XE is started. The first attempt was to use our ObservationManager component to send startup / shutdown events and let OpenOfficeServerManager listen to them. But this approach requires that OpenOfficeServerManager component is loaded on XE startup so that it can recieve the startup notification. As a solution I tried to use <load-on-startup> components list in plexus.xml file but since OpenOfficeServerManager has a dependancy on ConfigurationSourceCollection component, it fails to load on startup. This is because ConfigurationSourceCollection requires a valid ApplicationContext to be present for it's operation but at the time plexus is loading <load-on-startup> components, no ApplicationContext is present. The core issue is, plexus is initialized before we initialize ApplicationContext; and we can't change this order either. Since the above approach is not going to work, I propose to introduce an ApplicationContextInitializer component pretty much alike RequestInitializer and ExecutionContextInitializer. The idea is to allow any component to do further initializations on ApplicationContext if they need to do so. When XE is started up and an ApplicationContext is created, ApplicationContextInitializerManager will lookup for all the components that implement ApplicationContextInitializer and let them a chance to execute their own initializations. But this doesn't solve the problem of shutdown notifications. For shutdown notifications we can either use the plain old ObservationManager component or we can do the following; rather than having ApplicationContextInitializer and ApplicationContextInitializerManager, we will have ApplicationContextListener and ApplicationContextListenerManager. ApplicationContextListener will have two methods like contextCreated() and contextDestroyed() that will allow any component to perform startup / shutdown tasks. But still, I don't see where we can invoke contextDestroyed() method from, I looked at both servlet container API and portlet container API and couldn't find a consistent way of invoking the contextDestroyed() method. Please let me know what you think about this idea. Thanks. - Asiri
Hi Asiri, On May 6, 2009, at 7:24 AM, Asiri Rathnayake wrote:
Hi Devs,
I was working on openoffice server auto-start feature and faced a few problems with it.
To start the openoffice server when XE is started, I need to send a notification to openoffice server manager when XE is started. The first attempt was to use our ObservationManager component to send startup / shutdown events and let OpenOfficeServerManager listen to them. But this approach requires that OpenOfficeServerManager component is loaded on XE startup so that it can recieve the startup notification.
As a solution I tried to use <load-on-startup> components list in plexus.xml file but since OpenOfficeServerManager has a dependancy on ConfigurationSourceCollection component, it fails to load on startup. This is because ConfigurationSourceCollection requires a valid ApplicationContext to be present for it's operation but at the time plexus is loading <load-on-startup> components, no ApplicationContext is present. The core issue is, plexus is initialized before we initialize ApplicationContext; and we can't change this order either.
Facts: - Right now the Container component is initialized explicitly by calling a container initializer component. This is done at all thread entry points in XWiki and is dependent on the environment (servlet, daemon, portlet, etc). - Since this is tied to the environment we can't autoload the container initialization component at plexus startup (it requires info from the environment) and since the Container is a component it requires plexus to be loaded before it's initialized. - Since we dynamically register components using annotations, I don't think the plexus load on startup configuration option will work (it'll run before we register the components). Need: - Load on startup components but after the Application Context is initialized (at least for components using it). - One reason we need to load some components are startup is because they are accessing resources and we need to ensure these resources are present when the app is started as otherwise it'll fail lazily later on which is bad (better to know when the admin starts the app) - Another need is to do something when the app is started, like store something in the application context Solution: - The one proposed below using ApplicationContextListener/ ApplicationContextListenerManager - Component who need to be started at start time can implement ApplicationContextListener (directly or through another component which would have the component to startup injected as a dependency for ex in order to load it automatically).
Since the above approach is not going to work, I propose to introduce an ApplicationContextInitializer component pretty much alike RequestInitializer and ExecutionContextInitializer. The idea is to allow any component to do further initializations on ApplicationContext if they need to do so. When XE is started up and an ApplicationContext is created, ApplicationContextInitializerManager will lookup for all the components that implement ApplicationContextInitializer and let them a chance to execute their own initializations.
But this doesn't solve the problem of shutdown notifications. For shutdown notifications we can either use the plain old ObservationManager component or we can do the following; rather than having ApplicationContextInitializer and ApplicationContextInitializerManager, we will have ApplicationContextListener and ApplicationContextListenerManager. ApplicationContextListener will have two methods like contextCreated() and contextDestroyed() that will allow any component to perform startup / shutdown tasks.
initializeApplicationContext() destroyApplicationContext()
But still, I don't see where we can invoke contextDestroyed() method from, I looked at both servlet container API and portlet container API and couldn't find a consistent way of invoking the contextDestroyed() method.
For servlet api, in XWikiPlexusServletContextListener you'll override contextDestroyed() and call it. I'm pretty sure the same can be done for portlets. +1 to all this. Don't forget to rename RequestInitializerManager into RequestListenerManager and RequestInitializer into RequestListener. And ExecutionContextInitializer* into ExecutionContextListener* for consistency (since we'll want to implement destroy() methods for them too). Thanks -Vincent
Please let me know what you think about this idea.
Thanks.
- Asiri
participants (2)
-
Asiri Rathnayake -
Vincent Massol