I have a Spring Web application with an applicationContext.xml
loaded through a ContextLoaderListener
in an XmlWebApplicationContext
. The application context has a Quartz scheduler (defined with a SchedulerFactoryBean
like here) but has no trigger nor job details.
During loading of this main application context, I load some "plug-in" JARs containing their own pluginApplicationContext.xml
file.
Each pluginApplicationContext.xml
is loaded in a GenericXmlApplicationContext
as a child of the main XmlWebApplicationContext
.
Those plug-ins may contain Quartz jobs (QuartzJobBean
) which are scheduled within the scheduler discussed above. Scheduling have to be done programmatically through the Quartz API but this is fine for me. When the job is triggered, it is well instanciated by Quartz and, because it extends the QuartzJobBean
, I'm able to get the current ApplicationContext
through setApplicationContext
.
The problem here is that I get the XmlWebApplicationContext
instead of the GenericXmlApplicationContext
from which the job have been scheduled. Thus, I cannot call getBean
to retrieve the beans defined within the plugin.
I well understand why all of this happen. But I cannot find a clean and reusable solution to handle it. I've already had a look at OSGi but we're implementing this plug-in system on an existing application, not creating a new one from scratch and migrating the whole application to OSGi would be too much work to do. Do you know how OSGi and other plug-in frameworks deal with this kind of situation?
Thanks a lot for your help
I am not sure I get all those spring problems but I've done these things with OSGi.
What people often do not realize is that you can embed OSGi in your existing application without making any changes to the existing code. Richard Hall describes it here http://felix.apache.org/site/apache-felix-framework-launching-and-embedding.html (the API is 100% standardized).
Having a framework, you can then run your plugins in the framework. You will have to make sure the framework exports all the application packages (see the org.osgi.framework.system.packages.extra launch property). Plugins and application can then communicate through services.
I've never used Quartz but I've some experience with scheduling. I register a Runnable service with cron like properties:
@Component(properties="cron=1 * * * *") public void SomeImpl implements Runnable { public void run() { ... } }
You will then need to make a bundle that calls that service according to its cron specification).