{"record":{"id":"e51546ba7ac4a0d1","repo":"jeecgboot/JeecgBoot","slug":"e-getmessage","errorCode":null,"errorMessage":"${e.getMessage()}","messagePattern":"\\$\\{e\\.getMessage\\(\\)\\}","errorType":"exception","errorClass":"JeecgBootException","httpStatus":null,"severity":"error","filePath":"jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/quartz/service/impl/QuartzJobServiceImpl.java","lineNumber":155,"sourceCode":"\tprivate void schedulerAdd(String id, String jobClassName, String cronExpression, String parameter) {\n\t\ttry {\n\t\t\t// 启动调度器\n\t\t\tscheduler.start();\n\n\t\t\t// 构建job信息\n\t\t\tJobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(id).usingJobData(\"parameter\", parameter).build();\n\n\t\t\t// 表达式调度构建器(即任务执行的时间)\n\t\t\tCronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);\n\n\t\t\t// 按新的cronExpression表达式构建一个新的trigger\n\t\t\tCronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(id).withSchedule(scheduleBuilder).build();\n\n\t\t\tscheduler.scheduleJob(jobDetail, trigger);\n\t\t} catch (SchedulerException e) {\n\t\t\tthrow new JeecgBootException(\"创建定时任务失败\", e);\n\t\t} catch (RuntimeException e) {\n\t\t\tthrow new JeecgBootException(e.getMessage(), e);\n\t\t}catch (Exception e) {\n\t\t\tthrow new JeecgBootException(\"后台找不到该类名：\" + jobClassName, e);\n\t\t}\n\t}\n\n\t/**\n\t * 删除定时任务\n\t * \n\t * @param id\n\t */\n\tprivate void schedulerDelete(String id) {\n\t\ttry {\n\t\t\tscheduler.pauseTrigger(TriggerKey.triggerKey(id));\n\t\t\tscheduler.unscheduleJob(TriggerKey.triggerKey(id));\n\t\t\tscheduler.deleteJob(JobKey.jobKey(id));\n\t\t} catch (Exception e) {\n\t\t\tlog.error(e.getMessage(), e);\n\t\t\tthrow new JeecgBootException(\"删除定时任务失败\");","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/quartz/service/impl/QuartzJobServiceImpl.java#L137-L173","documentation":"Thrown by schedulerAdd in the catch(RuntimeException) branch, propagating e.getMessage() verbatim as a JeecgBootException with the original exception chained. This branch sits between SchedulerException and the generic Exception catch, so it captures non-Quartz runtime errors - most notably the ClassNotFoundException or ClassCastException from getClass(jobClassName) when the configured job class is missing or does not implement Job. Note the message is dynamic (${e.getMessage()}), so it surfaces the underlying runtime failure text directly.","triggerScenarios":"jobClassName refers to a class not on the classpath; the class exists but does not implement org.quartz.Job; the class is in a package blocked by the safe-load guard (getClass restricts to org.jeecg.*); a NoSuchMethodException/IllegalAccessException during instantiation.","commonSituations":"Deploying a job whose implementing class was removed/renamed; referencing a class in a non-jeecg package; the class is present but in a module not loaded (microservice split); version upgrade moved the class.","solutions":["Read the wrapped message text - it usually states the exact missing class or the 'must implement Job' violation.","Ensure the job class exists on the runtime classpath under the org.jeecg.* package and implements org.quartz.Job.","If the class was moved, update the jobClassName in the QRTZ/sys_quartz_job record to the new FQN.","Rebuild/redeploy so the module containing the job class is on the classpath."],"exampleFix":"// before: jobClassName = \"com.oldpkg.MyTask\"  (not on classpath / not in org.jeecg.*)\n// after:  // move/recreate the class as org.jeecg.modules.quartz.job.MyJob implements Job\n//         jobClassName = \"org.jeecg.modules.quartz.job.MyJob\"","handlingStrategy":"validation","validationCode":"// Validate the job class before scheduling\nprivate static boolean isSchedulableJobClass(String fqn) {\n    try {\n        Class<?> c = Class.forName(fqn);\n        return c.getName().startsWith(\"org.jeecg.\") && org.quartz.Job.class.isAssignableFrom(c);\n    } catch (ClassNotFoundException e) {\n        return false;\n    }\n}\nif (!isSchedulableJobClass(jobClassName)) { /* reject before schedulerAdd */ }","typeGuard":"private static boolean isQuartzJobClass(String fqn) {\n    try {\n        Class<?> c = Class.forName(fqn);\n        return org.quartz.Job.class.isAssignableFrom(c)\n            && c.getName().startsWith(\"org.jeecg.\");\n    } catch (Throwable t) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    quartzJobService.saveAndSchedule(job);\n} catch (JeecgBootException e) {\n    // message is dynamic (e.getMessage()); if it names a missing class or 'must implement Job',\n    // fix the jobClassName / classpath rather than retrying\n}","preventionTips":["Place job classes under org.jeecg.* and have them implement org.quartz.Job.","Keep the module containing job classes on the runtime classpath in all profiles.","When renaming/moving a job class, update sys_quartz_job records to the new FQN."],"tags":["quartz","scheduling","classpath","configuration"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}