jfinal与quartz整合时使用数据库存储方式,在启动时会报错,系统无法启动
quartz.properties配置信息如下:
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate org.quartz.jobStore.dataSource = my org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount = 5 org.quartz.threadPool.threadPriority = 5 org.quartz.dataSource.my.connectionProvider.class = com.jfinal.plugin.quartz.ConnectionPoolProvider
AppConfig代码:
public class AppConfig extends JFinalConfig { public static DruidPlugin druidPlugin; @Override public void configPlugin(Plugins me) { // 主系统数据库 String databaseUse = getProperty("databaseUse", "master"); druidPlugin = new DruidPlugin(getProperty(databaseUse + "_jdbcUrl"), getProperty(databaseUse + "_user"), getProperty(databaseUse + "_password").trim(), getProperty(databaseUse + "_jdbcClass")); } }
ConnectionPoolProvider代码:
public class ConnectionPoolProvider implements ConnectionProvider { @Override public Connection getConnection() throws SQLException { return AppConfig.druidPlugin.getDataSource().getConnection(); } @Override public void initialize() throws SQLException { } @Override public void shutdown() throws SQLException { } }
报错信息如下:
Caused by: java.lang.NullPointerException at com.jfinal.plugin.quartz.ConnectionPoolProvider.getConnection(ConnectionPoolProvider.java:13) at org.quartz.utils.DBConnectionManager.getConnection(DBConnectionManager.java:108) at org.quartz.impl.jdbcjobstore.JobStoreSupport.getConnection(JobStoreSupport.java:775)
错误产生原因:
类加载器不同,导致ConnectionPoolProvider中访问AppConfig.druidPlugin(static属性)的时候与系统中实际可用(期望对象)并不是同一对象,导致ConnectionPoolProvider访问到AppConfig.druidPlugin为空
解决办法:
/** * 建议使用 JFinal 手册推荐的方式启动项目 运行此 main * 方法可以启动项目,此main方法可以放置在任意的Class类定义中,不一定要放于此 */ public static void main(String[] args) { // JFinal.start("src/main/webapp", 80, "/", 5); // 不想一个类一个类找的话直接.addHotSwapClassPrefix("org.quartz.") UndertowServer.create(AppConfig.class).addHotSwapClassPrefix("org.quartz.").start(); }
经验总结,借用波总的代码注释:
/** * 仅用于解决项目的 JFinalConfig 继承类打成 jar 包,并且使用 undertow.devMode=true 配置 * 时报出的异常,以上两个条件没有同时成立时无需理会,也就是说没有报异常就无需理会 * * 假定项目中的 JFinalConfig 的继承类 com.abc.MyConfig 被打进了 jar 包并且 * undertow.devMode 设置成了 true,这里在启动项目的时候由于 ClassLoader * 不同会报出以下异常: * Can not create instance of class: com.abc.MyConfig. Please check the config in web.xml * * 解决办法是使用 addHotSwapClassPrefix(...) : * UndertowServer.create(MyConfig.class).addHotSwapClassPrefix("com.abc.").start(); * * 只添加 JFinalConfig 的继承类 com.abc.MyConfig 也可以: * UndertowServer.create(MyConfig.class).addHotSwapClassPrefix("com.abc.MyConfig").start(); * * 注意:该配置对生产环境无任何影响,在打包部署前无需删除该配置 */