This library allows for the triggering of a Java job based on a CRON expression.
- Classic integer ranges
- Day and month names (3 letters, case insensitive)
- Special expressions, with the exception of
@reboot
- cron4j
- Quartz (but CRONs are only a little part of it)
- crontab4j (take the best of each world and make it the most flexible as can be)
import org.keyboardplaying.cron.parser.UnixCronParser;
import org.keyboardplaying.cron.scheduler.CronScheduler;
public class CronStarter {
public static void main(String[] args) {
CronScheduler schd = new CronScheduler();
// Set parser: only Unix at the moment, but more to come
schd.setParser(new UnixCronParser());
schd.scheduleJob(() -> System.out.println("Another minute ticked."), "* * * * *");
// schd is a daemon: it will not prevent the JVM from stopping
}
}
The JVM will stop automatically if all remaining threads are daemons. The CronScheduler
is a daemon
by default. To prevent this behaviour, you should instantiate it this way:
CronScheduler schd = new CronScheduler(false);
A fair warning: you will have to stop it for the JVM to close:
schd.terminate();
<bean id="schd" class="org.keyboardplaying.cron.scheduler.CronScheduler">
<property name="parser"><bean class="org.keyboardplaying.cron.parser.UnixCronParser"/></property>
<property name="jobs">
<list>
<ref bean="job1"/>
<ref bean="job2"/>
...
</list>
</property>
</bean>
<bean id="job1" class="org.keyboardplaying.cron.scheduler.CronJob">
<property name="job" ref="myRunnableBean"/>
<property name="cron" value="0 0 * * *"/>
</bean>
- Unix man crontab
- Quartz (but CRONs are only a little part of it)
- cron4j
- cron-utils
It happened at work: we wanted to gain the flexibility of CRON expressions for job scheduling, but my boss feared Quartz was overkill for a single job.
So I gathered my knowledge about the CRONs (which was few, so I had to look for some more) and created my own parser and scheduler. Not that hard, actually, but this was a kind of a draft.
I had the wish to go from scratch and write something a bit more elaborate and clean. And when
looking for the name, I discovered cron4j
was already taken by a similar project. Still,
for the challenge...
My first try had been using joda-time
for comfort and ease of use. However, this time, I
chose to avoid external libraries as much as possible in order to keep the footprint as light as
possible, and therefore used java.util.Calendar
instead.
- Find a parsing method without use of regular expressions
- Scheduler enhancement
- Use a custom implementation instead of Java's timer
- Concurrence management (per job!)
- Minor enhancements (search for TODO and FIXME in code)
- Create a module
crontab4j-scheduler
, containing one default syntax - Keep the best of each world
- cron4j: possibility of multiple expressions
- Quartz: seconds and years, advanced day management
- Create a module
crontab4j-syntaxes
for additional syntaxes - Unix
- cron4j
- Quartz
- Drop
Calendar
and use Java 8's time utilities
- Ensure functionality
- Include license in jar (META-INF; avoid file duplication if possible)
- Documentation
- Enhancements
- Ensure min < max in ranges when validating/parsing
- Optimizer (parses the rules and rewrite them for optimization)
- Single values with a step (
1/2
->1
) - Remove CRON expressions without a next occurrence
- Repetition with step ##
1
-> range - Multiple expressions with at least one
*
(e.g.1-5,*,20-30/9
) ->*
- Overlapping ranges (or repeats with same step) -> Single range (or repeat with same step)
- Identical ranges with multiple steps (
*/4,*/2
) ->*/2
- Out of access ranges (
0 0 2-7/2 31 *
-> 31st of every even month until July) - Generator (related to previous; reverts a
CronExpression
to aString
) - Descriptor (describes a CRON in natural language; low priority)
- Split into
crontab4j-core
andcrontab4j-utils
to reduce footprint if need be - Review documentation