quartz job when used as dataSource the
Hello Everybody,
I am trying to run a spring batch job from quartz cluster. To use Quartz in a cluster mode it is needed to maintain a persistent storage or Datasource. Spring Batch is able to run correctly with org.springframework.scheduling.quartz.SchedulerFac toryBean when in memory repository for quartz is used, but, the configuration load fails when a data source for quartz is introduced. The error refers to a serialization issue as below
Caused by: java.io.NotSerializableException: Unable to serialize JobDataMap for insertion into database because the value of property 'jobLauncher' is not serializable: org.springframework.batch.core.launch.support.Simp leJobLauncher
at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.seria lizeJobData(StdJDBCDelegate.java:3358)
at org.quartz.impl.jdbcjobstore.oracle.OracleDelegate .insertJobDetail(OracleDelegate.java:173)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.store Job(JobStoreSupport.java:1103)
Can somebody tell me how to overcome this problem?
-------------------------------------------------------------------------
configuration usede for quartz SchedulerFactoryBean:
---------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schem...-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<import resource="job-simple1.xml"/>
<bean class="org.springframework.scheduling.quartz.Sched ulerFactoryBean">
<property name="triggers">
<bean id="cronTrigger2" class="org.springframework.scheduling.quartz.CronT riggerBean">
<property name="jobDetail" ref="jobDetail2" />
<property name="cronExpression" value="0/60 * * * * ?" />
</bean>
</property>
<!-- This portion is needed to avail a persistent quartz cluster DB storage-->
<property name="quartzProperties">
<props>
<prop key="org.quartz.scheduler.instanceName">myClustere dScheduler</prop>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<prop key="org.quartz.jobStore.isClustered">true</prop>
<prop key="org.quartz.jobStore.class">org.quartz.impl.jd bcjobstore.JobStoreTX</prop>
<prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
<prop key="org.quartz.jobStore.driverDelegateClass">org. quartz.impl.jdbcjobstore.oracle.OracleDelegate</prop>
</props>
</property>
<property name="dataSource" ref="bdbDataSource"/>
<property name="transactionManager" ref="jtaTransactionManager"/>
<property name="nonTransactionalDataSource" ref="bdbDataSource"/>
<property name="overwriteExistingJobs" value="true"/>
<!-- End of persistent quartz cluster DB storage-->
</bean>
<bean id="jobDetail2" class="org.springframework.scheduling.quartz.JobDe tailBean">
<property name="jobClass" value="com.ppp.saby.batch.JobLauncherDetails" />
<property name="group" value="quartz-batch" />
<property name="jobDataAsMap">
<map>
<entry key="jobName" value-ref="multilineJob"/>
<entry key="jobLocator" value-ref="jobRegistry"/>
<entry key="jobLauncher" value-ref="jobLauncher"/>
</map>
</property>
</bean>
<bean id="jobRegistry" class="org.springframework.batch.core.configuratio n.support.MapJobRegistry" />
<bean id="jobLauncher" class="org.springframework.batch.core.launch.suppo rt.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
<property name="taskExecutor">
<bean class="org.springframework.core.task.SimpleAsyncTa skExecutor" />
</property>
</bean>
</beans>
--------------------------------------------------
Job details form job-simple1.xml
-----------------------------------------------
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" >
<property name="dataSource" ref="bdbDataSource" />
</bean>
<bean id="jobRepository" class="org.springframework.batch.core.repository.s upport.JobRepositoryFactoryBean">
<property name="dataSource" ref="bdbDataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="databaseType" value="oracle" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSou rceTransactionManager">
<property name="dataSource" ref="bdbDataSource" />
</bean>
<batch:job id="multilineJob">
<batch:step id="step1">
<batch:tasklet ref="helloTask">
</batch:tasklet>
</batch:step>
</batch:job>
<!-- Step1 - print hello world -->
<bean id="helloTask" class="com.batch.simpletask.HelloTask">
<property name="taskStartMessage" value="Hello World - the time is now " />
</bean>
--------------------------------------------------
Java class com.ppp.saby.batch.JobLauncherDetails
-------------------------
public class JobLauncherDetails extends QuartzJobBean{
private static Logger log = Logger.getLogger(JobLauncherDetails.class);
private Job job;
private JobLocator jobLocator;
private JobLauncher jobLauncher;
public void setJobLocator(JobLocator jobLocator) {
this.jobLocator = jobLocator;
}
public void setJobLauncher(JobLauncher jobLauncher) {
this.jobLauncher = jobLauncher;
}
public void setJobName(Job job) {
this.job = job;
}
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
JobParametersBuilder jobParametersBuilder = new JobParametersBuilder();
Calendar aDate = new GregorianCalendar();
jobParametersBuilder.addString("dateTime",String.v alueOf(aDate.getTime()));
try {
jobLauncher.run(job, jobParametersBuilder.toJobParameters());
} catch (Exception e) {
}
}
}
---------------------------------------------------------
Can somebody tell me how to overcome this problem?
If some glue code is required to allow the jobLauncher to be serialise, then please provide some example.
Thanks & Regards,
Saby