How to use quartz scheduler in java? - java

I need to schedule a task that will run everyday on 7:00 p.m. in java using quartz. Can someone point out a good tutorial on how to use quartz scheduler in java?

Take a look at quartz API documentation.
Edit:
Working URL for quartz API Documentation

To run everyday at 7pm, configure in your quartz.xml. Here "name" is whatever you want it to be, "job-name" should be same as the job-name you mentioned in between job tags.
<job>
<name>Scheduletracer</name>
<job-class>//here goes package name.program name</job-class>
</job>
<trigger>
<cron>
<name>server1</name>
<job-name>ScheduleTracer</job-name>
<cron-expression>0 0 19 * * ?</cron-expression>
</cron>
</trigger>

Related

start the job immediately using quartz framework?

I am running some jobs periodically using quartz framework. I have a below quartz_config xml file which contains all the jobs I am running and at what interval.
<job-scheduling-data
xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData http://www.quartz-scheduler.org/xml/job_scheduling_data_2_0.xsd"
version="1.8">
<schedule>
<job>
<name>ParserApp</name>
<job-class>com.process.task.ParserApp</job-class>
</job>
<trigger>
<cron>
<name>ParserApp</name>
<job-name>ParserApp</job-name>
<cron-expression>0 0 0/3 1/1 * ? *</cron-expression>
</cron>
</trigger>
</schedule>
</job-scheduling-data>
I am running ParserApp job every 3 hours. Now what I have noticed is - whenever I start my application, it doesn't start ParserApp job immediately. What it does instead is, it starts ParserApp jobs after 3 hours only which is fine as per cron expression. Is there any way by which I can start ParserApp job immediately whenever application is started up and then next run should happened after 3 hours only just like java ScheduledExecutorService does?
In the below code, as soon as you start executorService, it will call parserApp immediately and then it will call parserApp again after 3 hours periodically. Is there any way to do the same thing using quartz-scheduler?
executorService.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
parserApp();
}
}, 0, 3, TimeUnit.HOURS);
Below is how I am starting all the jobs using quartz scheduler:
StdSchedulerFactory factory = new StdSchedulerFactory();
try {
factory.initialize(App.class.getClassLoader().getResourceAsStream("quartz.properties"));
Scheduler scheduler = factory.getScheduler();
// starts all our jobs using quartz_config.xml file
scheduler.start();
} catch (SchedulerException ex) {
logger.logError("error while starting scheduler= ", ExceptionUtils.getStackTrace(ex));
}

Multiple Jobs in Quartz Scheduler not running according to the triggers

I have configured a quartz scheduler with 4 different jobs, each triggering every 1 minute. The schedule I have configured is as follows:-
<schedule>
<job>
<name>LockMonitor</name>
<job-class>background.jobs.LockMonitor</job-class>
</job>
<trigger>
<simple>
<name>LockJobTrigger</name>
<job-name>LockMonitor</job-name>
<repeat-count>-1</repeat-count>
<repeat-interval>60000</repeat-interval>
</simple>
</trigger>
<job>
<name>LogMonitor</name>
<job-class>background.jobs.LogMonitorJob</job-class>
</job>
<trigger>
<simple>
<name>LogMonitorTrigger</name>
<job-name>LogMonitor</job-name>
<repeat-count>-1</repeat-count>
<repeat-interval>60000</repeat-interval>
</simple>
</trigger>
<job>
<name>ProcessMonitor</name>
<job-class>background.jobs.ProcessMonitor</job-class>
</job>
<trigger>
<simple>
<name>ProcessMonitorTrigger</name>
<job-name>ProcessMonitor</job-name>
<repeat-count>-1</repeat-count>
<repeat-interval>60000</repeat-interval>
</simple>
</trigger>
<job>
<name>HealthCheck</name>
<job-class>background.jobs.HealthCheck</job-class>
</job>
<trigger>
<simple>
<name>HealthCheckTrigger</name>
<job-name>HealthCheck</job-name>
<repeat-count>-1</repeat-count>
<repeat-interval>60000</repeat-interval>
</simple>
</trigger>
</schedule>
The problem that I am encountering is that only the 1st and 2nd jobs are getting executed most of the time. The 3rd and 4th jobs - namely ProcessMonitor and HealthCheck are getting executed only once in a while. Can someone help me with this? Is this because I have configured the same time interval for all the jobs? Is there any means by which I can ensure that all the 4 jobs are executed before starting the next set of execution?
I have configured all the jobs as implements StatefulJob
How many threads did you configure? When I keep the number of thread == number of jobs registered to run in the Quartz framework, everything seems to run as expected.

quartz job data-store persistence issue

I have the following question.
I have quartz scheduler 2.2.1
I have jdbc datastore
I have marked the job as Persistent
I can see the trigger and the job info saved into the db.
Yet, it seems my job datamap information does not survive an application restart.
When I restart the application the data I saved into the datamap seem to disappear and the datamap is empty when the application is restarted.
context.getJobDetail().getJobDataMap().putAsString(LAST_EXEC, curTimeMilliSecs);
I have the following in the jobs.xml
<job>
<name>check-new-events-job</name>
<group>EVENTS_GROUP</group>
<description>Check new events in the db</description>
<job-class>jobs.CheckNewEventsJob</job-class>
<durability>true</durability>
<recover>true</recover>
</job>
<trigger>
<cron>
<name>check-new-events-trigger</name>
<group>EVENTSTRIGGER_GROUP</group>
<job-name>check-new-events-job</job-name>
<job-group>EVENTS_GROUP</job-group>
<cron-expression>0 0/1 * * * ?</cron-expression>
</cron>
</trigger>
My job is configured to be
#PersistJobDataAfterExecution
#DisallowConcurrentExecution
public class CheckNewEventsJob implements Job {
The goal of this job is to survive application restarts and keep track of all the last executions.
Any ideas where to look ?
Thanks a lot!

How do I run a cron job 45 minutes past the hour on google app engine?

I'm working on an app for google app engine that fetches data from facebook, twitter, and email every 15, 30, and 45 minutes past the hour. I've read the documentation, but I'm not seeing a way to do it. Am I missing something? Thank you for your time and attention.
Add 24 different cron jobs with the formats:
every day 00:45
every day 01:45
every day 02:45
etc.
They can all use the same handler.
Wouldn't it be easier to just run it on a set interval like this?
<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
<url>/fetch-data</url>
<description>Fetch data every 15 minutes</description>
<schedule>every 15 minutes</schedule>
</cron>
</cronentries>
If you need your job to start precisely 15mn, 30mn and 45mn past the hour, it's possible with the combination of 3 crons calling the same url:
<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
<url>/cron/everyHour</url>
<description>Every hour 1</description>
<schedule>every 1 hours from 00:15 to 23:15</schedule>
<timezone>Europe/Paris</timezone>
</cron>
<cron>
<url>/cron/everyHour</url>
<description>Every hour 2</description>
<schedule>every 1 hours from 00:30 to 23:30</schedule>
<timezone>Europe/Paris</timezone>
</cron>
<cron>
<url>/cron/everyHour</url>
<description>Every hour 3</description>
<schedule>every 1 hours from 00:45 to 23:45</schedule>
<timezone>Europe/Paris</timezone>
</cron>
</cronentries>

Java Quartz default timezone

I run Tomcat with -Duser.timezone=UTC. However Quartz scheduler 2.2.1 seems to run in Europe/Prague which is my OS timezone.
Is there a way to run Quartz in custom timezone or determine which timezone Quartz is using?
If not, is there a way to determine OS timezone programatically?
Quartz by default will use the default system locale and timezone, and it is not programed to pick up the property user.timezone you are providing your app. Remember also that this is only applies to a CronTrigger and not a SimpleTrigger.
If you are using Spring for example:
<bean id="timeZone" class="java.util.TimeZone" factory-method="getTimeZone">
<constructor-arg value="GMT" />
</bean>
<bean id="yourTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="yourJob" />
<property name="cronExpression" value="0 0 0/1 * * ?" />
<property name="timeZone" ref="timeZone" />
</bean>
If you are using plain java:
Trigger yourTrigger = TriggerBuilder
.newTrigger()
.withIdentity("TRIGGER-ID", "TRIGGER-GROUP")
.withSchedule(CronScheduleBuilder
.cronSchedule("0 0 0/1 * * ?")
.inTimeZone(TimeZone.getTimeZone("GMT")))
).build();
If you are using the XML configuration file, e.g. the quartz-config.xml from Example To Run Multiple Jobs In Quartz of mkyong, you can configure the timezone in the element time-zone:
<schedule>
<job>
<name>JobA</name>
<group>GroupDummy</group>
<description>This is Job A</description>
<job-class>com.mkyong.quartz.JobA</job-class>
</job>
<trigger>
<cron>
<name>dummyTriggerNameA</name>
<job-name>JobA</job-name>
<job-group>GroupDummy</job-group>
<!-- It will run every 5 seconds -->
<cron-expression>0/5 * * * * ?</cron-expression>
<time-zone>UTC</time-zone>
</cron>
</trigger>
</schedule>
See also Java's java.util.TimeZone for to see the ID for several timezones.
You can call setTimeZone() to set the time zone of your choosing for anything in Quartz that inherits BaseCalendar.
Java's TimeZone class has a getDefault() which should aid in determining OS timezone programmatically.

Categories

Resources