I am new to java and trying to learn quartz. I have main method
public static void main(String[] args) throws SchedulerException {
try {
JobDetail job1 = JobBuilder.newJob(Job1.class).withIdentity("job1", "group1").build();
Trigger trigger1 = TriggerBuilder.newTrigger().withIdentity("cronTrigger1", "group1")
.withSchedule(CronScheduleBuilder.weeklyOnDayAndHourAndMinute(3, 12, 38)).build();
Scheduler scheduler1 = new StdSchedulerFactory().getScheduler();
scheduler1.start();
scheduler1.scheduleJob(job1, trigger1);
scheduler1.shutdown();
}
catch (Exception e) {
e.printStackTrace();
}
Which works fine. It prints to the console on 3rd day of the week at 12:38 pm.
Now, what I want to do is to reschedule the trigger, so that it deletes the previous stored trigger and creates a new trigger with new schedule.
I read a lot of things at a lot of places but I just can't seem to understand clearly what I actually have to do, for ex:
public void execute(JobExecutionContext context) throws JobExecutionException {
Trigger newTigger = what ever you want;
Trigger oldTrigger = context.getTrigger()
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.rescheduleJob(oldTrigger.getKey(), newTrigger);
}
and also this:
// Define a new Trigger
Trigger trigger = newTrigger()
.withIdentity("newTrigger", "group1")
.startNow()
.build();
// tell the scheduler to remove the old trigger with the given key, and
// put the new one in its place
sched.rescheduleJob(triggerKey("oldTrigger", "group1"), trigger);
but I can't understand the approach(I do understand what is happening in the code though). Thanks in advance.
Related
i have a class where i perform some activities, and i want to create a job that will handle this operation automatically, scheduled every x minutes for example.
I am using Quartz, this class implements Job, and in my driver class i'm creating my jobdetail, scheduler and trigger and then starting it. However, the job isn't being executed, log info :
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
The code for the scheduler in my driver class:
try {
JobDetail job = JobBuilder.newJob(TestMkFPMJob.class).withIdentity("TestMkFPMJob").build();
Trigger trigger = TriggerBuilder.newTrigger().withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(Integer.parseInt(strTimeSched)).repeatForever()).build();
SchedulerFactory schFactory = new StdSchedulerFactory();
Scheduler sch = schFactory.getScheduler();
sch.start();
sch.scheduleJob(job, trigger);
}
catch (SchedulerException e)
{
e.printStackTrace();
System.out.println("Scheduler Error");
}
With "TestMkFPMJob" being the job class where my operations are handled, and strTimeSched is already fetched and set as 120 fetched from
I've been looking for a similar issue but can't seem to find any tip to move forward, appreciate any.
Please note that this is my first time using Quartz/Job scheduling.
The log entry with NOT STARTED is misleading, as it is shown whenever a QuartzScheduler instance is created. It does not mean that the jobs are not running. It is written after the line Scheduler sch = schFactory.getScheduler(); is executed and the scheduler is started in the next line.
If I take your example and run it on my pc, it is working as designed:
public class Quartz {
public static void main(String[] args) {
try {
JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity("myJob").build();
Trigger trigger = TriggerBuilder.newTrigger().withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(Integer.parseInt("10")).repeatForever()).build();
SchedulerFactory schFactory = new StdSchedulerFactory();
Scheduler sch = schFactory.getScheduler();
sch.start();
sch.scheduleJob(job, trigger);
}
catch (SchedulerException e)
{
e.printStackTrace();
System.out.println("Scheduler Error");
}
}
public static class MyJob implements Job {
#Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("runnning job");
}
}
}
public class CronTriggerApp {
public static void main(String[] args) {
try {
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler scheduler = sf.getScheduler();
JobDetail job = JobBuilder.newJob(Main.class)
.withIdentity("dummyJobName", "group1").build();
System.out.println(job);
Date startTime = DateBuilder.nextGivenSecondDate(null, 5);
System.out.println(startTime);
// run every 20 seconds infinite loop
CronTrigger crontrigger = TriggerBuilder
.newTrigger()
.withIdentity("TwentySec", "group1")
.startAt(startTime)
.startNow()
.withSchedule(CronScheduleBuilder.cronSchedule("* * * ? * *"))//0 53 12 * * ? *
.build();
scheduler.start();
scheduler.scheduleJob(job, crontrigger);
//scheduler.shutdown();
} catch (SchedulerException se) {
se.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class Main implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException
{
System.out.println("Trigger Starts.."+new Date());
System.out.println("ALL_OFF");
}
}
By using above code i can able to schedule cron job..but if want cancel the schedule time how can able to cancel or stop the schedule task?
can any one plz help me how can i stop or cancel the scheduled task?
You can expose an endpoint to interrupt it. And use the following function of scheduler to stop it.
scheduler.interrupt(jobDetail.getKey());
Using Timer and TimerTask.
Not able to understand why is this configuration starting the task immediately on deployment (using this in a web based Spring app). It should be started at today.getTime and then must repeat every day.
Calendar today = Calendar.getInstance();
today.set(Calendar.HOUR_OF_DAY, 3);
today.set(Calendar.MINUTE, 0);
today.set(Calendar.SECOND, 0);
MyTask task = new MyTask();
Timer timerJob = new Timer();
timerJob.schedule(task, today.getTime(),
TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS));
I think, it would be better to use CronTrigger or Trigger with 24hours repeat interval.
Example of CronTrigger:
public class CronTriggerRunner {
public static void main(String args[]) throws SchedulerException, Exception {
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
JobDetail job = JobBuilder.newJob(ClassToRun.class).withIdentity("jobName", "group").build();
// Starting CronTrigger
String exp = "0 0 9 * * ?"; //trigger format, everyday at 9:00 am
Trigger trigger = TriggerBuilder.newTrigger()
.startNow()
.withSchedule(
CronScheduleBuilder.cronSchedule(exp))
.build();
// Planning job detail
scheduler.scheduleJob(job, trigger);
// starting scheduler
scheduler.start();
}
}
ClassToRun.java
public class ClassToRun implements Job {
#Override
public void execute(JobExecutionContext context) throws JobExecutionException {
try{
//doSomething
}
catch(Exception e){
e.printStackTrace(System.out);
}
}
}
Everyday at 9:00 am, public void execute() function will doSomething :D
Hope this will help. Please let me know.
EDIT: You need to download and add 2 jar files. 1) quartz-2.2.1.jar 2) slf4j-api-1.6.6.jar
I am using quartz to schedule a daily batch process, and it runs the first days, but it had happened that fires the event for 2 days or so, and then, it stops firing the job.
The java version i'm using is:
java version "1.7.0_25"
Quartz version (in POM):
org.quartz-scheduler
quartz
2.2.1
Here is my code:
Main function for the batch:
public static void main(String[] args) {
try {
SimpleDateFormat sd=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
JobDetail job = JobBuilder.newJob(MyJobClass.class).withIdentity("MyJobClass", "group1").build();
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("MyTrigger", "group1")
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInHours(24).repeatForever())
.startAt(sd.parse("2015-01-12 07:30:00"))
.build();
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);
String strLog="Batch initiated on " + new Date();
System.out.println(strLog);
log.info(strLog);
} catch (Exception e) {
//log error
}
}
And here is my execute method in the job:
public void execute(JobExecutionContext arg0) throws JobExecutionException {
generateBatchProcess();
}
public void generateBatchProcess(){
try{
//do lots of interesting stuff, calling MyBatis Daos, generating excel files and sending an email
}catch (Exception e){
//log error
}
}
Does someone have an idea of why this happens? Is it the garbage collector something to do with this?
I'm ashamed to admit it was only a "BadProgrammerException" because I had a call to a database connection outside the try...catch block that i hadn't seen before, so the problem was that I was not reaching the database and I couldn't figure it out with the log information (the database connection was intermitent). After I found this out, I corrected the database issue and quartz worked ok.
I am running a simple quartz job in main class which runs every 30 secs.
public class Start {
public static void main(String[] args) throws Exception {
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
JobDetail job = newJob(MyJob.class).withIdentity("myJob","XXX").build();
Trigger trigger = TriggerBuilder.newTrigger()
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(30)
.repeatForever())
.build();
sched.scheduleJob(job, trigger);
sched.start();
}
}
Here i am implementing InterruptableJob like
public class MyJob implements InterruptableJob {
private volatile boolean isJobInterrupted = false;
private JobKey jobKey = null;
private volatile Thread thisThread;
public MyJob() {
}
#Override
public void interrupt() throws UnableToInterruptJobException {
// TODO Auto-generated method stub
System.err.println("calling interrupt:"+thisThread+"==>"+jobKey);
isJobInterrupted = true;
if (thisThread != null) {
// this call causes the ClosedByInterruptException to happen
thisThread.interrupt();
}
}
#Override
public void execute(JobExecutionContext context) throws JobExecutionException {
// TODO Auto-generated method stub
thisThread = Thread.currentThread();
jobKey = context.getJobDetail().getKey();
System.err.println("calling execute:"+thisThread+"==>"+jobKey);
}
}
Now i tried to stop the job using another main class like in every possible way with no luck
public class Stop {
public static void main(String[] args) throws Exception {
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
// get a "nice round" time a few seconds in the future...
Date startTime = nextGivenSecondDate(null, 1);
JobDetail job = newJob(MyJob.class).withIdentity("myJob", "XXX").build();
Trigger trigger = TriggerBuilder.newTrigger()
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(30)
.repeatForever())
.build();
sched.scheduleJob(job, trigger);
sched.start();
try {
// if you want to see the job to finish successfully, sleep for about 40 seconds
Thread.sleep(60000) ;
// tell the scheduler to interrupt our job
sched.interrupt(job.getKey());
Thread.sleep(3 * 1000L);
} catch (Exception e) {
e.printStackTrace();
}
System.err.println("------- Shutting Down --------");
TriggerKey tk=TriggerKey.triggerKey("myJob","group1");
System.err.println("tk"+tk+":"+job.getKey());
sched.unscheduleJob(tk);
sched.interrupt(job.getKey());
sched.interrupt("myJob");
sched.deleteJob(job.getKey());
sched.shutdown();
System.err.println("------- Shutting Down ");
sched.shutdown(false);
System.err.println("------- Shutdown Complete ");
System.err.println("------- Shutdown Complete ");
}
}
Can anyone please tell me the correct way to stop the job? Thanks a lot.
This question seems to answer the exact problem you're describing:
You need to write a your job as an implementation of InterruptableJob. To interrupt this job, you need handle to Scheduler, and call interrupt(jobKey<<job name & job group>>)
As-per the InterruptableJob documentation:
The interface to be implemented by Jobs that provide a mechanism for having their execution interrupted. It is NOT a requirement for jobs to implement this interface - in fact, for most people, none of their jobs will.
Interrupting a Job is very analogous in concept and challenge to normal interruption of a Thread in Java.
The means of actually interrupting the Job must be implemented within the Job itself (the interrupt() method of this interface is simply a means for the scheduler to inform the Job that a request has been made for it to be interrupted). The mechanism that your jobs use to interrupt themselves might vary between implementations. However the principle idea in any implementation should be to have the body of the job's execute(..) periodically check some flag to see if an interruption has been requested, and if the flag is set, somehow abort the performance of the rest of the job's work.
Emphasis mine. It is analogous but not the same. You're not expected to use Threads (but indeed you could if that's what your Job does...).
An example of interrupting a job can be found in the java source for the class org.quartz.examples.DumbInterruptableJob. It is legal to use some combination of wait() and notify() synchronization within interrupt() and execute(..) in order to have the interrupt() method block until the execute(..) signals that it has noticed the set flag.
So I recommend reading the documentation and inspecting examples in the full download.