与Spring一起使用时出现Quartz持久性作业问题

时间:2014-05-05 08:55:50

标签: java spring quartz-scheduler

我已经配置了一个弹簧的方法,之前调用了一个正常工作的方法。现在我的要求是将此作业保持为持久性,这将在集群环境中运行。 将quartz配置为集群和持久性后,应用程序在部署时抛出以下异常:

  

java.io.NotSerializableException:无法为JobDataMap序列化   因为属性'methodInvoker'的值而插入数据库   不可序列化:   org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean

我使用以下版本:

  • Spring版本3.1.4.RELEASE
  • Quartz版本2.1.7

更新:根据MethodInvokingJobDetailFactoryBean的文档:

JobDetails created via this FactoryBean are not serializable.

因此,寻找一些在春季配置持久作业的替代方法。

3 个答案:

答案 0 :(得分:7)

我已将MethodInvokingJobDetailFactoryBean替换为JobDetailFactoryBean,从而解决了问题。其配置如下:

<bean name="myJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
    <property name="jobClass" value="mypackage.MyJob" />
    <property name="group" value="MY_JOBS_GROUP" />
    <property name="durability" value="true" />
</bean>

但是,对于我的作业类Autowire中的mypackage.MyJob弹簧托管bean,我在执行方法中添加了以下内容作为第一行:

class MyJob implements Job {
    ...
    public void execute(final JobExecutionContext context) throws JobExecutionException {
        // Process @Autowired injection for the given target object, based on the current web application context. 
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
        ...
    }

}

希望它能帮助其他人面对同样的问题。

答案 1 :(得分:6)

使用持久性水晶作业时,应将org.quartz.jobStore.useProperties属性设置为true。这会强制将作业数据保存为Strings而不是Java Serialized对象。

但是这样做可能会导致Spring出现一些问题,这些问题很容易解决。

检查这些链接以获取更多详细信息:

http://site.trimplement.com/using-spring-and-quartz-with-jobstore-properties/

http://forum.spring.io/forum/spring-projects/container/121806-quartz-error-ioexception

答案 2 :(得分:0)

解决此问题的另一种方法是避免对'JobDetailFactoryBean'bean使用'jobDataMap'属性。而是在Scheudler中使用'schedulerContextAsMap'属性添加依赖项(要运行的包含bean的方法)。

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
     ... (other properties)...
     <property name="schedulerContextAsMap">
     <map>
       <entry key="executeProcessBean" value-ref="executeProcessBean" />
     </map>
  </property>
</bean>

因此,SchedulerFactoryBean中的schedulerContextAsMap文档提到了使用Spring bean时的用法。

/**
     * Register objects in the Scheduler context via a given Map.
     * These objects will be available to any Job that runs in this Scheduler.
     * <p>Note: When using persistent Jobs whose JobDetail will be kept in the
     * database, do not put Spring-managed beans or an ApplicationContext
     * reference into the JobDataMap but rather into the SchedulerContext.
     * @param schedulerContextAsMap Map with String keys and any objects as
     * values (for example Spring-managed beans)
     * @see JobDetailFactoryBean#setJobDataAsMap
     */