I set following properties in my quartz.properties file:
org.quartz.threadPool.threadCount = 60
org.quartz.scheduler.batchTriggerAcquisitionMaxCount = 60
, however, for some reason, apparently it doesn't take effect. because when I start my application, the log shows that it still uses 1 thread in the pool:
[main] INFO org.quartz.impl.StdSchedulerFactory - Using default implementation for ThreadExecutor
[main] INFO org.quartz.core.SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
[main] INFO org.quartz.core.QuartzScheduler - Quartz Scheduler v.2.1.1 created.
[main] INFO org.quartz.simpl.RAMJobStore - RAMJobStore initialized.
[main] INFO org.quartz.core.QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.1.1) 'QuartzScheduler' with instanceId 'NON_CLUSTERED' Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally. NOT STARTED. Currently in standby mode. Number of jobs executed: 0
Using **thread pool 'org.quartz.simpl.SimpleThreadPool' - with 1 threads.**
I know, the quartz.properties needs to be at class path to be found. and I just did it.
any other reason why this file is not detected? or it is detected but number of threads is not set correctly?
Thanks
For those who are using Spring + Quartz and quartz.properties file is not working (i.e. gets ignored while starting the application):
Quartz Scheduler (org.quartz.Scheduler) instantiated by Spring Factory Bean (org.springframework.scheduling.quartz.SchedulerFactoryBean) won't read quartz.properties file from the classpath by default as it's said in Quartz docs - you need to set the reference manually:
[in case of Java config]:
#Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
schedulerFactoryBean.setConfigLocation(new ClassPathResource("quartz.properties"));
// ...
}
[in case of XML config]:
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="configLocation" value="classpath:quartz.properties" />
// ...
</bean>
oops, I found the problem, actually the code was overriding the properties file config by creating an instance of Properties class in the code. so the answer is this line:
sf = new StdSchedulerFactory("conf/quartz.properties");
If someone still looking for answer, they can use the below snippet
#Bean
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
SchedulerFactoryBean scheduler = new SchedulerFactoryBean();
scheduler.setTriggers(jobOneTrigger());
scheduler.setQuartzProperties(quartzProperties());
scheduler.setJobDetails(jobOneDetail());
return scheduler;
}
#Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
Related
I'm setting up a Quartz Scheduler in Spring Boot. I want the scheduled Jobs to be able to inject Beans from the Application Context. For that I created my own Quartz Job Factory:
public final class MyQuartzJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private transient AutowireCapableBeanFactory beanFactory;
#Override
public void setApplicationContext(final ApplicationContext context) throws BeansException {
beanFactory = context.getAutowireCapableBeanFactory();
}
#Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
beanFactory.autowireBean(job);
return job;
}
}
For keeping a reference to the Scheduler, I have a SchedulerManager Bean that initializes the Scheduler:
public void initScheduler() {
try (InputStream propsInputStream = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("my-quartz.properties")) {
log.info("Creating Quartz scheduler...");
Properties myQuartzProperties = new Properties();
myQuartzProperties.load(propsInputStream);
SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
schedulerFactory.setQuartzProperties(myQuartzProperties);
schedulerFactory.afterPropertiesSet();
schedulerFactory.setJobFactory(quartzJobFactory);
this.scheduler = schedulerFactory.getScheduler();
this.schedulingConfigMap = new HashMap<>();
log.info("Quartz scheduler created.");
} catch (Exception e) {
log.error("Unable to create Quartz scheduler", e);
throw new RuntimeException("Scheduler extension initialization error", e);
}
}
I do the initialization of the Scheduler once the context has been initialized:
public class MyLifecycleListener implements ServletContextListener {
private final SchedulerManager schedulerManager;
#Override
public void contextInitialized(ServletContextEvent sce) {
schedulerManager.initScheduler();
}
}
The quartz configuration file is as follows:
org.quartz.scheduler.instanceName=MyQuartzScheduler
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=12
org.quartz.threadPool.threadPriority=5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true
org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore
org.quartz.jobStore.misfireThreshold=60000
When starting the application I see my Quartz Scheduler is initialized, but the problem is that I see a second Quartz Scheduler initialized (maybe a Spring default one?).
Mine: 'MyQuartzScheduler' with 12 threads
2022-08-23 14:13:03.239 INFO 24788 --- [ main] org.quartz.core.QuartzScheduler : Quartz Scheduler v.2.3.2 created.
2022-08-23 14:13:03.240 INFO 24788 --- [ main] org.quartz.simpl.RAMJobStore : RAMJobStore initialized.
2022-08-23 14:13:03.241 INFO 24788 --- [ main] org.quartz.core.QuartzScheduler : Scheduler meta-data: Quartz Scheduler (v2.3.2) 'MyQuartzScheduler' with instanceId 'NON_CLUSTERED'
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 12 threads.
Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
2022-08-23 14:13:03.241 INFO 24788 --- [ main] org.quartz.impl.StdSchedulerFactory : Quartz scheduler 'MyQuartzScheduler' initialized from an externally provided properties instance.
Some milliseconds later, another one called 'quartzScheduler' with 10 threads.
2022-08-23 14:13:03.713 INFO 24788 --- [ main] org.quartz.core.QuartzScheduler : Quartz Scheduler v.2.3.2 created.
2022-08-23 14:13:03.713 INFO 24788 --- [ main] org.quartz.simpl.RAMJobStore : RAMJobStore initialized.
2022-08-23 14:13:03.713 INFO 24788 --- [ main] org.quartz.core.QuartzScheduler : Scheduler meta-data: Quartz Scheduler (v2.3.2) 'quartzScheduler' with instanceId 'NON_CLUSTERED'
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
2022-08-23 14:13:03.713 INFO 24788 --- [ main] org.quartz.impl.StdSchedulerFactory : Quartz scheduler 'quartzScheduler' initialized from an externally provided properties instance.
How can I disable this second one?
Sample project can be found here: https://github.com/dajoropo/spring-quartz-demo/tree/stackoverflow_question_73459083
The easiest way is to use the Spring configured scheduler instead of doing it yourself. Move the quartz.properties to the spring.quartz namespace in the application.properties.
spring.quartz.scheduler-name=MyQuartzScheduler
spring.quartz.properties.org.quartz.threadPool.threadCount=12
spring.quartz.properties.org.quartz.threadPool.threadPriority=5
spring.quartz.properties.org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true
spring.quartz.properties.org.quartz.jobStore.misfireThreshold=60000
To configure your own JobFactory write a SchedulerFactoryBeanCustomizer to configure it on the SchedulerFactoryBean.
#Component
class MySchedulerFactoryBeanCustomizer implements SchedulerFactoryBeanCustomizer {
void customize(SchedulerFactoryBean schedulerFactoryBean) {
schedulerFactoryBean.setJobFactory(new MyQuartzJobFactory());
}
}
Now ditch the quartz.properties, MyLifecycleListener and the SchedulerManager and let Spring handle all that for you.
I want to move our Quartz Scheduling configuration to our application.yml instead of maintaining a separate quartz.properties file.
Our Spring Boot application runs and picks up the configuration as expected when using quartz.properties file, but it doesn't pick up the config from application.yml.
Scheduler bean:
#SpringBootApplication
public class MyApp{
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
...
#Bean
public Scheduler scheduler(SomeCustomConfig cfg, RestTemplate restTemplate) throws SchedulerException {
//StdSchedulerFactory schedulerFactory = new StdSchedulerFactory();
//schedulerFactory.initialize("quartz.properties");
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.getContext().put("restTemplate", restTemplate);
scheduler.getContext().put("cfg", cfg);
return scheduler;
}
}
Pertinent application.yml:
spring:
application.name: myApp
quartz:
properties:
org:
quartz:
scheduler:
instanceId: AUTO
threadPool:
threadCount: 5
plugin:
shutdownhook:
class: org.quartz.plugins.management.ShutdownHookPlugin
cleanShutdown: TRUE
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
tablePrefix: my_schema.
isClustered: true
dataSource: myDataSource
dataSource:
myDataSource:
driver: org.postgresql.Driver
URL: jdbc:postgresql://localhost/myDataSource
user: removed
password: removed
Our quartz.properties was:
org.quartz.scheduler.instanceId = AUTO
org.quartz.plugin.shutdownhook.class = org.quartz.plugins.management.ShutdownHookPlugin
org.quartz.plugin.shutdownhook.cleanShutdown = TRUE
org.quartz.threadPool.threadCount = 5
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
org.quartz.jobStore.tablePrefix = my_schema.
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.dataSource = myDataSource
org.quartz.dataSource.myDataSource.driver = org.postgresql.Driver
org.quartz.dataSource.myDataSource.URL = jdbc:postgresql://localhost/myDataSource
org.quartz.dataSource.myDataSource.user = removed
org.quartz.dataSource.myDataSource.password = removed
I feel like I'm missing something?
Instead of
spring:
quartz:
properties:
org:
quartz:
jobStore:
isClustered: true
Use this layout:
spring:
quartz:
properties:
org.quartz.jobStore:
isClustered: true
org.quartz.scheduler:
instanceId: AUTO
With the latter layout, I get:
2019-09-06 13:45:19.919 INFO PID --- [ main] o.q.c.QuartzScheduler : {} Scheduler meta-data: Quartz Scheduler (v2.3.0) 'quartzScheduler' with instanceId '0157799997'
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
Using job-store 'org.springframework.scheduling.quartz.LocalDataSourceJobStore' - which supports persistence. and is clustered.
Your application.yml configuration sets for spring-boot-starter-quartz and I think you are using org.quartz-scheduler independently. So you should config your application.yml something like this:
spring:
application.name: myApp
org:
quartz:
scheduler:
instanceId: AUTO
threadPool:
threadCount: 5
plugin:
shutdownhook:
class: org.quartz.plugins.management.ShutdownHookPlugin
cleanShutdown: TRUE
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
tablePrefix: my_schema.
isClustered: true
dataSource: myDataSource
dataSource:
myDataSource:
driver: org.postgresql.Driver
URL: jdbc:postgresql://localhost/myDataSource
user: removed
password: removed
I have recently worked with Spring Boot Quartz Application and was facing a similar issue where the quartz.properties was not being detected by application where I was using application.yml to hold application environment variable
spring:
quartz:
properties:
org.quartz.scheduler:
instanceName: ${QUARTZ_SCHEDULER_INSTANCE_NAME:Scheduler}
instanceId: ${QUARTZ_SCHEDULER_INSTANCE_ID:AUTO}
makeSchedulerThreadDaemon: ${QUARTZ_SCHEDULER_MAKE_THREAD_DAEMON:true}
org.quartz.jobStore:
class: ${QUARTZ_JOBSTORE_CLASS:org.quartz.impl.jdbcjobstore.JobStoreTX}
driverDelegateClass: ${QUARTZ_JOBSTORE_DRIVER:org.quartz.impl.jdbcjobstore.PostgreSQLDelegate}
tablePrefix: ${QUARTZ_JOBSTORE_TABLE_PREFIX:qrtz_}
isClustered: ${QUARTZ_JOBSTORE_ISCLUSTER:false}
dataSource: ${QUARTZ_JOBSTORE_DATASOURCE:myDS}
misfireThreshold: ${QUARTZ_JOBSTORE_MISFIRE_THRESHOLD:25000}
org.quartz.threadPool:
class: ${QUARTZ_THREADPOOL_CLASS:org.quartz.simpl.SimpleThreadPool}
makeThreadsDaemons: ${QUARTZ_THREADPOOL_DAEMON:true}
threadCount: ${QUARTZ_THREADPOOL_COUNT:20}
threadPriority: ${QUARTZ_THREADPOOL_PRIORITY:5}
org.quartz.dataSource:
myDS:
driver: ${SPRING_DATASOURCE_DRIVER:org.postgresql.Driver}
URL: ${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/postgres}
user: ${SPRING_DATASOURCE_USERNAME:postgres}
password: ${SPRING_DATASOURCE_PASSWORD:postgres}
maxConnections: ${SPRING_DATASOURCE_MAX_CONNECTION:20}
validationQuery: ${SPRING_DATASOURCE_VALIDATION_QUERY:select 1}
By using the above configuration in the above format, I was not only able to trigger Quartz jobs , i was also able to store in database
I have spring boot application with it's application.properties file. The project has a dependency on third-party library, in my case its:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
The library has its quartz.properties file with configs. I would like to override some values, e.g.:
org.quartz.threadPool.threadCount:10
to have another number of threads.
How can I do it using my own properties file and/or environment variable?
With Spring boot 2 application ( assuming you have the spring-boot-starter-quartz ), you can just specify the properties directly:
spring:
quartz:
properties:
org.quartz.threadPool.threadCount:10
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-quartz.html
Quartz Scheduler configuration can be customized by using Quartz configuration properties ()spring.quartz.properties.*) and SchedulerFactoryBeanCustomizer beans, which allow programmatic SchedulerFactoryBean customization.
You can override this value creating your own property resolver:
#Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
And in your quartz.properties:
#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceId = AUTO
org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer = true
org.quartz.scheduler.skipUpdateCheck = true
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 20
#Thread.MAX_PRIORITY 10
org.quartz.threadPool.threadPriority: 5
#============================================================================
# Configure JobStore
#============================================================================
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
Here you can check code example.
https://www.quickprogrammingtips.com/spring-boot/spring-boot-quartz-scheduler-integration.html
https://gist.github.com/cardosomarcos/149f915b966f7bb132f436dae5af1521
I have this Spring Boot app. using Quartz (a richly featured, open source job scheduling library that can be integrated within virtually any Java application ) to execute a Job the 10th day of the month
#EnableScheduling
#SpringBootApplication
public class IberiaUtilsApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(IberiaUtilsApplication.class);
app.run(args);
}
#Override
public void run(String... args) throws Exception {
..
}
}
and inside the config package:
#Configuration
public class JobConfig {
#Bean
public JobDetail sampleJobDetail() {
return JobBuilder.newJob(MonthlyIberiaMetrics.class).withIdentity("iberiaJob")
.usingJobData("iberiaMetrics", "fleet").storeDurably().build();
}
#Bean
public Trigger sampleJobTrigger() {
return newTrigger()
.forJob(sampleJobDetail())
.withIdentity("iberiaTrigger")
.withSchedule(cronSchedule("0 0 10 10 * ?"))
.build();
}
}
I run the app. from the command line, using mvn spring-boot:run but it seems that the Quartz is not initialised:
...
017-10-31 15:11 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
2017-10-31 15:11 [main] WARN c.z.hikari.util.DriverDataSource - Registered driver with driverClassName=oracle.jdbc.driver.OracleDriver was not found, trying direct instantiation.
2017-10-31 15:12 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
2017-10-31 15:12 [main] INFO org.quartz.impl.StdSchedulerFactory - Using default implementation for ThreadExecutor
2017-10-31 15:12 [main] INFO o.quartz.core.SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
2017-10-31 15:12 [main] INFO org.quartz.core.QuartzScheduler - Quartz Scheduler v.2.3.0 created.
2017-10-31 15:12 [main] INFO org.quartz.simpl.RAMJobStore - RAMJobStore initialized.
2017-10-31 15:12 [main] INFO org.quartz.core.QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.3.0) 'quartzScheduler' with instanceId 'NON_CLUSTERED'
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
2017-10-31 15:12 [main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler 'quartzScheduler' initialized from an externally provided properties instance.
2017-10-31 15:12 [main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler version: 2.3.0
2017-10-31 15:12 [main] INFO org.quartz.core.QuartzScheduler - JobFactory set to: org.springframework.boot.autoconfigure.quartz.AutowireCapableBeanJobFactory#64ea8964
2017-10-31 15:12 [main] INFO o.s.j.e.a.AnnotationMBeanExporter - Registering beans for JMX exposure on startup
2017-10-31 15:12 [main] INFO o.s.j.e.a.AnnotationMBeanExporter - Bean with name 'dataSource' has been autodetected for JMX exposure
2017-10-31 15:12 [main] INFO o.s.j.e.a.AnnotationMBeanExporter - Located MBean 'dataSource': registering with JMX server as MBean [com.zaxxer.hikari:name=dataSource,type=HikariDataSource]
2017-10-31 15:12 [main] INFO o.s.c.s.DefaultLifecycleProcessor - Starting beans in phase 2147483647
2017-10-31 15:12 [main] INFO o.s.s.quartz.SchedulerFactoryBean - Starting Quartz Scheduler now
2017-10-31 15:12 [main] INFO org.quartz.core.QuartzScheduler - Scheduler quartzScheduler_$_NON_CLUSTERED started.
2017-10-31 15:12 [Thread-3] INFO o.s.c.a.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#589ebb: startup date [Tue Oct 31 15:11:56 CET 2017]; root of context hierarchy
2017-10-31 15:12 [Thread-3] INFO o.s.c.s.DefaultLifecycleProcessor - Stopping beans in phase 2147483647
2017-10-31 15:12 [Thread-3] INFO org.quartz.core.QuartzScheduler - Scheduler quartzScheduler_$_NON_CLUSTERED paused.
2017-10-31 15:12 [Thread-3] INFO o.s.s.quartz.SchedulerFactoryBean - Shutting down Quartz Scheduler
2017-10-31 15:12 [Thread-3] INFO org.quartz.core.QuartzScheduler - Scheduler quartzScheduler_$_NON_CLUSTERED shutting down.
2017-10-31 15:12 [Thread-3] INFO org.quartz.core.QuartzScheduler - Scheduler quartzScheduler_$_NON_CLUSTERED paused.
2017-10-31 15:12 [Thread-3] INFO org.quartz.core.QuartzScheduler - Scheduler quartzScheduler_$_NON_CLUSTERED shutdown complete.
2017-10-31 15:12 [Thread-3] INFO o.s.j.e.a.AnnotationMBeanExporter - Unregistering JMX-exposed beans on shutdown
2017-10-31 15:12 [Thread-3] INFO o.s.j.e.a.AnnotationMBeanExporter - Unregistering JMX-exposed beans
2017-10-31 15:12 [Thread-3] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
2017-10-31 15:12 [Thread-3] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
MacBook-Pro-de-lopes:iberiaUtils lopes$
I also tried changing the expression to 0 * * * * ? (every minute) with the same result
and also created this other class with the same result:
public class ScheduledTasks1 {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
#Scheduled(cron = "0 * * * * ?")
public void reportCurrentTime() {
System.out.println("The time is now {}" +
dateFormat.format(new Date()));
}
}
for your information, I have another similar application without Quartz properties and its working fine:
#SpringBootApplication
public class IberiaReservationsApplication {
public static void main(String[] args) {
SpringApplication.run(IberiaReservationsApplication.class, args);
}
#Bean
public JobDetail sampleJobDetail() {
return JobBuilder.newJob(CheckDBJobExecution.class).withIdentity("sampleJob")
.usingJobData("name", "World").storeDurably().build();
}
#Bean
public Trigger sampleJobTrigger() {
return newTrigger()
.forJob(sampleJobDetail())
.withIdentity("sampleTrigger")
.withSchedule(cronSchedule("0 0/2 8-17 * * ?"))
.build();
}
}
Have you considered using Springs own scheduler, it's easy to configure and I've always found it to work well.
https://spring.io/guides/gs/scheduling-tasks/
You are missing various configuration for Quartz here like
Quartz properties
SchedulerFactoryBean
Follow below examples for complete implementation:
https://chynten.wordpress.com/2016/06/17/quartz-with-databse-and-spring-4/
http://www.baeldung.com/spring-quartz-schedule
New to Apache camel, I have a requirement that I need to look for a folder and move the files from source to destination every five minutes. I wrote the below code, but when I run the Job it is copying the files to destination irrespective of time when I copy the files to source, Please help me in understanding this :
import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.routepolicy.quartz.CronScheduledRoutePolicy;
public class App1 {
public static void main(final String[] arguments) {
final CamelContext camelContext = new DefaultCamelContext();
try {
camelContext.addRoutes(new RouteBuilder() {
#Override
public void configure() throws Exception {
CronScheduledRoutePolicy startPolicy = new CronScheduledRoutePolicy();
startPolicy.setRouteStartTime("0 0/5 * 1/1 * ? *");
from("file:E:\\TestingWatch1\\input")
.routeId("testRoute").routePolicy(startPolicy)
.to("file:E:\\TestingWatch1\\output");
}
});
camelContext.start();
Thread.sleep(10000);
//camelContext.stop();
} catch (Exception camelException) {
}
}
}
In order to schedule a route I have been using the CAMEL QUARTZ component. I believe Claus has been alluding to this option as well:
from("quartz://scheduler_name?cron={{cron.schedule}}")
.routeId("cron-scheduler")
cron.schedule value is set in params as:
00+00+*/2+1/1+*+?+*
I.e to run every two hours.
So to run every 5 minutes that would be something like:
00+*/5+*+1/1+*+?+*
As Claus Ibsen said, you can use cron directly:
public class CopyTest {
public static void main(final String[] arguments) {
final CamelContext camelContext = new DefaultCamelContext();
try {
camelContext.addRoutes(new RouteBuilder() {
#Override
public void configure() throws Exception {
from("file://c:/test/input?scheduler=quartz2&scheduler.cron=00+*/5+*+1/1+*+?+*")
.routeId("testRoute")
.log(LoggingLevel.INFO, "File name : ${header.CamelFileName}")
.to("file://c:/test/output");
}
});
camelContext.start();
Thread.sleep(10*60*1000);
//camelContext.stop();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
More info can be found here:
http://www.davsclaus.com/2013/08/apache-camel-212-even-easier-cron.html
or here:
http://camel.apache.org/file2.html URI options->Consumer->scheduler
or here:
http://camel.apache.org/quartz2.html Using QuartzScheduledPollConsumerScheduler
Here is my log:
2016-12-23 21:52:24,440 [main ] INFO DefaultCamelContext - Apache Camel 2.15.2 (CamelContext: camel-1) is starting
2016-12-23 21:52:24,440 [main ] INFO ManagedManagementStrategy - JMX is enabled
2016-12-23 21:52:25,329 [main ] INFO DefaultTypeConverter - Loaded 200 type converters
2016-12-23 21:52:25,985 [main ] INFO DefaultCamelContext - AllowUseOriginalMessage is enabled. If access to the original message is not needed, then its recommended to turn this option off as it may improve performance.
2016-12-23 21:52:25,985 [main ] INFO DefaultCamelContext - StreamCaching is not in use. If using streams then its recommended to enable stream caching. See more details at http://camel.apache.org/stream-caching.html
2016-12-23 21:52:26,187 [main ] INFO QuartzComponent - Create and initializing scheduler.
2016-12-23 21:52:26,187 [main ] INFO QuartzComponent - Setting org.quartz.scheduler.jmx.export=true to ensure QuartzScheduler(s) will be enlisted in JMX.
2016-12-23 21:52:26,312 [main ] INFO StdSchedulerFactory - Using default implementation for ThreadExecutor
2016-12-23 21:52:26,312 [main ] INFO SimpleThreadPool - Job execution threads will use class loader of thread: main
2016-12-23 21:52:26,359 [main ] INFO SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
2016-12-23 21:52:26,359 [main ] INFO QuartzScheduler - Quartz Scheduler v.2.2.1 created.
2016-12-23 21:52:26,390 [main ] INFO RAMJobStore - RAMJobStore initialized.
2016-12-23 21:52:26,421 [main ] INFO QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.2.1) 'DefaultQuartzScheduler-camel-1' with instanceId 'NON_CLUSTERED'
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
2016-12-23 21:52:26,421 [main ] INFO StdSchedulerFactory - Quartz scheduler 'DefaultQuartzScheduler-camel-1' initialized from an externally provided properties instance.
2016-12-23 21:52:26,421 [main ] INFO StdSchedulerFactory - Quartz scheduler version: 2.2.1
2016-12-23 21:52:26,999 [main ] INFO DefaultCamelContext - Route: testRoute started and consuming from: Endpoint[file://c:/test/input?scheduler=quartz2&scheduler.cron=00+*%2F5+*+1%2F1+*+%3F+*]
2016-12-23 21:52:26,999 [main ] INFO QuartzComponent - Starting scheduler.
2016-12-23 21:52:26,999 [main ] INFO QuartzScheduler - Scheduler DefaultQuartzScheduler-camel-1_$_NON_CLUSTERED started.
2016-12-23 21:52:26,999 [main ] INFO DefaultCamelContext - Total 1 routes, of which 1 is started.
2016-12-23 21:52:26,999 [main ] INFO DefaultCamelContext - Apache Camel 2.15.2 (CamelContext: camel-1) started in 2.574 seconds
2016-12-23 21:55:00,052 [amel-1_Worker-1] INFO testRoute - File name : client.log
You'll need the dependency:
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-quartz2</artifactId>
<version>${camel.version}</version>
</dependency>