문제

I have configured a spring's method invoking job previously which is working fine. Now my requirement is to have this job as persistent which will run in a clustered environment. After configuring the quartz as clustered and persistence, application is throwing the following exception at deployment:

java.io.NotSerializableException: Unable to serialize JobDataMap for insertion into database because the value of property 'methodInvoker' is not serializable: org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean

I am using the following versions:

  • Spring version 3.1.4.RELEASE
  • Quartz version 2.1.7

Update: As per the documentation of MethodInvokingJobDetailFactoryBean:

JobDetails created via this FactoryBean are not serializable.

So, looking for some alternative approach to configure a persistent job in spring.

도움이 되었습니까?

해결책

I have solved the problem by replacing MethodInvokingJobDetailFactoryBean with JobDetailFactoryBean. Configuration for the same is as follows:

<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>

However, to Autowire the spring managed beans in my job class mypackage.MyJob, I have added the following as first line in my execute method:

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);
        ...
    }

}

Hope it it will help someone else facing the same issue.

다른 팁

When you are using persistent quartz jobs, you should be setting the org.quartz.jobStore.useProperties property to true. That forces the job data to be saved as Strings instead of Java Serialized objects.

Doing so however may cause some problems with Spring, that are easily solvable.

Check these links for more details:

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

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

The other way to solve this problem is avoid using 'jobDataMap' property for 'JobDetailFactoryBean' bean. Instead, add the dependency (the bean containing method to run) in Scheudler with 'schedulerContextAsMap' property.

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

Since, the documentation of schedulerContextAsMap in SchedulerFactoryBean mentions about the usage when you have Spring beans.

/**
     * 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
     */

just add implements Serializable

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top