Edit: I am using quartz-2.1.5.jar
. Here's the summary of my classes:
HttpPollingJob
extendsPollingJob
extendsScheduledJob
implementsorg.quartz.Job
Specifically:
1) ScheduledJob
implements Quartz Job
(abstract base class for all my Job
types):
import org.quartz.Job;
import org.quartz.Trigger;
public abstract class ScheduledJob implements Job {
private Trigger trigger;
public ScheduledJob() {
this(null);
}
public ScheduledJob(Trigger trig) {
super();
if(trig == null)
trig = getDefaultTrigger();
setTrigger(trig);
}
public Trigger getTrigger() {
return trigger;
}
public void setTrigger(final Trigger trig) {
trigger = trig;
}
protected abstract Trigger getDefaultTrigger();
}
2) PollingJob
extends ScheduledJob
- all "pollers" poll some resource/endpoint with a specific frequency:
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import com.me.jobs.ScheduledJob;
public abstract class PollingJob extends ScheduledJob {
private static long DEF_FREQUENCY = 10 * 1000; // 10 secs
private String name;
private long frequency;
public PollingJob(final String nm) {
this(nm, DEF_FREQUENCY);
}
public PollingJob(final String nm, final long freq) {
super();
setName(nm);
setFrequency(freq);
}
public abstract void poll(JobExecutionContext context);
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
poll(context);
}
public String getName() {
return name;
}
public void setName(final String nm) {
name = nm;
}
public long getFrequency() {
return frequency;
}
public void setFrequency(final long freq) {
frequency = freq;
}
protected final Trigger getDefaultTrigger() {
TriggerBuilder<?> triggerBuilder = TriggerBuilder.newTrigger()
.startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInMilliseconds(DEF_FREQUENCY));
return triggerBuilder.build();
}
}
3) HttpPollingJob
extends PollingJob
- "HTTP pollers" poll a web server (using HTtpClient):
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.quartz.JobExecutionContext;
import com.me.MonitoredEvent;
import com.me.MonitoredEventRegistrar;
public class HttpPollingJob extends PollingJob {
private String serverURL;
private org.slf4j.Logger logger =
org.slf4j.LoggerFactory.getLogger(HttpPollingJob.class);
public HttpPollingJob(final String nm, final String server) {
super(nm);
setServerURL(server);
}
public String getServerURL() {
return serverURL;
}
public void setServerURL(final String server) {
serverURL = server;
}
@Override
public final void poll(JobExecutionContext context) {
MonitoredEvent event = null;
try {
// This is where we would use HttpClient to connect to a web server and poll it.
System.out.println("Job fired!");
}
catch(Throwable thrown) {
logger.error(thrown.getMessage());
}
}
}
4) JobDriver
- defines several HttpPollingJob
s and uses Quartz to start them:
public class JobDriver {
private List<HttpPollingJob> jobs;
public JobDriver() {
HttpPollingJob job1 = new HttpPollingJob("job-1", "http://www.example.com/1");
HttpPollingJob job2 = new HttpPollingJob("job-2", "http://www.example.com/2");
HttpPollingJob job3 = new HttpPollingJob("job-3", "http://www.example.com/3");
jobs = new ArrayList<HttpPollingJob>();
jobs.add(job1);
jobs.add(job2);
jobs.add(job3);
}
public static void main(String[] args) {
JobDriver driver = new JobDriver();
driver.startJobs();
}
private void startJobs() {
try {
// Obtain a basic SchedulerFactory and fire it up.
SchedulerFactory schedulerFactory = new org.quartz.impl.StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.start();
// Define a job for every declared monitor.
JobBuilder jobBuilder = null;
for(ScheduledJob job : jobs) {
Trigger trigger = job.getTrigger();
jobBuilder = JobBuilder.newJob(job.getClass());
// Bind the current job to this trigger.
scheduler.scheduleJob(jobBuilder.build(), trigger);
// TODO: Shut the scheduler down politely?!?!
}
catch(Throwable exc) {
logger.error(exc.getMessage());
// Force application to kick out.
throw new RuntimeException(exc);
}
}
}
When I run this code I get a perfect startup with no errors or runtime exceptions. If I sprinkle System.out.println
statements I can see every single line of code executing flawlessly. The only problem is, once the program is running, its not printing the "Job fired!" message indicating that the polling job is kicking off.
I've tried every combination of start()
and shutdown()
I can think of to no avail. Can any Quartz mavens look at this code and tell me why the job isn't firing?
In the logs (I configured log4j) I see the Quartz worker thread being created for the scheduled job. I feel like I'm 99% of the way there but am just missing something obvious. Thanks in advance!
@4herpsand7derpsago yes you are right, you are 99% there, I ran your code and there is only one problem in it, the Default constructors are absent in HttpPollingJob
and PollingJob
classes, For that reason Scheduler is not able to create their instances,
Simple Solution add following code in below classes
HttpPollingJob class
public HttpPollingJob() {
}
PollingJob class
public PollingJob() {
}
Bingo, the following messages will be printed
Job fired!
Job fired!
Job fired!
If you want to repeat the trigger, add following code in PollingJob
protected final Trigger getDefaultTrigger() {
TriggerBuilder<?> triggerBuilder = TriggerBuilder
.newTrigger()
.startNow()
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInMilliseconds(DEF_FREQUENCY).repeatForever());
return triggerBuilder.build();
}
Hoping that now I will receive the bounty :)
BONUS
Seems like you want to poll or do something with urls, A better way to pass that using king JobDataMap
Updated JobDriver
import java.util.ArrayList;
import java.util.List;
import org.quartz.JobBuilder;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
public class JobDriver {
private List<HttpPollingJob> jobs;
public JobDriver() {
HttpPollingJob job1 = new HttpPollingJob("job-1",
"http://www.example.com/1");
HttpPollingJob job2 = new HttpPollingJob("job-2",
"http://www.example.com/2");
HttpPollingJob job3 = new HttpPollingJob("job-3",
"http://www.example.com/3");
jobs = new ArrayList<HttpPollingJob>();
jobs.add(job1);
jobs.add(job2);
jobs.add(job3);
}
public static void main(String[] args) {
JobDriver driver = new JobDriver();
driver.startJobs();
}
private void startJobs() {
try {
// Obtain a basic SchedulerFactory and fire it up.
SchedulerFactory schedulerFactory = new org.quartz.impl.StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.start();
// Define a job for every declared monitor.
JobBuilder jobBuilder = null;
for (HttpPollingJob job : jobs) {
Trigger trigger = job.getTrigger();
jobBuilder = JobBuilder.newJob(job.getClass());
jobBuilder.usingJobData("name", job.getName());
jobBuilder.usingJobData("url", job.getServerURL());
// Bind the current job to this trigger.
scheduler.scheduleJob(jobBuilder.build(), trigger);
// TODO: Shut the scheduler down politely?!?!
}
} catch (Throwable exc) {
// Force application to kick out.
throw new RuntimeException(exc);
}
}
}
updated HttpPollingJob
import java.util.Map;
import org.quartz.JobExecutionContext;
public class HttpPollingJob extends PollingJob {
private String serverURL;
private org.slf4j.Logger logger =
org.slf4j.LoggerFactory.getLogger(HttpPollingJob.class);
public HttpPollingJob(final String nm, final String server) {
super(nm);
setServerURL(server);
}
public HttpPollingJob() {
}
public String getServerURL() {
return serverURL;
}
public void setServerURL(final String server) {
serverURL = server;
}
@Override
public final void poll(JobExecutionContext context) {
try {
Map dataMap = context.getJobDetail().getJobDataMap();
String nm = (String)dataMap.get("name");
String url = (String)dataMap.get("url");
// This is where we would use HttpClient to connect to a web server and poll it.
System.out.println("Job fired! name:"+nm+" url:"+url);
}
catch(Throwable thrown) {
logger.error(thrown.getMessage());
}
}
}
new output
Job fired! name:job-1 url:http://www.example.com/1
Job fired! name:job-2 url:http://www.example.com/2
Job fired! name:job-3 url:http://www.example.com/3
Apparently, you have not started the trigger. See Quartz Tutorial or Javadocs:
// Trigger the job to run now, and then every 40 seconds
Trigger trigger = newTrigger()
.withIdentity("myTrigger", "group1")
.startNow()
.withSchedule(simpleSchedule()
.withIntervalInSeconds(40)
.repeatForever())
.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