由于没有找到所需的课程,即使以前的触发者成功开火,也无法检索工作
我有一个用石英定义的cron触发器,该触发器成功地触发了几次,并在某些周期后以错误状态最终处于错误状态,并带有以下消息(类名称和软件包名称已编辑):
org.quartz.JobPersistenceException: Couldn't retrieve job because a required class was not found: xxx.xxx.xxx.MyQuartzJob
at org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveJob(JobStoreSupport.java:1393) [quartz-2.3.2.jar!/:na]
at org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTrigger(JobStoreSupport.java:2864) [quartz-2.3.2.jar!/:na]
at org.quartz.impl.jdbcjobstore.JobStoreSupport$41.execute(JobStoreSupport.java:2805) [quartz-2.3.2.jar!/:na]
at org.quartz.impl.jdbcjobstore.JobStoreSupport$41.execute(JobStoreSupport.java:2803) [quartz-2.3.2.jar!/:na]
at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3864) [quartz-2.3.2.jar!/:na]
at org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTriggers(JobStoreSupport.java:2802) [quartz-2.3.2.jar!/:na]
at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:287) [quartz-2.3.2.jar!/:na]
Caused by: java.lang.ClassNotFoundException: xxx.xxx.xxx.MyQuartzJob
at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[na:1.8.0_302]
at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[na:1.8.0_302]
at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:151) ~[app.jar:2.4.0-SNAPSHOT]
at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[na:1.8.0_302]
at java.lang.Class.forName0(Native Method) ~[na:1.8.0_302]
at java.lang.Class.forName(Class.java:348) ~[na:1.8.0_302]
at org.springframework.util.ClassUtils.forName(ClassUtils.java:284) ~[spring-core-5.2.7.RELEASE.jar!/:5.2.7.RELEASE]
at org.springframework.scheduling.quartz.ResourceLoaderClassLoadHelper.loadClass(ResourceLoaderClassLoadHelper.java:81) ~[spring-context-support-5.2.7.RELEASE.jar!/:5.2.7.RELEASE]
at org.springframework.scheduling.quartz.ResourceLoaderClassLoadHelper.loadClass(ResourceLoaderClassLoadHelper.java:87) ~[spring-context-support-5.2.7.RELEASE.jar!/:5.2.7.RELEASE]
at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.selectJobDetail(StdJDBCDelegate.java:852) ~[quartz-2.3.2.jar!/:na]
at org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveJob(JobStoreSupport.java:1390) [quartz-2.3.2.jar!/:na]
一旦发生了此错误,触发器将自身更新为<代码>错误状态,不会再发射。这里的奇怪之处在于,扳机已经成功发射了几次(有时最多4次),突然间,在其下一次迭代中,触发器未能加载班级。 如果我手动将其状态更新为等待
再次触发更新后一次触发,并恢复时间表:它适用于几个周期,在某些时候,我无法再次启动,而我在上面复制了错误,并将其自身更新为错误
状态。
我不知道为什么或如何解决此问题。在运行单个服务器实例时,石英数据库上没有访问的并发性,因此我不明白为什么在同一版本的已部署服务器上成功找到和加载了类,然后再加载了几次。
数据库中的完全合格的className是正确的(软件包名称 +类名称)。
对此的任何建议将不胜感激。如果需要,请随时询问更多细节。
I have a CRON trigger defined with Quartz, which successfully fires several times and ends up in error state after some cycles, with the following message (class names and package names have been redacted):
org.quartz.JobPersistenceException: Couldn't retrieve job because a required class was not found: xxx.xxx.xxx.MyQuartzJob
at org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveJob(JobStoreSupport.java:1393) [quartz-2.3.2.jar!/:na]
at org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTrigger(JobStoreSupport.java:2864) [quartz-2.3.2.jar!/:na]
at org.quartz.impl.jdbcjobstore.JobStoreSupport$41.execute(JobStoreSupport.java:2805) [quartz-2.3.2.jar!/:na]
at org.quartz.impl.jdbcjobstore.JobStoreSupport$41.execute(JobStoreSupport.java:2803) [quartz-2.3.2.jar!/:na]
at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3864) [quartz-2.3.2.jar!/:na]
at org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTriggers(JobStoreSupport.java:2802) [quartz-2.3.2.jar!/:na]
at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:287) [quartz-2.3.2.jar!/:na]
Caused by: java.lang.ClassNotFoundException: xxx.xxx.xxx.MyQuartzJob
at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[na:1.8.0_302]
at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[na:1.8.0_302]
at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:151) ~[app.jar:2.4.0-SNAPSHOT]
at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[na:1.8.0_302]
at java.lang.Class.forName0(Native Method) ~[na:1.8.0_302]
at java.lang.Class.forName(Class.java:348) ~[na:1.8.0_302]
at org.springframework.util.ClassUtils.forName(ClassUtils.java:284) ~[spring-core-5.2.7.RELEASE.jar!/:5.2.7.RELEASE]
at org.springframework.scheduling.quartz.ResourceLoaderClassLoadHelper.loadClass(ResourceLoaderClassLoadHelper.java:81) ~[spring-context-support-5.2.7.RELEASE.jar!/:5.2.7.RELEASE]
at org.springframework.scheduling.quartz.ResourceLoaderClassLoadHelper.loadClass(ResourceLoaderClassLoadHelper.java:87) ~[spring-context-support-5.2.7.RELEASE.jar!/:5.2.7.RELEASE]
at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.selectJobDetail(StdJDBCDelegate.java:852) ~[quartz-2.3.2.jar!/:na]
at org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveJob(JobStoreSupport.java:1390) [quartz-2.3.2.jar!/:na]
Once this error happens, the trigger updates itself to ERROR
state and won't fire anymore. The strange thing here is that the trigger already fired successfully a few times (sometimes up to 4 times) and suddenly, at its next iteration, fails to load the class.
If I manually update its state to WAITING
again it triggers once right after the update, and resumes its schedule: it works for a few cycles, and at some point fails to launch again with the error I copied above, and updates itself to ERROR
state.
I have no clue as to why, or how to fix this. There is no concurrency of access on the Quartz database as we are running a single server instance, so I don't understand why the class would be successfully found and loaded several times and then not, on the same version of the deployed server.
Fully qualified classname in the database is correct (package name + class name).
Any advice on this would be greatly appreciated. Feel free to ask more details if needed.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是在Spring Boot应用程序中遇到的一个非常常见的问题,Spring Quartz调度程序工厂创建了一个石英调度程序实例,默认情况下,该实例使用
org.springframework.scheduling.quartz.ResourceloDeroDerceloAderoDerclassloadhelpersloadhelper
作为类负载辅助器。可以在您的堆栈跟踪中看到此类负载辅助器。石英使用类负载助手来加载作业实现类。要解决该问题,请将以下属性添加到您的Quartz.properties:
This is a very common problem encountered in Spring Boot applications where the Spring Quartz scheduler factory creates a Quartz scheduler instance that by default uses
org.springframework.scheduling.quartz.ResourceLoaderClassLoadHelper
as the class load helper. This class load helper can be seen in your stack trace. Quartz uses the class load helper to load job implementation classes.To fix the issue, please add the following property to your quartz.properties:
我试图理解为什么我仍然看到错误在配置中更改旧的classloadhelper类的错误,事实证明,我们在云提供商上运行的应用程序中有第二个“隐藏”实例,并带有代码的较旧版本从几个月前。
它重复尝试并且未能触发触发器,因为当时不存在石英作业类,因此将触发器设置为在实际最新实例使用的同一数据库中触发到误差状态。为了解决这种情况,我们只需要摆脱外部实例即可。
抱歉,误导性信息,我在发布此问题时并不知道另一个实例。
I was trying to understand why I was still seeing errors mentioning the old ClassLoadHelper class after changing it in the config, it turns out we had a second "hidden" instance of our app running on our Cloud provider, with an older version of the code from a few months ago.
It repetitively tried and failed to fire the trigger because the Quartz Job class did not exist at that point, thus setting the trigger to error state in the same database used by the real up-to-date instance. To fix this situation, we just had to get rid of the extraneous instance.
Sorry for the misleading info, I was not aware of this other instance when posting this question.
也许您的QRTZ_JOB_DETAILS表存在一些不正确的数据。例如重复的作业名称。
请检查qrtz_job_details,qrtz_triggers表数据
Maybe your qrtz_job_details table existed some incorrect data. e.g. duplicate job name.
please check qrtz_job_details, qrtz_triggers table data