{"id":21694444,"url":"https://github.com/andrehertwig/spring-boot-starter-quartz","last_synced_at":"2025-04-12T10:50:43.781Z","repository":{"id":50588001,"uuid":"90497842","full_name":"andrehertwig/spring-boot-starter-quartz","owner":"andrehertwig","description":"Spring-Boot auto-configuration for Quartz-Scheduler","archived":false,"fork":false,"pushed_at":"2019-09-15T10:09:03.000Z","size":83,"stargazers_count":51,"open_issues_count":0,"forks_count":26,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-26T05:41:52.587Z","etag":null,"topics":["quartz-scheduler","quartz-tools","spring-boot","spring-boot-starter"],"latest_commit_sha":null,"homepage":null,"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/andrehertwig.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}},"created_at":"2017-05-06T23:52:38.000Z","updated_at":"2024-11-27T07:17:28.000Z","dependencies_parsed_at":"2022-09-26T22:01:20.509Z","dependency_job_id":null,"html_url":"https://github.com/andrehertwig/spring-boot-starter-quartz","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrehertwig%2Fspring-boot-starter-quartz","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrehertwig%2Fspring-boot-starter-quartz/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrehertwig%2Fspring-boot-starter-quartz/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrehertwig%2Fspring-boot-starter-quartz/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andrehertwig","download_url":"https://codeload.github.com/andrehertwig/spring-boot-starter-quartz/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248557844,"owners_count":21124165,"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":["quartz-scheduler","quartz-tools","spring-boot","spring-boot-starter"],"created_at":"2024-11-25T18:28:26.770Z","updated_at":"2025-04-12T10:50:43.753Z","avatar_url":"https://github.com/andrehertwig.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Spring-Boot auto configuration for Quartz Scheduler\r\n\r\n\u003e Just a Spring-Boot starter for Quartz Scheduler.\r\n\r\nOf course there are already several starters for Quartz Scheduler, but none of them fulfill all my needs, therefore I created my own.\r\n\r\n[![Maven Central](https://img.shields.io/maven-central/v/de.chandre.quartz/spring-boot-starter-quartz.svg)](https://mvnrepository.com/artifact/de.chandre.quartz)\r\n[![GitHub issues](https://img.shields.io/github/issues/andrehertwig/spring-boot-starter-quartz.svg)](https://github.com/andrehertwig/spring-boot-starter-quartz/issues)\r\n[![license](https://img.shields.io/github/license/andrehertwig/spring-boot-starter-quartz.svg)](https://github.com/andrehertwig/spring-boot-starter-quartz/blob/develop/LICENSE)\r\n\r\nThis is just a spare-time project. The usage of this tool (especially in production systems) is at your own risk.\r\n\r\n# Content\r\n\r\n1. [Requirements, Dependencies](#requirements-dependencies)\r\n2. [Usage](#usage)\r\n3. [Configuration Properties](#configuration-properties)\r\n4. [Additional Things](#additional-things)\r\n   1. [Utils](#utils)\r\n   2. [Hooks](#hooks)\r\n   3. [Job interdependencies](#job-interdependencies-with-105)\r\n5. [Recommended Maven Dependency Management](#recommended-maven-dependency-management)\r\n\r\n## Requirements, Dependencies\r\n* spring-boot\r\n* quartz-scheduler\r\n\r\nTested with Spring Boot \r\n* (until 1.0.2) 1.3.8, 1.4.6, 1.5.3, 1.5.6, \r\n* (since 1.0.3) 1.4.6, 1.5.10, 1.5.16, 1.5.17\r\n\r\n## Usage\r\n\r\n```xml\r\n\r\n\u003cdependency\u003e\r\n\t\u003cgroupId\u003ede.chandre.quartz\u003c/groupId\u003e\r\n\t\u003cartifactId\u003espring-boot-starter-quartz\u003c/artifactId\u003e\r\n\t\u003cversion\u003e1.0.5\u003c/version\u003e\r\n\u003c/dependency\u003e\r\n\t\r\n```\r\n\r\nMaybe you have to explicitly enable the component scan for the package:\r\n```java\r\n\r\n@SpringBootApplication\r\n@EnableAutoConfiguration\r\n@ComponentScan(basePackages={\"your.packages\", \"de.chandre.quartz.spring\"})\r\npublic class MyBootApplication {\r\n \r\n}\r\n```\r\n\r\n## Configuration Properties\r\n\r\nFor special configuration, please check the [additional-spring-configuration-metadata.json](src/main/resources/META-INF/additional-spring-configuration-metadata.json) \r\n\r\nOriginal [Quartz 2.x Configuration](http://www.quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigMain.html) documentation. Please read this in case of questions how to configure Quartz correctly.\r\n\r\n```ini\r\n  # if auto configuration is enabled\r\n  quartz.enabled=true\r\n  \r\n  ################################\r\n  #      Quartz Persistence      #\r\n  ################################\r\n  \r\n  # should be set to true if quartz is configured to persist its data to a database\r\n  quartz.persistence.persisted=false\r\n  \r\n  # Only if quartz.persisted=true. if the PlatformTransactionManager should be used. Must be configured as Bean.\r\n  quartz.persistence.use-platform-tx-manager=true\r\n  \r\n  #since 1.0.4\r\n  #String\r\n  #Only if quartz.persisted=true. if there are more than one PlatformTransactionManagers \r\n  # within the context you can specify the bean name, which txManager to use.\r\n  quartz.persistence.platform-tx-manager-bean-name=\r\n  \r\n  #String\r\n  # Only if quartz.persisted=true. If more than one database connection is configured the \r\n  # name (case-sensitive) of the used DataSource must be configured.\r\n  quartz.persistence.data-source-name=\r\n  \r\n  ################################\r\n  #   Quartz SchedulerFactory    #\r\n  ################################\r\n  \r\n  #String\r\n  # Optional: a name for the scheduler\r\n  quartz.scheduler-factory.schedulerName=\r\n  \r\n  # Set whether to automatically start the scheduler after initialization.\r\n  quartz.scheduler-factory.auto-startup=true\r\n  \r\n  # Set whether to wait for running jobs to complete on shutdown.\r\n  quartz.scheduler-factory.wait-for-jobs-to-complete-on-shutdown=false\r\n  \r\n  # Set whether any jobs defined on this scheduler-factoryBean should overwrite existing job definitions.\r\n  quartz.scheduler-factory.overwrite-existing-jobs=false\r\n  \r\n  # Set whether to expose the Spring-managed Scheduler instance in the Quartz SchedulerRepository.\r\n  quartz.scheduler-factory.expose-scheduler-in-repository=false\r\n  \r\n  # Specify the phase in which this scheduler should be started and stopped. \r\n  # The startup order proceeds from lowest to highest, and the shutdown order is the reverse of that.\r\n  quartz.scheduler-factory.phase=java.lang.Integer.MAX_VALUE\r\n  \r\n  # Set the number of seconds to wait after initialization before starting the scheduler asynchronously.\r\n  # Default is 0, meaning immediate synchronous startup on initialization of this bean.\r\n  quartz.scheduler-factory.startup-delay=0\r\n  \r\n  ################################\r\n  #      Quartz Properties       #\r\n  ################################\r\n  \r\n  # Optional: a different resource location for quartz internal properties. \r\n  # (http://www.quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigMain.html)\r\n  quartz.properties-config-location=classpath:/org/quartz/quartz.properties\r\n  \r\n  # Optional: option to manage quartz internal properties via spring application properties. \r\n  # (http://www.quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigMain.html)\r\n  # you can also check org.quartz.impl.StdSchedulerFactory for static variables\r\n  quartz.properties.*\r\n  #example:\r\n  #quartz.properties.org.quartz.scheduler.rmi.export=true\r\n  \r\n  # If true, the properties from spring application will override the exsisting \r\n  # quartz properties from quartz.properties-config-location.\r\n  # If false only Springs quartz.properties.* will be used with fallback to file if empty.\r\n  quartz.override-config-location-properties=true\r\n  \r\n  ################################\r\n  #      Spring Boot Actuator    #\r\n  ################################\r\n  \r\n  # With 1.0.5\r\n  \r\n  # if set to true the TriggerMetricsListener will be added to Quartz listeners \r\n  # which requires a configured CounterService and GaugeService\r\n  quartz.metrics.enabled=false\r\n  \r\n  # listener name for Quartz. Default: class name\r\n  quartz.metrics.listener-name=\r\n  \r\n  # if metrics for counting fired job groups is enabled\r\n  quartz.metrics.enable-job-group-counter=false\r\n  \r\n  # if metrics for counting fired jobs should be enabled\r\n  quartz.metrics.enable-job-counter=true\r\n  \r\n  # if metrics for counting fired triggers should be enabled\r\n  quartz.metrics.enable-trigger-counter=true\r\n  \r\n  # if metrics for final instructions per job/trigger should be enabled\r\n  quartz.metrics.enable-execution-instruction-counter=false\r\n  \r\n  # if metrics for gauge of fired jobs should be enabled\r\n  quartz.metrics.enable-job-gauges=true\r\n  \r\n  # if metrics for gauge of fired triggers should be enabled\r\n  quartz.metrics.enable-trigger-gauges=true\r\n\r\n```\r\n\r\nThe Property `quartz.properties.org.quartz.scheduler.instanceName` is overridden by Spring by default with the SchedulerFactory bean name. To rename it, use `quartz.scheduler-factory.schedulerName`\r\n\r\n## Additional Things\r\n\r\n### Utils\r\nCheck `de.chandre.quartz.spring.QuartzUtils` for Builders for JobDetail, SimpleTrigger and CronTrigger\r\n\r\n### Hooks\r\nIf you want to add scheduler properties at runtime while application start-up, you are able to do that by implementing the `de.chandre.quartz.spring.QuartzPropertiesOverrideHook` (Maybe if your Configuration is stored in a database, or you want to change the Quartz table prefix with Hibernate's common table prefix).\r\n\r\nIf you want to customize the SchedulerFactory, e.g. to set own task executor, you are able to do that by implementing the `de.chandre.quartz.spring.QuartzSchedulerFactoryOverrideHook`\r\n\r\nExample:\r\n\r\n```java\r\n@Configuration\r\n@AutoConfigureBefore(QuartzSchedulerAutoConfiguration.class)\r\npublic class SchedulerConfig\r\n{\r\n\tprivate static final Logger LOGGER = LogManager.getFormatterLogger(SchedulerConfig.class);\r\n\t\r\n\tprivate static final String QRTZ_TABLE_PREFIX_KEY = \"org.quartz.jobStore.tablePrefix\";\r\n\t\r\n\tprivate static final String QRTZ_JOB_CLASS = \"org.quartz.jobStore.class\";\r\n\r\n\t@Bean\r\n\tpublic QuartzPropertiesOverrideHook quartzPropertiesOverrideHook() {\r\n\t\treturn new QuartzPropertiesOverrideHook() {\r\n\r\n\t\t\t@Override\r\n\t\t\tpublic Properties override(Properties quartzProperties) {\r\n\t\t\t\tString jobclazz = (String) quartzProperties.get(QRTZ_JOB_CLASS);\r\n\t\t\t\tif (!jobclazz.contains(\"RAMJobStore\")) {\r\n\t\t\t\t\tString qrtzPrefix = (String) quartzProperties.get(QRTZ_TABLE_PREFIX_KEY);\r\n\t\t\t\t\tLOGGER.info(\"setting %s to %s\", QRTZ_TABLE_PREFIX_KEY, MyCustomNamingStrategy.getPrefix() + qrtzPrefix);\r\n\t\t\t\t\tquartzProperties.put(QRTZ_TABLE_PREFIX_KEY, MyCustomNamingStrategy.getPrefix() + qrtzPrefix);\r\n\t\t\t\t}\r\n\t\t\t\treturn quartzProperties;\r\n\t\t\t}\r\n\t\t};\r\n\t}\r\n\t\r\n\t@Bean\r\n\tpublic QuartzSchedulerFactoryOverrideHook quartzSchedulerFactoryOverrideHook() {\r\n\t\treturn new QuartzSchedulerFactoryOverrideHook() {\r\n\t\t\r\n\t\t\t@Override\r\n\t\t\tpublic SchedulerFactoryBean override(SchedulerFactoryBean factory, QuartzSchedulerProperties properties,\r\n\t\t\t\t\tProperties quartzProperties) {\r\n\t\t\t\t\t\r\n\t\t\t\t// when doing this you may should not set \"quartz.properties.org.quartz.threadPool.class\" in properties\r\n\t\t\t\tfactory.setTaskExecutor(Executors.newFixedThreadPool(10));\r\n\t\t\t\treturn factory;\r\n\t\t\t}\r\n\t\t};\r\n\t}\r\n}\r\n```\r\n\r\n### Job interdependencies (With 1.0.5)\r\nSince 1.0.5 there are also predefined classes to queue dependent jobs. This implementation aims to jobs modifying same resources or should not run together at all.\r\n\r\nFirst defining the queue service\r\n\r\n```java\r\n\t\r\n@Bean(name=\"queueService\")\r\npublic QueueService\u003cFuture\u003cJobExecutionResult\u003e\u003e callbackQueueServiceImpl() {\r\n\t//AsyncQueueServiceImpl or any own implemented service\r\n\treturn new CallbackQueueServiceImpl();\r\n}\r\n\r\n```\r\n\r\nAfterwards within the job\r\n\r\n```java\r\n\r\n@Scope(scopeName=ConfigurableBeanFactory.SCOPE_PROTOTYPE)\r\npublic class CallbackQueuedJob implements Job, QueuedInstance\r\n{\r\n\tprivate final Log LOGGER = LogFactory.getLog(CallbackQueuedJob.class);\r\n\t\r\n\tpublic static String GROUP = \"myGroup\";\r\n\t\r\n\t@Autowired\r\n\tprivate QueueService\u003cFuture\u003cJobExecutionResult\u003e\u003e queueService;\r\n\t\r\n\tprivate JobExecutionContext context = null;\r\n\t\r\n\t@Override\r\n\tpublic String getGroup() {\r\n\t\treturn GROUP;\r\n\t}\r\n\t\r\n\t@Override\r\n\tpublic String getName() {\r\n\t\tif (null != context) {\r\n\t\t\treturn context.getTrigger().getKey().getName();\r\n\t\t}\r\n\t\treturn QueuedInstance.super.getName();\r\n\t}\r\n\t\r\n\t@Override\r\n\tpublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {\r\n\t\tthis.context = jobExecutionContext;\r\n\t\tFuture\u003cJobExecutionResult\u003e future= queueService.queueMe(this);\r\n\t\ttry {\r\n\t\t\tif (null != future) {\r\n\t\t\t\tJobExecutionResult jer = future.get(10000L, TimeUnit.MILLISECONDS);\r\n\t\t\t\tif (jer.getException() != null) {\r\n\t\t\t\t\tthrow new JobExecutionException(jer.getException());\r\n\t\t\t\t}\r\n\t\t\t\t//do something else...\r\n\t\t\t} else {\r\n\t\t\t\tLOGGER.info(\"job not added \" + jobExecutionContext.getTrigger().getKey().getName());\r\n\t\t\t}\r\n\t\t} catch (InterruptedException | ExecutionException | TimeoutException e) {\r\n\t\t\tthrow new JobExecutionException(e);\r\n\t\t}\r\n\t}\r\n\r\n\t@Override\r\n\tpublic boolean run() {\r\n\t\t//doing someing ... \r\n\t\t/*\r\n\t\t * can use this.context because my job bean should be a prototype\r\n\t\t */\r\n\t\treturn true;\r\n\t}\r\n}\r\n\r\n```\r\n\r\n## Recommended Maven Dependency Management\r\n\r\nBecause Quartz still will have some transitive dependencies you may don't want to have in your application, you should consider about the following dependency settings.\r\n\r\n```xml\r\n\u003cdependency\u003e\r\n\t\u003cgroupId\u003eorg.quartz-scheduler\u003c/groupId\u003e\r\n\t\u003cartifactId\u003equartz\u003c/artifactId\u003e\r\n\t\u003cversion\u003e${quartz-version}\u003c/version\u003e\r\n\t\u003cexclusions\u003e\r\n\t\t\u003cexclusion\u003e\r\n\t\t\t\u003cgroupId\u003ecom.mchange\u003c/groupId\u003e\r\n\t\t\t\u003cartifactId\u003ec3p0\u003c/artifactId\u003e\r\n\t\t\u003c/exclusion\u003e\r\n\t\t\u003cexclusion\u003e\r\n\t\t\t\u003cgroupId\u003ecom.mchange\u003c/groupId\u003e\r\n\t\t\t\u003cartifactId\u003emchange-commons-java\u003c/artifactId\u003e\r\n\t\t\u003c/exclusion\u003e\r\n\t\t\u003cexclusion\u003e\r\n\t\t\t\u003cgroupId\u003ecom.zaxxer\u003c/groupId\u003e\r\n\t\t\t\u003cartifactId\u003eHikariCP-java6\u003c/artifactId\u003e\r\n\t\t\u003c/exclusion\u003e\r\n\t\u003c/exclusions\u003e\r\n\u003c/dependency\u003e\r\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrehertwig%2Fspring-boot-starter-quartz","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandrehertwig%2Fspring-boot-starter-quartz","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrehertwig%2Fspring-boot-starter-quartz/lists"}