Couldnt launch jobs with (Spring Batch 2.1.9 + Quartz 2.1.6) integration
Hi,
I am trying to schedule a job using Quartz 2.1.6 framework integrated with Spring Batch 2.1.9 and Spring 3.1.1 version.
I could run the jobs without introducing persistance if i introduce datasource, the job is not invoked through the java file. Please let me know what is the issue. If there is any sample for Quartz 2.1.6 + Spring Batch 2.1.9 + Spring 3.1.1, it would be really great.
Please help me on this ASAP.
PFB the code.
Spring-Quartz.xml
Code:
<?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:batch="http://www.springframework.org/schema/batch"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schem...-beans-3.1.xsd
http://www.springframework.org/schema/batch
http://www.springframework.org/schem...-batch-2.1.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schem...g-jdbc-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<bean id="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="dataSource" ref="quartzDataSource"/>
<property name="transactionManager" ref="quartzTransactionManager"/>
<property name="overwriteExistingJobs" value="false"/>
<property name="waitForJobsToCompleteOnShutdown" value="true"/>
<property name="applicationContextSchedulerContextKey" value="applicationContext"/>
<property name="schedulerContextAsMap">
<map>
<entry key="jobLocator" value-ref="jobRegistry" />
<entry key="jobLauncher" value-ref="jobLauncher" />
</map>
</property>
<property name="triggers">
<list>
<ref bean="simpleTrigger" />
</list>
</property>
<property name="quartzProperties">
<props>
<prop key="org.quartz.scheduler.instanceName">TestBatchScheduler</prop>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<prop key="org.quartz.jobStore.misfireThreshold">100</prop>
<prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
<prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
<prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
<prop key="org.quartz.jobStore.isClustered">true</prop>
<prop key="org.quartz.threadPool.class">org.springframework.scheduling.quartz.SimpleThreadPoolTaskExecutor</prop>
<prop key="org.quartz.threadPool.threadCount">30</prop>
<prop key="org.quartz.threadPool.threadPriority">5</prop>
</props>
</property>
</bean>
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
<property name="taskExecutor">
<bean class="org.springframework.core.task.SimpleAsyncTaskExecutor" />
</property>
</bean>
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
<property name="dataSource" ref="quartzDataSource" />
<property name="transactionManager" ref="quartzTransactionManager" />
<property name="databaseType" value="MySQL" />
</bean>
<bean id="jobRegistry" class="org.springframework.batch.core.configuration.support.MapJobRegistry" />
<bean class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
<property name="jobRegistry" ref="jobRegistry"/>
</bean>
<bean id="quartzDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="admin"/>
</bean>
<bean id="quartzTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="quartzDataSource" />
</bean>
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="testJobDetail"/>
<property name="repeatInterval" value="50000"/>
<property name="startDelay" value="1000"/>
</bean>
<bean id="testJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="main.java.runMeJob" />
<property name="jobDataAsMap">
<map>
<entry key="jobName" value="testJob"/>
</map>
</property>
</bean>
<batch:job id="testJob">
<batch:step id="testJobStep">
<batch:tasklet transaction-manager="quartzTransactionManager">
<batch:chunk reader="skynetFileItemReader" writer="skynetFileWriter"
commit-interval="2" />
</batch:tasklet>
</batch:step>
</batch:job>
<bean id="skynetFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resource" value="classpath:main/resources/sample.csv" />
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="names" value="Aircraffid" />
</bean>
</property>
<property name="fieldSetMapper">
<bean class="main.java.SkynetFieldSetMapper" />
</property>
</bean>
</property>
</bean>
<bean id="skynetFileWriter" class="main.java.skynetFileWriter"/>
</beans>
runMeJob.java
Code:
import java.util.Map;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerContext;
import org.springframework.context.ApplicationContext;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.configuration.JobLocator;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
public class runMeJob extends QuartzJobBean {
private static final String JOB_NAME = "jobName";
private static final String JOB_LAUNCH_DATE = "job.launch.date";
private JobLauncher jobLauncher;
protected void executeInternal(JobExecutionContext context)
throws JobExecutionException {
final Map<String, Object> jobDataMap = context.getMergedJobDataMap();
final JobParameters jobParameters = getJobParametersFromJobMap(jobDataMap);
if (jobDataMap.get(JOB_LAUNCH_DATE) == null)
{
final Calendar calender = Calendar.getInstance();
final Date currentDate = calender.getTime();
jobDataMap.put(JOB_LAUNCH_DATE, currentDate);
}
final String jobName = (String) jobDataMap.get(JOB_NAME);
System.out.println("job Name:" + jobName);
if (jobName == null)
{
throw new IllegalStateException("Job Name can't be null");
}
try {
SchedulerContext schedulerContext = context.getScheduler().getContext();
final ApplicationContext applicationContext = (ApplicationContext) schedulerContext.get("applicationContext");
jobLauncher = (JobLauncher) applicationContext.getBean("jobLauncher");
final JobLocator jobLocator = (JobLocator) applicationContext.getBean("jobRegistry",JobLocator.class);
final Job jobToRun = jobLocator.getJob(jobName);
jobLauncher.run(jobToRun, jobParameters);
} catch (Exception e) {
throw new IllegalStateException("Job has exception");
}
}
private JobParameters getJobParametersFromJobMap(
final Map<String, Object> jobDataMap) {
final JobParametersBuilder builder = new JobParametersBuilder();
for (Map.Entry<String, Object> entry : jobDataMap.entrySet()) {
final String key = (String) entry.getKey();
final Object value = entry.getValue();
if (((value instanceof String)) && (!key.equals(JOB_NAME))) {
builder.addString(key, (String) value);
} else if (((value instanceof Float))
|| ((value instanceof Double))) {
builder.addDouble(key,
Double.valueOf(((Number) value).doubleValue()));
} else if (((value instanceof Integer))
|| ((value instanceof Long))) {
builder.addLong(key, Long.valueOf(((Number) value).longValue()));
} else if ((value instanceof Date)) {
builder.addDate(key, (Date) value);
}
}
return builder.toJobParameters();
}
}