B4J Library Quartz Scheduler Cron - For enterprise grade task scheduling software

Hello everyone,
I wrapped this last year whilst trying to learn Java, I then had to learn about cron expressions o_O

Yesterday I decided to cleaned up the code, fixed all known issues, and I added the IDE tooltips for the IDE. I also created an extensive B4J example for developers to learn from, so read it very carefully.

This truly is THE ONLY 100% precise timing library that you need to use when it comes to scheduling tasks in your B4J projects

Quartz Scheduler is a precise timing lightweight, embeddable job scheduler solution. Its purpose is simple, it lets your program run tasks automatically at specific times or intervals, without relying on the operating systems scheduler or complicated timer routines.

Here is the essence of Quartz in plain terms.

What Quartz does

  • Runs jobs on a schedule (every few seconds, every minute, every hour, every day, every x days, etc) via cron expressions
  • Manages all recurring tasks reliably inside your application
  • Supports multiple jobs, triggers, calendars, and priorities
  • Can persist schedules in a database so they survive restarts (You have to add the database code of your choice), I removed SQLite for reliability purposes
  • Works in desktop applications, servers applications
  • Use in desktop applications or as a background worker service

Why developers around the world use Quartz

  • Quarts is an industry standard scheduler solution
  • It's far more flexible than OS‑level schedulers
  • It handles complex timing rules (cron, exclusions, holidays) etc
  • It's stable and reliable

In one short paragraph

Quartz Scheduler is a powerful, programmable Quartz level timer system that lets your application run tasks automatically and reliably according to any schedule you define. Quartz can schedule everything from interacting with databases, processing files, to launching external applications using the Shell command, sending commands, processing data, working with I/O and much more. What Quartz actually does is simple. Quartz can fire your code at precise times or intervals that you specify, without you needing to manage timers, threads, or OS‑level schedulers.

How you use that sort of power is entirely up to you. As a B4J developer, you can combine Quartz with your existing knowledge of file I/O, networking, SQL, APIs, or system automation to build anything from simple reminders to full industrial grade task automation solutions. With a bit of imagination and the help of the B4X search box when you need help, you can easily manipulate this library to its full potential.

Quartz Scheduler is used in industry grade solutions.
Quartz has been used for more than 20 years in production systems across finance, telecoms, logistics, healthcare, and enterprise Java platforms.

Hint: Personally, I would create an external SQLite database to store all jobs and schedules, and then connect the database to the Quartz Scheduler. Jobs and schedules can also be hard-coded directly into your application.


B4J library tab:
1770821109745.png


Example B4J application:
1770819773702.png


SS_QuartzScheduler

Author:
Peter Simpson
Version: 1.11
  • QuartzScheduler
    • Events:
      • ExecutorHealth (Healthy As Boolean)
      • JobDeleted (JobName As String)
      • JobError (JobName As String, Error As String)
      • JobExecute (JobName As String, Data As Map)
      • JobFinished (JobName As String)
      • JobScheduled (JobName As String)
      • JobStarted (JobName As String)
      • SchedulerError (Error As String)
      • SchedulerShutdown
      • SchedulerStarted
    • Fields:
      • SetMaxLogEntries As Int
        Sets the maximum number of log entries to retain.
        Default entries is set to 1000.
        Older entries are removed automatically.
    • Functions:
      • CancelJob (jobName As String)
        Alias for PauseJob.
        jobName is the Job name.
      • CheckExecutorHealth
        Checks if the executor is alive and not shutdown.
        Raises event: ExecutorHealth (Boolean)
      • ClearLog
        Clears the internal log entries.
      • DeleteGroup (groupName As String)
        Deletes all jobs in a given group on a background thread.
        groupName is the Group name.
      • DeleteJob (jobName As String)
        Deletes a job by name in any group on a background thread.
        jobName is the Job name.
      • GetAllJobs As List
        Returns a B4J List of all job names across all groups.
        Each item is a Map with keys: "group" and "name".
      • GetJobData (jobName As String)
        Retrieves the Map of data associated with a job.
        jobName is the Job name.
        Returns a Map of job data (empty if job not found).
      • GetJobDetailInfo (jobName As String)
        Returns basic job detail metadata as Map: Name, Group, Description.
        jobName is the Job name.
        Returns a Map with keys "Name", "Group", "Description" (empty if job not found).
      • GetJobGroups As List
        Returns a list of job group names.
      • GetJobLog (jobName As String) As List
        Returns logs related to a specific job name.
        jobName is the Job name.
        Returns a List of strings.
      • GetJobNames (groupName As String) As List
        Returns a list of job names for a given group.
      • GetJobState (jobName As String)
        Returns the current state of a job.
        Possible values: SCHEDULED, PAUSED, RUNNING, COMPLETE, NOT_FOUND.
        jobName The job name.
        Returns State string.
      • GetLog As List
        Returns the full internal log of the scheduler.
        Returns a List of strings.
      • GetLogCount As Int
        Returns the number of log entries currently stored.
      • GetLogs As List
        Returns a copy of the internal log entries as a B4J List.
        The returned list contains the log lines in chronological order (oldest first).
      • GetNextFireTime (jobName As String) As java.util.Date
        Returns the next fire time for a given job (by name) as a Date, or Null if not found.
        Searches across all groups for the job name.
      • GetNextRunTime (jobName As String)
        Returns the next scheduled execution time for a job.
        jobName is the Job name.
        Returns Next run time in milliseconds (0 if not found or no upcoming run).
      • GetSchedulerState As Map
        Returns a B4J Map with scheduler metadata: started(boolean), inStandby(boolean), shutdown(boolean)
      • GetTriggerInfo (jobName As String)
        Returns detailed trigger information for a specific job.
        Each item in the returned list is a Map containing trigger metadata.
        jobName is the job name.
        Returns A List of Maps describing the job's triggers.
      • InitializeAsync (EventName As String)
        Initialise asynchronously, Uses RAMJobStore.
        eventName is the Event name prefix ("QS", "Quartz", "Schedule" etc).
      • InterruptJob (jobName As String)
        Requests interruption of a running job on a background thread.
        jobName is the Job name.
      • IsStarted As Boolean
        Returns true if the scheduler is started and not shutdown.
      • JobExists (jobName As String)
        Checks whether a job with the given name exists in any group.
        jobName is the Job name.
        Returns true if the job exists, false otherwise.
      • ListGroups
        Returns all job groups currently registered in the scheduler.
        Returns A List of group names.
      • ListJobs
        Returns a List of job names currently known to the scheduler.
      • PauseGroup (groupName As String)
        Pauses all jobs in a given group on a background thread.
        groupName is the Group name.
      • PauseJob (jobName As String)
        Pauses a job by name in any group on a background thread.
        jobName is the Job name.
      • ResumeGroup (groupName As String)
        Resumes all jobs in a given group on a background thread.
        groupName is the Group name.
      • ResumeJob (jobName As String)
        Resumes a previously paused job by name in any group on a background thread.
        jobName is the Job name.
      • RunJobNow (jobName As String)
        Run a job immediately by name (helper used by chaining).
      • ScheduleCronJob (jobName As String, cron As String, data As Map)
        Schedule a cron job (default group) on a background thread.
        jobName is the Job name (unique).
        cron is the Cron expression.
        data is the Map of data to pass to job (can be null).
      • ScheduleCronJob2 (jobName As String, groupName As String, cron As String, data As Map)
        Schedule a cron job with group on a background thread.
        jobName is the Job name.
        groupName is the Group name.
        cron is the Cron expression.
        data is the Map data.
      • ScheduleJobAsync (jobName As String, cronOrNull As String, intervalSeconds As Long, repeatCount As Long, data As Map)
        Schedule job asynchronously on background thread (default group).
        jobName is the Job name.
        cronOrNull is the Cron expression or null.
        intervalSeconds is the Interval seconds for repeating (ignored if cron provided).
        repeatCount is the Repeat count for repeating (ignored if cron provided).
        data is the Map data.
      • ScheduleJobAsync2 (jobName As String, groupName As String, cronOrNull As String, intervalSeconds As Long, repeatCount As Long, data As Map)
        Schedule job asynchronously on background thread with group.
        jobName is the Job name.
        groupName is the Group name.
        cronOrNull is the Cron expression or null.
        intervalSeconds is the Interval seconds for repeating (ignored if cron provided).
        repeatCount is the Repeat count for repeating (ignored if cron provided).
        data is the Map data.
      • ScheduleRepeatingJob (jobName As String, intervalSeconds As Long, repeatCount As Long, data As Map)
        Schedule a repeating job (default group) on a background thread.
        jobName is the Job name.
        intervalSeconds is the Interval in seconds.
        repeatCount Number of repeats, zero or less means repeat forever.
        data is the Map data.
      • ScheduleRepeatingJob2 (jobName As String, groupName As String, intervalSeconds As Long, repeatCount As Long, data As Map)
        Schedule a repeating job with group on a background thread.
        jobName is the Job name.
        groupName is the Group name.
        intervalSeconds is the Interval in seconds.
        repeatCount Number of repeats, zero or less means repeat forever.
        data is the Map data.
      • SetJobChain (jobNames As List)
        Define a simple chain of jobs: JobNames(0) -> JobNames(1) -> JobNames(2) ...
        When one finishes successfully, the next is triggered.
        jobNames is the List of job names in execution order.
      • ShutdownAsync
        Shutdown scheduler on background thread. Returns immediately.
      • StartAsync
        Start the scheduler on a background thread.
        The call returns immediately without waiting for the scheduler to start.
      • StopAsync
        Stop the scheduler completely.
        Deletes all scheduled jobs, shuts down Quartz,
        clears internal state, and destroys the instance.
      • WatchdogStatus
        Logs a watchdog snapshot of scheduler and executor health.

PLEASE NOTE:
TO RUN THE ATTACHED EXAMPLE, YOU NEED TO DOWNLOAD THE THIRD-PARTY JAVA DEPENDENCIES LINKED BELOW, AS WELL AS USING THE ATTACHED POST LIBRARY.

CLICK HERE - Download Extra Libraries <<<<<<<<<<<<<<<<<<<<<<<<


D = 123 + 166


Enjoy...
 

Attachments

  • QuartzScheduler.zip
    11.9 KB · Views: 19
  • QuartzScheduler_Lib.zip
    21.4 KB · Views: 26
Last edited:

Peter Simpson

Expert
Licensed User
Longtime User
More...

Quartz Scheduler is used in industry

Quartz is an enterprise level scheduling engine, it is part of the Java ecosystem and is widely deployed in the following categories
  • Banking systems
  • Insurance platforms
  • Telecom billing systems
  • Manufacturing automation
  • Logistics and fleet management
  • Large scale web applications
  • Microservices
  • Cloud based backend systems
It is stable, predictable, and designed for long running mission critical workloads.

Why industry uses Quartz

1. Reliability

Quartz is designed to run for months or years without stopping. It handles the following with ease.
  • Missed triggers
  • Retries
  • Persistent job stores
  • Clustering
  • Failover

2. Flexibility

This library supports the following.

3. Persistence

Quartz can store schedules in:
  • RAM (fast, simple) - Default
  • Encrypted files, you add your file of choice
  • SQLite database, or JDBC databases (PostgreSQL, MySQL, SQL Server, Oracle), You add your database of choice
This means schedules survive application restarts, essential for production.

4. Clustering

Multiple servers can share the same job store and coordinate scheduling (Store jobs and schedules in JDBC databases). This is a major enterprise feature.

5. Embeddable

Quartz runs inside your application, not as a separate service. This gives developers full control.

Why Quartz works perfectly in B4J

Quartz is:
  • Safe
  • Easy to use
  • Fully asynchronous
  • Can be used with any database. You have to add the connector yourself and manipulate the events
This is exactly how industrial systems integrate Quartz:
  • JobExecute
  • JobStarted
  • JobFinished
  • SchedulerError

In short

Quartz is one of the most trusted scheduling engines in the Java world.


Enjoy...
 
Last edited:

Peter Simpson

Expert
Licensed User
Longtime User
Hello everyone,
Below is a quick cheat sheet to help B4J developers learn how to use cron expressions.

Cron expression cheat sheet - Quartz Format

This cheat sheet gives developers quick, ready to use cron expressions for the most common scheduling patterns.

All examples use the Quartz six field format.
Fields are as follows, and are separated by a space.
Seconds Minutes Hours DayOfMonth Month DayOfWeek

Allowed ranges

FieldRange
Seconds0 to 59
Minutes0 to 59
Hours0 to 23
Day of month1 to 31
Month1 to 12 (1 is January) - jan to dec
Day of week1 to 7 (1 is Sunday) - sun to sat


1. Quick reference table

PurposeCron Expression
Every second0/1 ?
Every 5 seconds0/5 ?
Every 10 seconds0/10 ?
Every 30 seconds0/30 ?
Every minute0 0/1 * ?
Every 5 minutes0 0/5 * ?
Every 15 minutes0 0/15 * ?
Every 30 minutes0 0/30 * ?
Every hour0 0 * ?
Every 2 hours0 0 0/2 ?
Every 6 hours0 0 0/6 ?
Every day at midnight0 0 0 ?
Every day at 6am0 0 6 ?
Every day at 6.30am0 30 6 ?
Every Monday at noon0 0 12 ? * 2
Every Friday at 5pm0 0 17 ? * 6
Every weekend (Sat and Sun) at 9am0 0 9 ? * 1,7
First day of every month at midnight0 0 0 1 * ?
Last day of every month at midnight0 0 0 L * ?
Every weekday at 9am0 0 9 ? * 2-6
Every day at 9am0 0 9 * * ?
Every year on 1 January at midnight0 0 0 1 1 ?


2. Human Friendly Examples

Run something every 10 seconds

0/10 ?

Run something every 15 minutes
0 0/15 * ?

Run at 2.45pm every day
0 45 14 ?

Run at 11pm every Sunday
0 0 23 ? * 1

Run at 3am on the first day of every month
0 0 3 1 * ?

Run at 9am Monday to Friday
0 0 9 ? * 2-6


3. Special characters explained

SymbolMeaning
*Every possible value
/Step values (for example 0/5 means every 5 units)
,List of values
-Range of values
?No specific value (used in DayOfMonth or DayOfWeek)
LLast day of the month


4. Tips for writing reliable cron expressions

Always include the seconds field because Quartz requires it.
Use ? in either DayOfMonth or DayOfWeek when you do not care about that field.
Use step values like 0/5 for regular intervals.
Keep expressions simple until you are confident.
Test your cron expressions using an online Quartz tester.


Enjoy...
 
Last edited:

Peter Simpson

Expert
Licensed User
Longtime User
Hello everyone,
I’ve finally updated the Quartz Scheduler library. There are both updated and new methods, new features, and improved stability (even though it was already stable). There are too many improvements to list in this post. I’ve updated the documentation in the first post of this thread, along with the library and the B4J example code.

For client projects, I personally rely on ABBackgroundWorkers that handles all server‑side background processing such as order transfers, monthly billing, API workflows, database interactions and data conversion, while Quartz Scheduler provides the precise and reliable scheduling needed for time‑critical operations.

The latest version of this library has been running smoothly and without errors, 24/7, for just under 67 days (see the VisualVM screenshot below). That’s when I last updated the library to v1.11. Now that it has been running flawlessly across multiple client solutions, I’ve decided to release the updated library.

VisualVM showing a background worker app running for just under 67 days. In this case, Quartz is used for on the second execution of call and processes.
VisualVM.jpg


Enjoy...
 
Last edited:
Top