xkcoding/spring-boot-demo · error · Exception

【定时任务】创建失败!

Error message

【定时任务】创建失败!

What it means

JobServiceImpl.addJob wraps scheduler.scheduleJob(jobDetail, trigger) in try/catch(SchedulerException) and rethrows a generic Exception('【定时任务】创建失败!') at JobServiceImpl.java:62. Note the cron build (CronScheduleBuilder.cronSchedule at line 53) is OUTSIDE the try, so an invalid cron expression escapes uncaught.

Source

Thrown at demo-task-quartz/src/main/java/com/xkcoding/task/quartz/service/impl/JobServiceImpl.java:62

    @Override
    public void addJob(JobForm form) throws Exception {
        // 启动调度器
        scheduler.start();

        // 构建Job信息
        JobDetail jobDetail = JobBuilder.newJob(JobUtil.getClass(form.getJobClassName()).getClass()).withIdentity(form.getJobClassName(), form.getJobGroupName()).build();

        // Cron表达式调度构建器(即任务执行的时间)
        CronScheduleBuilder cron = CronScheduleBuilder.cronSchedule(form.getCronExpression());

        //根据Cron表达式构建一个Trigger
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(form.getJobClassName(), form.getJobGroupName()).withSchedule(cron).build();

        try {
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            log.error("【定时任务】创建失败!", e);
            throw new Exception("【定时任务】创建失败!");
        }

    }

    /**
     * 删除定时任务
     *
     * @param form 表单参数 {@link JobForm}
     * @throws SchedulerException 异常
     */
    @Override
    public void deleteJob(JobForm form) throws SchedulerException {
        scheduler.pauseTrigger(TriggerKey.triggerKey(form.getJobClassName(), form.getJobGroupName()));
        scheduler.unscheduleJob(TriggerKey.triggerKey(form.getJobClassName(), form.getJobGroupName()));
        scheduler.deleteJob(JobKey.jobKey(form.getJobClassName(), form.getJobGroupName()));
    }

    /**

View on GitHub (pinned to 87a142f960)

Solutions

  1. Check scheduler.checkExists(JobKey.jobKey(className, groupName)) before scheduleJob
  2. Ensure the job class implements org.quartz.Job and is loadable by JobUtil.getClass
  3. Validate the cron expression (CronExpression.isValidExpression) before building the schedule
  4. Keep job class+group unique per submission

Example fix

// before
try {
    scheduler.scheduleJob(jobDetail, trigger);
} catch (SchedulerException e) {
    throw new Exception('【定时任务】创建失败!');
}
// after
JobKey jobKey = JobKey.jobKey(form.getJobClassName(), form.getJobGroupName());
if (scheduler.checkExists(jobKey)) {
    throw new IllegalStateException('任务已存在: ' + jobKey);
}
try {
    scheduler.scheduleJob(jobDetail, trigger);
} catch (SchedulerException e) {
    throw new Exception('【定时任务】创建失败!', e);
}
Defensive patterns

Strategy: validation

Validate before calling

JobKey jobKey = JobKey.jobKey(form.getJobClassName(), form.getJobGroupName());
if (scheduler.checkExists(jobKey)) {
    throw new IllegalStateException('job already exists: ' + jobKey);
}
if (!CronExpression.isValidExpression(form.getCronExpression())) {
    throw new IllegalArgumentException('invalid cron: ' + form.getCronExpression());
}

Try / catch

try { jobService.addJob(form); }
catch (Exception e) { if ('【定时任务】创建失败!'.equals(e.getMessage())) { /* surface scheduling failure */ } }

Prevention

When it happens

Trigger: Adding a job whose class+group already exists (ObjectAlreadyExistsException, a SchedulerException); a job class not on the classpath or not implementing org.quartz.Job; a scheduler-store error during scheduleJob.

Common situations: Submitting the same jobClassName twice; a wrong class name in JobForm; clustered Quartz with a conflicting job identity.


AI-assisted analysis of xkcoding/spring-boot-demo@87a142f960 (2026-08-14). Data as JSON: /api/errors/959341cfdc1807e7. Report an issue: GitHub.