|
|||||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES | ||||||||||
See:
Description
| Interface Summary | |
| CronManager | Crond like interface for sceduling on top of Quartz. |
| Class Summary | |
| CronEditor | An editor to handle adding/removal of CronEntrys to CronManager. |
| CronEntry | A "cron" row consisting of time to run command and command to run. |
| CronManagerService | An MBean service of CronManager based on the Quartz scheduler. |
| HelloWorld | |
| MBeanJob | A Quartz job that will delegate to an MBean. |
| Exception Summary | |
| CronException | Common exception thrown i cron API. |
Qcron is an MBean wrapper and JBoss integration of the scheduler Quartz.
Qcron integrates the popular scheduler Quartz into JBoss as an MBean. It also creates a more convenient method of handling scheduling task based on the cron concept. See Quartz for more info on the scheduler.
The integration is centered around CronManagerService. Through this MBean it is possible to start one or more globally available Quartz instances that are completely configured through the jboss-service mbean stanza.
If one is familiar with Quartz and like to use it directly is is possible use the MBean as a SchedulerFactory. Just invoke getScheduler(). However it is alos possible to use the extended API available in this package which provide:
The Cron API is basically built around three classes: the CronEditor which mimics crontab, CronEntry which is much like a row in a crontab and that encapsulates the Quartz JobDetail and CronTrigger and CronManager which is an interface into a scheduler, here implemented by CronManagerService.
There are of course a number of ways to utilize these classes; only one pattern is really explained here. If you have an MBean that needs to be called by a scheduler you need to set up a CronEntry in a CronEditor.This is normally done in a jboss-service.xml file when configuring the editor. To change a CronEntry, remove or add the jboss-service.xml file is edited and redeployed. Lets start looking at how a CronEntry might look like. A minimal cron entry must consist of the things: the mbean name, which will become the name of the entry (and thereby the underlying Trigger and JobDetail), a CronExp which is a cronlike string and a JobObjectName which is the ObjectName of another Mbean to call when the job triggers. An entry also has a group name, when added to an Editor the group name will be the same as the ObjectName of the editor. So a minimal CronEntry might look like this:
<mbean code="org.backsource.qcron.CronEntry" name="cron:name=runSub2">
<attribute name="CronExp">0 0/1 * * * ?</attribute>
<attribute name="JobObjectName">cron:name=HelloWorld</attribute>
</mbean>
This entry says to run the jobb every minute and that the scheduler should invoke the MBean with the name cron:name=HelloWorld. An entry created this way will not use one important features in Quertz: persistence and recovery. When quertz is configured to be backed by a database it is possible to let Quertz save CronEntries and remember them; and more importantly Quertz may even call a trigger that should have been run, if not the server happened to be down when the trigger happened, i.e Quartz have support for failsafe scheduling. To turn this on the attribute RequestsRecovery must be set to true.
<mbean code="org.backsource.qcron.CronEntry" name="cron:name=runSub">
<attribute name="CronExp">0 0/2 * * * ?</attribute>
<attribute name="JobObjectName">cron:name=HelloWorld</attribute>
<attribute name="RequestsRecovery">true</attribute>
</mbean>
By default a cron entry is persisted, but is not failsafe. To turn of persistence set Volatility to true.
The CronEditor owns all its CronEntries. This means that it will track any changes to the list of entries it handles. If an entry is changed, removed or added when the editor is started/restarted this will be mirrored in what entries is actually in Quartz.The editor may be used manually, but the easiest way is to specify the cron entries as a depends-list when defining the list. Here is an uncommented example:
<mbean code="org.backsource.qcron.CronEditor" name="cron:name=ineditor">
<depends optional-attribute-name="CronManagerName">cron:name=CronManagerService,service=test</depends>
<depends-list optional-attribute-name="CronEntries">
<depends-list-element>
<mbean code="org.backsource.qcron.CronEntry" name="cron:name=runSub">
<attribute name="CronExp">0 0/2 * * * ?</attribute>
<attribute name="JobObjectName">cron:name=HelloWorld</attribute>
<attribute name="RequestsRecovery">true</attribute>
</mbean>
<!-- OBS: do not leave anything between list elements: JBoss is BUGGY!-->
</depends-list-element><depends-list-element>
<mbean code="org.backsource.qcron.CronEntry" name="cron:name=runSub2">
<attribute name="CronExp">0 0/1 * * * ?</attribute>
<attribute name="JobObjectName">cron:name=HelloWorld</attribute>
<attribute name="Volatility">true</attribute>
</mbean>
</depends-list-element>
</depends-list>
</mbean>
Under the hood the class MBeanJob is used to make Quartz call Mbeans. This class works as a delegate by implementing the Job interface and delegate to its configured MBean. How is this done one may as: quertz is only able to be configured with a Class object, and it will create a new its Job classes for each call. The trick is to use the static method: setMBeanJob(org.quartz.JobDataMap, org.backsource.qcron.MBeanJob) to let MBeanJob set itself as an antry in the JobDataMap that Quartz provide. Since MBeanJob is serializable it will later be able to retrieve the ObjectName of the MBean to call. This is used automatically by CronEntry, but may of course be used manually.
The cron expression Quartz uses is only cron like. Here is the documentation from Quartz CronTrigger:
A "Cron-Expression" is a string comprised of 6 or 7 fields separated by
white space. The 6 mandatory and 1 optional fields are as follows:
| Field Name | Allowed Values | Allowed Special Characters | ||
|---|---|---|---|---|
Seconds |
0-59 |
, - * / |
||
Minutes |
0-59 |
, - * / |
||
Hours |
0-23 |
, - * / |
||
Day-of-month |
1-31 |
, - * ? / L C |
||
Month |
1-12 or JAN-DEC |
, - * / |
||
Day-of-Week |
1-7 or SUN-SAT |
, - * ? / L C # |
||
Year (Optional) |
empty, 1970-2099 |
, - * / |
The '*' character is used to specify all values. For example, "*" in the minute field means "every minute".
The '?' character is allowed for the day-of-month and day-of-week fields. It is used to specify 'no specific value'. This is useful when you need to specify something in one of the two fileds, but not the other. See the examples below for clarification.
The '-' character is used to specify ranges For example "10-12" in the hour field means "the hours 10, 11 and 12".
The ',' character is used to specify additional values. For example "MON,WED,FRI" in the day-of-week field means "the days Monday, Wednesday, and Friday".
The '/' character is used to specify increments. For example "0/15" in the seconds field means "the seconds 0, 15, 30, and 45". And "5/15" in the seconds field means "the seconds 5, 20, 35, and 50". You can also specify '/' after the '*' character - in this case '*' is equivalent to having '0' before the '/'.
The 'L' character is allowed for the day-of-month and day-of-week fields. This character is short-hand for "last", but it has different meaning in each of the two fields. For example, the value "L" in the day-of-month field means "the last day of the month" - day 31 for January, day 28 for February on non-leap years. If used in the day-of-week field by itself, it simply means "7" or "SAT". But if used in the day-of-week field after another value, it means "the last xxx day of the month" - for example "6L" means "the last friday of the month". When using the 'L' option, it is important not to specify lists, or ranges of values, as you'll get confusing results.
The '#' character is allowed for the day-of-week field. This character is used to specify "the nth" XXX day of the month. For example, the value of "6#3" in the day-of-week field means the third Friday of the month (day 6 = Friday and "#3" = the 3rd one in the month). Other examples: "2#1" = the first Monday of the month and "4#5" = the fifth Wednesday of the month. Note that if you specify "#5" and there is not 5 of the given day-of-week in the month, then no firing will occur that month.
The 'C' character is allowed for the day-of-month and day-of-week fields. This character is short-hand for "calendar". This means values are calculated against the associated calendar, if any. If no calendar is associated, then it is equivalent to having an all-inclusive calendar. A value of "5C" in the day-of-month field means "the first day included by the calendar on or after the 5th". A value of "1C" in the day-of-week field means "the first day included by the calendar on or after sunday".
The legal characters and the names of months and days of the week are not case sensitive.
Here are some full examples:
| Expression | Meaning | |
|---|---|---|
"0 0 12 * * ?" |
Fire at 12pm (noon) every day |
|
"0 15 10 ? * *" |
Fire at 10:15am every day |
|
"0 15 10 * * ?" |
Fire at 10:15am every day |
|
"0 15 10 * * ? *" |
Fire at 10:15am every day |
|
"0 15 10 * * ? 2005" |
Fire at 10:15am every day during the year 2005 |
|
"0 * 14 * * ?" |
Fire every minute starting at 2pm and ending at 2:59pm, every day |
|
"0 0/5 14 * * ?" |
Fire every 5 minutes starting at 2pm and ending at 2:55pm, every day |
|
"0 0/5 14,18 * * ?" |
Fire every 5 minutes starting at 2pm and ending at 2:55pm, AND fire every 5 minutes starting at 6pm and ending at 6:55pm, every day |
|
"0 0-5 14 * * ?" |
Fire every minute starting at 2pm and ending at 2:05pm, every day |
|
"0 10,44 14 ? 3 WED" |
Fire at 2:10pm and at 2:44pm every Wednesday in the month of March. |
|
"0 15 10 ? * MON-FRI" |
Fire at 10:15am every Monday, Tuesday, Wednesday, Thursday and Friday |
|
"0 15 10 15 * ?" |
Fire at 10:15am on the 15th day of every month |
|
"0 15 10 L * ?" |
Fire at 10:15am on the last day of every month |
|
"0 15 10 ? * 6L" |
Fire at 10:15am on the last Friday of every month |
|
"0 15 10 ? * 6L" |
Fire at 10:15am on the last Friday of every month |
|
"0 15 10 * * 6L 2002-2005" |
Fire at 10:15am on EVERY DAY of every month during the years 2002, 2003, 2004 and 2005 |
|
"0 15 10 * * 6#3" |
Fire at 10:15am on the third Friday of every month |
Pay attention to the effects of '?' and '*' in the day-of-week and day-of-month fields!
NOTES:
|
|||||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES | ||||||||||