Tuesday, December 23, 2014

Couldn't store job: Unable to serialize JobDataMap for insertion into database because the value of property 'jobLauncher' is not serializable

This occurs during the quartz - spring-batch integration when we are trying to pass in the
JobLauncher object into the quartz class that extens the quartz bean. this can be overcome like below


<bean id="fetchTransaction_quartz" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.incomm.chase.settlement.quartz.FetchTransaction">
</property>
  <property name="jobDataAsMap">  
    <map>
      entry key="timeout" value="5"/>
      <entry key="jobName" value="chaseSettlement"></entry>
      <!--the entries added here will cause a serialization exception -->
          <!--  <entry key="jobLocator" value-ref="jobRegistry"/>  
         <entry key="jobLauncher" value-ref="jobLauncher"/> -->  
   </map>
 </property>
   <property name="durability" value="true"></property>
</bean>

Instead add it in the scheduler

<bean id="fetchScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false">
 <property name="configLocation" value="classpath:quartz.properties"></property>  <property name="dataSource" ref="dataSource"></property>
 <property name="transactionManager" ref="transactionManager"/>
<property name="schedulerContextAsMap">
     <map>
       <entry key="jobLocator" value-ref="jobRegistry" />
         <entry key="jobLauncher" value-ref="jobLauncher" />  
     </map>
  </property>
  <property name="triggers">
      <list>    
     <ref bean="fetchCronTrigger"></ref>
     </list>  
</property>
 <property name="autoStartup" value="true"></property>
</bean>

And it works like a charm..The reason is in the java doc and as below



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

6 comments:

  1. thanks for solution. saved lot of my research time

    ReplyDelete
  2. Thank you very much. You saved my life :P

    ReplyDelete
  3. game saver! Would have been nice for Spring to include your note in its Quartz integration docs:

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

    ReplyDelete