Florent Paillard
Florent Paillard

Reputation: 559

How to get Quartz jobs running in a multi-ApplicationContext environment?

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

Answers (2)

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340873

I agree 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

Peter Kriens
Peter Kriens

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

Related Questions