Could not start Quartz Scheduler after delay; nested exception is org.quartz.SchedulerException:

Java项目启动报错:Mybatis映射文件问题
该博客讲述一个Java项目因定时器报错看似无法启动,实则是Mybatis映射文件resultMap填错。起初一直围绕定时器问题查找解决办法无果,后查看报错日志找到根源,修改后项目正常启动。总结指出遇到报错要冷静观察日志以快速定位原因。

问题描述

首先这个项目是存在定时器的,然后看似是定时任务报错导致的项目启动不起来,其实不然。

2020-11-19 15:22:06.141 [restartedMain] INFO  com.alibaba.druid.pool.DruidDataSource 1609 - {dataSource-1} closed
2020-11-19 15:22:06.952  INFO 1352 --- [lerFactoryBean]] o.s.s.quartz.SchedulerFactoryBean        : Starting Quartz Scheduler now, after delay of 1 seconds
2020-11-19 15:22:06.952 [Quartz Scheduler [schedulerFactoryBean]] INFO  org.springframework.scheduling.quartz.SchedulerFactoryBean 665 - Starting Quartz Scheduler now, after delay of 1 seconds
Exception in thread "Quartz Scheduler [schedulerFactoryBean]" org.springframework.scheduling.SchedulingException: Could not start Quartz Scheduler after delay; nested exception is org.quartz.SchedulerException: The Scheduler cannot be restarted after shutdown() has been called.
	at org.springframework.scheduling.quartz.SchedulerFactoryBean$1.run(SchedulerFactoryBean.java:671)
Caused by: org.quartz.SchedulerException: The Scheduler cannot be restarted after shutdown() has been called.
	at org.quartz.core.QuartzScheduler.start(QuartzScheduler.java:557)
	at org.quartz.impl.StdScheduler.start(StdScheduler.java:142)
	at org.springframework.scheduling.quartz.SchedulerFactoryBean$1.run(SchedulerFactoryBean.java:668)

解决过程

在刚开始的时候一直是以为定时任务导致的项目启动不起来,却忽略了上面报错日志。搜了很多关于定时器报错的问题,都没有解决。然后往上一翻原来是有别的报错。就是Mybatis的映射文件resultMap填错了。改完之后就好了。

在这里插入图片描述

总结

在遇到报错的时候,一定要沉着冷静,好好观察日志。再观察完日志之后,才能快速的锁定报错原因。

在Spring与Quartz集成的过程中,如果调度器启动失败,并提示 `org.springframework.context.ApplicationContextException: Failed to start bean 'quartzScheduler'`,且嵌套异常为 `org.springframework.scheduling.SchedulingException: Could not start Quartz Scheduler`,最终错误指向 `org.quartz.SchedulerConfigException: Failure occured during job recovery` 和 `org.quartz.impl.jdbcjobstore.LockException: Table 'java_mer_trip.QRTZ_LOCKS' doesn't exist`,这表明 Quartz 无法在数据库中找到必要的表结构,尤其是 `QRTZ_LOCKS` 表[^1]。 ### 问题分析 Quartz 支持两种任务存储方式:内存模式(RAMJobStore)和数据库模式(JDBCJobStore)。当使用数据库持久化任务时,Quartz 依赖一组预定义的数据库表来存储任务、触发器、调度器状态等信息。如果这些表缺失或结构不完整,调度器将无法正常启动。 错误信息中的 `QRTZ_LOCKS` 表是 Quartz 在集群环境下用于保证多个调度器节点之间一致性的重要表。如果该表不存在,Quartz 在尝试恢复任务或获取锁时会抛出 `LockException`,从而导致调度器启动失败。 ### 解决方案 1. **确认 Quartz 使用的 JobStore 类型** 在 Spring 的 Quartz 配置中,需检查 `org.quartz.jobStore.class` 是否设置为 `org.quartz.impl.jdbcjobstore.JobStoreTX` 或 `org.quartz.impl.jdbcjobstore.JobStoreCMT`,这表明使用的是数据库持久化模式: ```properties org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX ``` 2. **创建 Quartz 所需的数据库表** Quartz 提供了标准的 SQL 脚本用于创建所需的表结构。根据所使用的数据库类型(如 MySQL、PostgreSQL、Oracle、SQL Server 等),从 Quartz 官方或其源码中获取对应的建表脚本,并在目标数据库中执行。 - MySQL 示例建表语句片段: ```sql CREATE TABLE QRTZ_JOB_DETAILS( JOB_NAME VARCHAR(200) NOT NULL, JOB_GROUP VARCHAR(200) NOT NULL, DESCRIPTION VARCHAR(250) NULL, JOB_CLASS_NAME VARCHAR(250) NOT NULL, IS_DURABLE VARCHAR(1) NOT NULL, IS_VOLATILE VARCHAR(1) NOT NULL, IS_STATEFUL VARCHAR(1) NOT NULL, REQUESTS_RECOVERY VARCHAR(1) NOT NULL, JOB_DATA BLOB NULL, PRIMARY KEY (JOB_NAME, JOB_GROUP) ); ``` 类似地,确保创建 `QRTZ_LOCKS`、`QRTZ_TRIGGERS`、`QRTZ_SCHEDULER_STATE` 等关键表。 3. **检查数据库连接配置** 确保 Spring 配置文件中 Quartz 的数据源配置正确,包括数据库 URL、用户名、密码等信息。例如: ```properties org.quartz.dataSource.myDS.driver=com.mysql.cj.jdbc.Driver org.quartz.dataSource.myDS.URL=jdbc:mysql://localhost:3306/your_database org.quartz.dataSource.myDS.user=root org.quartz.dataSource.myDS.password=root ``` 4. **验证 Quartz 表是否存在并更新数据** 如果数据库中已有部分 Quartz 表但结构不完整,建议清空旧表并重新执行建表脚本。可使用如下语句删除旧表(以 MySQL 为例): ```sql DROP TABLE IF EXISTS QRTZ_LOCKS; DROP TABLE IF EXISTS QRTZ_JOB_DETAILS; DROP TABLE IF EXISTS QRTZ_TRIGGERS; -- 依次删除其他相关表 ``` 5. **避免类路径变更导致的 Job 恢复失败** 如果任务类的包路径发生变化,而数据库中仍保留旧的类路径信息,会导致 Quartz 无法正确恢复任务。此时应清理 `QRTZ_JOB_DETAILS` 表中的相关记录,或更新其中的 `JOB_CLASS_NAME` 字段为新的类路径[^4]。 6. **使用正确的连接池配置** 若使用了连接池(如 C3P0),需确保连接池类配置正确,例如: ```properties org.quartz.jobStore.dataSource=myDS org.quartz.jobStore.useProperties=false org.quartz.dataSource.myDS.connectionProvider.class=org.quartz.utils.C3p0PoolingConnectionProvider ``` 如果出现 `ConnectionProvider class could not be instantiated` 错误,需检查依赖库是否完整,尤其是 Quartz 与连接池相关的 JAR 文件是否引入[^2]。 ---
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

怪 咖@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值