Reputation: 559
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
Upvotes: 1
Views: 1253
Reputation: 340873
I agree osgi is a good approach, but maybe you can simply crate one huge application context (to rule them all)? Instead of manually starting new child application context based on pluginApplicationContext.xml
file simply add:
<import resource="classpath:/pluginApplicationContext.xml"/>
And this will find all plugins and merge their beans into a single application context. From architecture point of view this is a worse approach, but it will work if you discover all plugins at startup time.
Upvotes: 0
Reputation: 15372
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).
Upvotes: 2