Search code examples
javaspringspring-bootcron

Get the spring boot scheduled cron expression from outside jar file


I have a spring boot java service I have to schedule to run on a particular time. I have enabled the @Enablescheduling and @Scheduled annotation and given the cron expression.

It's working fine. The scheduler is running at the expected time. But my concern is I should control the cron expression somewhere from outside my jar file. I have tried using it in property file but when packaging my property file also getting included in that.

Sample code:

    @PostMapping(path = "getoktatodynamodb")
    @Scheduled(cron = "0 0/5 0 * * ?")
    @ApiOperation("Sync data to DynamoDB")
    public FinalResponse getdatatodynamodb() {
        FinalResponse finalResponse = new FinalResponse();
        try {
            LOGGER.info("Sync data to DynamoDB starts - " + new Date());
            finalResponse = dynamodbuserService.dynamoDbSync();
        } catch (MyRestTemplateException ex) {
            LOGGER.error(ex.getMessage());
            finalResponse.setResponseMessage(ex.getMessage());
            finalResponse.setStatusCode(ex.getStatusCode().value());
        } catch (Exception execption) {
            LOGGER.error(execption.getMessage());
            finalResponse.setResponseMessage(execption.getMessage());
            finalResponse.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
        } finally {
            LOGGER.info("Sync data DynamoDB Ends - " + new Date());
        }
        return finalResponse;
    }

The main intention is scheduler should be in our control whenever we need to change the time it should be configurable. No code change and restarting the scheduler for minor changes.

How should we achieve this also we would like to schedule this in linux ec2 instance? in case if we have better suggestion to achieve this kindly share it.


Solution

  • You can implement SchedulingConfigurer: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/SchedulingConfigurer.html

    This DZone article shows a really good example: https://dzone.com/articles/schedulers-in-java-and-spring which I'm showing here in case the article doesn't stay permanent.

    @Configuration
    @EnableScheduling
    public class ScheduledConfiguration implements SchedulingConfigurer {
        TaskScheduler taskScheduler;
        private ScheduledFuture<?> job1;
        private ScheduledFuture<?> job2;
        @Override
        public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
            ThreadPoolTaskScheduler threadPoolTaskScheduler =new ThreadPoolTaskScheduler();
            threadPoolTaskScheduler.setPoolSize(10);// Set the pool of threads
            threadPoolTaskScheduler.setThreadNamePrefix("scheduler-thread");
            threadPoolTaskScheduler.initialize();
            job1(threadPoolTaskScheduler);// Assign the job1 to the scheduler
            // Assign the job1 to the scheduler
            this.taskScheduler=threadPoolTaskScheduler;// this will be used in later part of the article during refreshing the cron expression dynamically
            taskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
        }
        private void job1(TaskScheduler scheduler) {
            job1 = scheduler.schedule(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + " The Task1 executed at " + new Date());
                    try {
                        Thread.sleep(10000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }, new Trigger() {
                @Override
                public Date nextExecutionTime(TriggerContext triggerContext) {
                    String cronExp = "0/5 * * * * ?";// Can be pulled from a db .
                    return new CronTrigger(cronExp).nextExecutionTime(triggerContext);
                }
            });
        }
        private void job2(TaskScheduler scheduler){
            job2=scheduler.schedule(new Runnable(){
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+" The Task2 executed at "+ new Date());
                }
            }, new Trigger(){
                @Override
                public Date nextExecutionTime(TriggerContext triggerContext) {
                    String cronExp="0/1 * * * * ?";//Can be pulled from a db . This will run every minute
                    return new CronTrigger(cronExp).nextExecutionTime(triggerContext);
                }
            });
        }
    }