有任务调度需求的人对Quartz应该不会陌生,目前,Quartz的最新版本是2.2.0,该文章也是基于2.2.0版本。为了保证任务调度系统的HA,对于JobStore我采用了数据库存储的方式。系统出现故障时,系统中正在执行的任务会在数据库中保存,并在系统恢复正常后,Quartz根据misfire的处理策略对任务进行重新调度。
Quartz2.2.0默认使用的数据库连接池为c3p0。在OSGI环境中,使用该连接池时,会出现连不上数据库的错误。为了解决该问题:主要有两种思路,(1)查看C3P0的源码,修改其中不适合OSGI环境的地方。(2)对Quartz2.2.0提供其它数据库连接池的支持,比如dbcp。对于第一种方法,C3P0的源码繁多,对于工期紧的项目,工作量大,可行度压力大。对于第二种方法,通过了解Quartz2.2.0的源码,发现可行性较高。
在Quartz中,首先我们看看Quartz是如何使用连接池以及如何设置默认的数据库连接池的。
在StdSchedulerFactory类的instantiate()方法中,有如下一段:
1 //Set up any DataSources2 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3
4 String[] dsNames =cfg.getPropertyGroups(PROP_DATASOURCE_PREFIX);5 for (int i = 0; i < dsNames.length; i++) {6 PropertiesParser pp = newPropertiesParser(cfg.getPropertyGroup(7 PROP_DATASOURCE_PREFIX + "." + dsNames[i], true));8
9 String cpClass = pp.getStringProperty(PROP_CONNECTION_PROVIDER_CLASS, null);10
11 //custom connectionProvider...
12 if(cpClass != null) {13 ConnectionProvider cp = null;14 try{15 cp =(ConnectionProvider) loadHelper.loadClass(cpClass).newInstance();16 } catch(Exception e) {17 initException = new SchedulerException("ConnectionProvider class '" +cpClass18 + "' could not be instantiated.", e);19 throwinitException;20 }21
22 try{23 //remove the class name, so it isn't attempted to be set
24 pp.getUnderlyingProperties().remove(25 PROP_CONNECTION_PROVIDER_CLASS);26
27 setBeanProps(cp, pp.getUnderlyingProperties());28 cp.initialize();29 } catch(Exception e) {30 initException = new SchedulerExc