{"id":20718499,"url":"https://github.com/knowm/sundial","last_synced_at":"2025-05-15T11:04:48.998Z","repository":{"id":537855,"uuid":"1660504","full_name":"knowm/Sundial","owner":"knowm","description":"A Light-weight Job Scheduling Framework","archived":false,"fork":false,"pushed_at":"2024-07-15T12:16:45.000Z","size":3272,"stargazers_count":272,"open_issues_count":13,"forks_count":51,"subscribers_count":13,"default_branch":"develop","last_synced_at":"2025-04-07T05:03:27.750Z","etag":null,"topics":["cron","java","quartz","scheduled-jobs","scheduler","trigger"],"latest_commit_sha":null,"homepage":"http://knowm.org/open-source/sundial/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/knowm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2011-04-25T16:11:53.000Z","updated_at":"2025-04-04T13:32:57.000Z","dependencies_parsed_at":"2024-10-30T20:42:42.906Z","dependency_job_id":null,"html_url":"https://github.com/knowm/Sundial","commit_stats":{"total_commits":365,"total_committers":19,"mean_commits":"19.210526315789473","dds":0.3068493150684931,"last_synced_commit":"042c483ef2bf638c83a7187e2a8e6216037ed846"},"previous_names":["timmolter/sundial"],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knowm%2FSundial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knowm%2FSundial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knowm%2FSundial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knowm%2FSundial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/knowm","download_url":"https://codeload.github.com/knowm/Sundial/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248912014,"owners_count":21182196,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cron","java","quartz","scheduled-jobs","scheduler","trigger"],"created_at":"2024-11-17T03:13:51.654Z","updated_at":"2025-04-14T15:54:34.924Z","avatar_url":"https://github.com/knowm.png","language":"Java","readme":"## [![Sundial](https://raw.githubusercontent.com/knowm/Sundial/develop/etc/Sundial_64_64.png)](http://knowm.org/open-source/sundial/) Sundial\n\nA Lightweight Job Scheduling Framework for Java.\n\n## In a Nutshell\n\nSundial makes adding scheduled jobs to your Java application a walk in the park. Simply define jobs, define triggers, and start the Sundial scheduler.\n\n## Long Description\n\nSundial is a lightweight Java job scheduling framework forked from Quartz (http://www.quartz-scheduler.org/) stripped down to the bare essentials. Sundial also hides the nitty-gritty configuration details of Quartz, reducing the time needed to get a simple RAM job scheduler up and running. Sundial\nuses a ThreadLocal wrapper for each job containing a HashMap for job key-value pairs. Convenience methods allow easy access to these parameters. JobActions are reusable components that also have access to the context parameters. If you are looking for a hassle-free 100% Java job scheduling framework that is easy to integrate into your applications, look no further.\n\n## Features\n\n * [x] Apache 2.0 license\n * [x] ~150 KB Jar\n * [x] In-memory multi-threaded jobs\n * [x] Define jobs and triggers in jobs.xml\n * [x] or define jobs and triggers via annotations\n * [x] or define jobs and triggers programmatically\n * [x] Cron Triggers\n * [x] Simple Triggers\n * [x] Java 8 and up\n * [x] Depends only on slf4j\n\n## Create a Job Class\n\n```java\npublic class SampleJob extends org.knowm.sundial.Job {\n\n  @Override\n  public void doRun() throws JobInterruptException {\n    // Do something interesting...\n  }\n}\n```\n##  ...with CronTrigger or SimpleTrigger Annotation\n```java\n@CronTrigger(cron = \"0/5 * * * * ?\")\n```\n```java\n@SimpleTrigger(repeatInterval = 30, timeUnit = TimeUnit.SECONDS)\n```\n\n## Start Sundial Job Scheduler\n\n```java\npublic static void main(String[] args) {\n\n  SundialJobScheduler.startScheduler(\"org.knowm.sundial.jobs\"); // package with annotated Jobs\n}\n```\nIf you need a bigger thread pool (default size is 10) use `startScheduler(int threadPoolSize, String annotatedJobsPackageName)` instead.\n\n## Alternatively, Put an XML File Called jobs.xml on Classpath\n\n```xml\n\u003c?xml version='1.0' encoding='utf-8'?\u003e\n\u003cjob-scheduling-data\u003e\n\n\t\u003cschedule\u003e\n\n\t\t\u003c!-- job with cron trigger --\u003e\n\t\t\u003cjob\u003e\n\t\t\t\u003cname\u003eSampleJob3\u003c/name\u003e\n\t\t\t\u003cjob-class\u003ecom.foo.bar.jobs.SampleJob3\u003c/job-class\u003e\n\t\t\t\u003cconcurrency-allowed\u003etrue\u003c/concurrency-allowed\u003e\n\t\t\u003c/job\u003e\n\t\t\u003ctrigger\u003e\n\t\t\t\u003ccron\u003e\n\t\t\t\t\u003cname\u003eSampleJob3-Trigger\u003c/name\u003e\n\t\t\t\t\u003cjob-name\u003eSampleJob3\u003c/job-name\u003e\n\t\t\t\t\u003ccron-expression\u003e*/15 * * * * ?\u003c/cron-expression\u003e\n\t\t\t\u003c/cron\u003e\n\t\t\u003c/trigger\u003e\n\n\t\t\u003c!-- job with simple trigger --\u003e\n\t\t\u003cjob\u003e\n\t\t\t\u003cname\u003eSampleJob2\u003c/name\u003e\n\t\t\t\u003cjob-class\u003ecom.foo.bar.jobs.SampleJob2\u003c/job-class\u003e\n\t\t\t\u003cjob-data-map\u003e\n\t\t\t\t\u003centry\u003e\n\t\t\t\t\t\u003ckey\u003eMyParam\u003c/key\u003e\n\t\t\t\t\t\u003cvalue\u003e42\u003c/value\u003e\n\t\t\t\t\u003c/entry\u003e\n\t\t\t\u003c/job-data-map\u003e\n\t\t\u003c/job\u003e\n\t\t\u003ctrigger\u003e\n\t\t\t\u003csimple\u003e\n\t\t\t\t\u003cname\u003eSampleJob2-Trigger\u003c/name\u003e\n\t\t\t\t\u003cjob-name\u003eSampleJob2\u003c/job-name\u003e\n\t\t\t\t\u003crepeat-count\u003e5\u003c/repeat-count\u003e\n\t\t\t\t\u003crepeat-interval\u003e5000\u003c/repeat-interval\u003e\n\t\t\t\u003c/simple\u003e\n\t\t\u003c/trigger\u003e\n\n\t\u003c/schedule\u003e\n\n\u003c/job-scheduling-data\u003e\n```\n\n## Or, Define Jobs and Triggers Manually\n\n```java\nSundialJobScheduler.addJob(\"SampleJob\", \"org.knowm.sundial.jobs.SampleJob\");\nSundialJobScheduler.addCronTrigger(\"SampleJob-Cron-Trigger\", \"SampleJob\", \"0/10 * * * * ?\");\nSundialJobScheduler.addSimpleTrigger(\"SampleJob-Simple-Trigger\", \"SampleJob\", -1, TimeUnit.SECONDS.toMillis(3));\n```\n\n## More Functions\n\n```java\n// asynchronously start a job by name\nSundialJobScheduler.startJob(\"SampleJob\");\n\n// interrupt a running job\nSundialJobScheduler.stopJob(\"SampleJob\");\n\n// remove a job from the scheduler\nSundialJobScheduler.removeJob(\"SampleJob\");\n\n// remove a trigger from the scheduler\nSundialJobScheduler.removeTrigger(\"SampleJob-Trigger\");\n\n// lock scheduler\nSundialJobScheduler.lockScheduler();\n\n// unlock scheduler\nSundialJobScheduler.unlockScheduler();\n\n// check if job a running\nSundialJobScheduler.isJobRunning(\"SampleJob\");\n```\nAnd many more useful functions. See all here: https://github.com/knowm/Sundial/blob/develop/src/main/java/org/knowm/sundial/SundialJobScheduler.java\n\n## Job Data Map\n```java\n// asynchronously start a job by name with data map\nMap\u003cString, Object\u003e params = new HashMap\u003c\u003e();\nparams.put(\"MY_KEY\", new Integer(660));\nSundialJobScheduler.startJob(\"SampleJob1\", params);\n```\n```java\n// annotate CronTrigger with data map (separate key/values with \":\" )\n@CronTrigger(cron = \"0/5 * * * * ?\", jobDataMap = { \"KEY_1:VALUE_1\", \"KEY_2:1000\" })\npublic class SampleJob extends Job {\n}\n```\n```xml\n\u003c!-- configure data map in jobs.xml --\u003e\n\u003cjob\u003e\n  \u003cname\u003eSampleJob\u003c/name\u003e\n  \u003cjob-class\u003eorg.knowm.sundial.jobs.SampleJob\u003c/job-class\u003e\n  \u003cjob-data-map\u003e\n    \u003centry\u003e\n      \u003ckey\u003eMyParam\u003c/key\u003e\n      \u003cvalue\u003e42\u003c/value\u003e\n    \u003c/entry\u003e\n  \u003c/job-data-map\u003e\n\u003c/job\u003e\n```\n```java\n// access data inside Job\nString value1 = getJobContext().get(\"KEY_1\");\nlogger.info(\"value1 = \" + value1);\n```\n\n## Get Organized with Job Actions!\n\nWith `JobAction`s, you can encapsule logic that can be shared by different `Job`s.\n```java\npublic class SampleJobAction extends JobAction {\n\n  @Override\n  public void doRun() {\n\n    Integer myValue = getJobContext().get(\"MyValue\");\n\n    // Do something interesting...\n  }\n}\n```\n```java\n// Call the JobAction from inside a Job\ngetJobContext().put(\"MyValue\", new Integer(123));\nnew SampleJobAction().run();\n```\n\n## Job Termination\n\nTo terminate a Job asynchronously, you can call the `SundialJobScheduler.stopJob(String jobName)` method. The Job termination mechanism works by setting a flag that the Job should be terminated, but it is up to the logic in the Job to decide at what point termination should occur. Therefore, in any long-running job that you anticipate the need to terminate, put the method call `checkTerminated()` at an appropriate location.\n\nFor an example see `SampleJob9.java`. In a loop within the Job you should just add a call to `checkTerminated();`.\n\nIf you try to shutdown the SundialScheduler and it just hangs, it's probably because you have a Job defined with an infinite loop with no `checkTerminated();` call. You may see a log message like: `Waiting for Job to shutdown: SampleJob9 : SampleJob9-trigger`. \n\n## Concurrent Job Execution\n\nBy default jobs are not set to concurrently execute. This means if a job is currently running and a trigger is fired for that job, it will skip running the job. In some cases concurrent job execution is desired and there are a few ways to configure it.\n\n1. You can add `\u003cconcurrency-allowed\u003etrue\u003c/concurrency-allowed\u003e` in jobs.xml.\n1. You can add it to the Sundial annotations like this: `@SimpleTrigger(repeatInterval = 30, timeUnit = TimeUnit.SECONDS, isConcurrencyAllowed = true)` Same idea for cron annotation too.\n\nNow go ahead and [study some more examples](http://knowm.org/open-source/sundial/sundial-example-code), [download the thing](http://knowm.org/open-source/sundial/sundial-change-log/) and [provide feedback](https://github.com/knowm/Sundial/issues).\n\n## Getting the Goods\n\n### Non-Maven\n\nDownload Jar: http://knowm.org/open-source/sundial/sundial-change-log/\n\n#### Dependencies\n\n* org.slf4j.slf4j-api-2.0.12\n\n### Maven\n\nThe Sundial release artifacts are hosted on Maven Central.\n\nAdd the Sundial library as a dependency to your pom.xml file:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.knowm\u003c/groupId\u003e\n    \u003cartifactId\u003esundial\u003c/artifactId\u003e\n    \u003cversion\u003e2.3.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nFor snapshots, add the following to your pom.xml file:\n\n```xml\n\u003crepository\u003e\n  \u003cid\u003esonatype-oss-snapshot\u003c/id\u003e\n  \u003csnapshots/\u003e\n  \u003curl\u003ehttps://oss.sonatype.org/content/repositories/snapshots\u003c/url\u003e\n\u003c/repository\u003e\n\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.knowm\u003c/groupId\u003e\n    \u003cartifactId\u003esundial\u003c/artifactId\u003e\n    \u003cversion\u003e2.3.1-SNAPSHOT\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## Building\n\n    mvn clean package  \n    mvn javadoc:javadoc\n    mvn com.spotify.fmt:fmt-maven-plugin:format\n\n### Dependency Updates\n\n    mvn versions:display-dependency-updates\n\n## Cron Expressions in jobs.xml\n\nSee the Cron Trigger tutorial over at [quartz-scheduler.org](http://www.quartz-scheduler.org/documentation/quartz-2.2.2/tutorials/crontrigger).\nHere are a few examples:  \n\nExpression | Meaning\n------------- | -------------\n0 0 12 * * ? | Fire at 12pm (noon) every day\n0 15 10 * * ? | Fire at 10:15am every day\n0 15 10 ? * MON-FRI | Fire at 10:15am every Monday, Tuesday, Wednesday, Thursday and Friday\n0 0/10 * * * ? | Fire every 10 mintes starting at 12 am (midnight) every day\n\n## Bugs\nPlease report any bugs or submit feature requests to [Sundial's Github issue tracker](https://github.com/knowm/Sundial/issues).  \n\n## Continuous Integration\n[![Java CI with Maven on Push](https://github.com/knowm/Sundial/actions/workflows/maven_on_push.yml/badge.svg)](https://github.com/knowm/Sundial/actions/workflows/maven_on_push.yml)\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknowm%2Fsundial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fknowm%2Fsundial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknowm%2Fsundial/lists"}