I have been using quartz scheduler to shoot out bulk emails on hourly basis, which is working absolutely fine. This scheduler is explicitly called once. The problem arises when server restarts in the middle of the scheduler execution. Though quartz scheduler creates a record in the JOB_DETAILS table but doesn't take up the task to execute automatically when server starts.
Any help to resolve this is appreciated.
Here are the sample codes and current configuration.
SchedulerFactory factory = new StdSchedulerFactory();
Scheduler scheduler;
try {
scheduler = factory.getScheduler();
// Creating Job and link to our Job class
JobDetailImpl jobDetail = new JobDetailImpl();
jobDetail.setName(jobName);
jobDetail.setJobClass(HelloJob.class);
int repeat = totalBal/Constants.HOURLY_LIMIT;
System.out.println("totalBal : "+totalBal+ " | "+ "repeat : "+repeat);
// Creating schedule time with trigger
SimpleTriggerImpl simpleTrigger = new SimpleTriggerImpl();
simpleTrigger.setStartTime(new Date(
System.currentTimeMillis() + 1000));
simpleTrigger.setRepeatCount(repeat); // SimpleTrigger.REPEAT_INDEFINITELY
//simpleTrigger.setRepeatInterval(3600000);
simpleTrigger.setRepeatInterval(5000);
simpleTrigger.setName(jobName);
// Start scheduler
System.out.println("Scheduler Started");
scheduler.start();
scheduler.getContext().put("externalInstance", cmpgId);
scheduler.scheduleJob(jobDetail, simpleTrigger);
} catch (SchedulerException e) {
Quartz Properties file
# Configure ThreadPool
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 25
org.quartz.threadPool.threadPriority = 5
# Configure JobStore
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.tablePrefix = QRTZ_
# Configure Datasources
org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc:mysql://10.10.10.131:3306/abc
org.quartz.dataSource.myDS.user = product
org.quartz.dataSource.myDS.password = product
org.quartz.dataSource.myDS.maxConnections = 5
org.quartz.dataSource.myDS.validationQuery=select 1
web.xml
...<context-param>
<param-name>quartz:config-file</param-name>
<param-value>quartz.properties</param-value>
</context-param>
<context-param>
<param-name>quartz:shutdown-on-unload</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>quartz:wait-on-shutdown</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>quartz:start-on-load</param-name>
<param-value>true</param-value>
</context-param>
<servlet>
<servlet-name>QuartzInitializer</servlet-name>
<servlet-class>org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class>
<init-param>
<param-name>shutdown-on-unload</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet> ....
You shouln't use the constructor of concrete JobDetail
/Trigger
but use the builder classes JobBuilder
and TriggerBuilder
instead. There you can set the reqeustRecovery
property, which
[i]nstructs the Scheduler whether or not the Job should be re-executed if a 'recovery' or 'fail-over' situation is encountered
JobDetail job = newJob(MyJob.class)
.withIdentity("myJob")
.requestRecovery(true)
.build();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With