Spring Scheduling back up - java

I have a simple spring application which has a Cron job like this.
#Service
#EnableScheduling
public class sampleClass {
#Scheduled(cron = "0 0/30 * * * *")
public void demoServiceMethod()
{
//executes something
}
}
This works fine and executes every 30 minutes. Now i'm looking for a way that if the server is down at a certain time and if it misses this scheduling, a way to find out, so I can trigger another process to cover the server being down. I'm quite new to spring scheduling and the answer might be obvious, but I could not find it. So thanks in advance.

Related

how to create scheduler which triggers a job at every 13 hours in java

how to create scheduler which triggers a job at every 13 hours in java
for example if it starts at
12 am then triggers a job at 1 pm
1 pm then triggers a job at 2 am
what about using #Scheduled(cron="0 0 */13 * * * ")
EDIT:
you can check here the only difference is that spring has added the first place (first *) for seconds.
EDIT2:
you can actually use also fixedRate
#Scheduled(fixedRate="13", timeunit=TimeUnit.HOURS)
In Spring Boot, you can just annotate a method with the #Scheduled annotation and the main class with the #EnableScheduling.
Examples:
Main class in Spring application
#EnableScheduling
#SpringBootApplication
public class ScheduledDemoApplication {
public static void main(String[] args) {
SpringApplication.run(ScheduledDemoApplication.class, args);
}
}
and create a method in a separate class that will be triggered on a schedule:
#Scheduled(some cron exp here)
public void execute() {
// some logic that will be executed on a schedule
}
This should work fine.
Here is a good article on how to schedule a Spring Boot task.

Spring Boot and Togglz: Catching feature activation time and do some action when feature became active

I have feature togglz in my spring boot application. There are some features which are successfully work for the moment. So now I need to do some operation right in the time when one of my feature is activated.
Is there any way to do that?
By using Spring Scheduling you can resolve your problem.
step 1: Enable scheduling for this annotation #EnableScheduling at class level
step 2: You can use any pattern like, hourly, minute, fixed delay,..etc.
#Scheduled(fixedRate = 10000)
#Scheduled(cron = "0 * * * * MON-FRI")`enter code here`
void checTogglzk() {
// ...
}
I would implement Custom ActivationStrategy and call your method within it.
Example how to do it in toggz doc: https://www.togglz.org/documentation/activation-strategies.html

Implement background process in Spring

I need to implement Spring process which checks database table for new rows and makes calculations. I'm thinking to implement infinite loop which is triggered every 10 minutes.
Is there someway to implement this with Spring Boot? I can always use Java Thread but it's for sure it's better to let Spring to manage this.
You can try scheduling with Spring Schedule
Here is a official example
Technically, you enable scheduling with #EnableScheduling and annotated your task with #Scheduled(fixedRate=600000).
Another config you can used to tune your scheduler:
fixedRate: Execute the annotated method with a fixed period in milliseconds between invocations.
fixedDelay: Execute the annotated method with a fixed period in milliseconds between the end of the last invocation and the start of the next.
cron: A cron-like expression, extending the usual UN*X definition to include triggers on the second as well as minute, hour, day of month, month and day of week.
find the below sample code
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
#Component
public class AppScheduler {
#Scheduled(fixedRate = 10000)
public void myScheduler() {
System.out.println("Test print");
}
}
It looks like this questions is old, but I would like to answer.
See, you can make an object of ThreadPoolTaskExecutor and assign the background process to it.
Here is my detailed code if anyone wants to see.
https://github.com/xbox2204/SpringBoot-JPA-Swagger-Angular
First thing to do would be, add these two annotation in your application starter class.
#EnableAsync
#EnableScheduling
Now, create you TaskExceutor in the same class and assign it to bean with a name, so that background tasks can be created anywhere in your application and attached with this bean.
#Bean(name="thPlExectr")
public Executor getExecutor(){
return new ThreadPoolTaskExecutor();
}
Now create a component class somewhere in the project, where you you will create the background task.
Here, you will mention the frequency with which you want your task to be exceuted. I wanted to print a statement every 5 second, you can choose your own frequency and give your own method definiton. Also, make it async and attach it with the TaskExecutor bean mentioned above, so that it doesn't interrupt the normal flow of your application.
#Component
public class BackgroundTasks {
private static final Logger log= LoggerFactory.getLogger(BackgroundTasks.class);
#Async("thPlExectr")
#Scheduled(fixedRate = 5000)
public void backTask(){
log.info("Hi Vineet! I am a background task");
}
}

Update Cron expression in SpringBoot #Scheduled

I have around 10 jobs scheduled with #Scheduled and a hardcoded cron expression like this:
#Scheduled(cron = "* * 1 * * *")
public void testMethod(){
doSomething();
}
Now i want to be able to through the database update this cron expression and reschedule the specific job in runtime.
Does anyone knows how to do this?
Thanks
If you want to configure the scheduling of job at runtime, I don't think you can use the annotation #Scheduled.
You can use your own scheduler instead from Spring documentation :
scheduler.schedule(task, new CronTrigger("0 15 9-17 * * MON-FRI"));
Then, if you want to change the configuration, you can cancel the scheduling and create a new one.
TaskScheduler return a ScheduledFuture that you should save somewhere and it can be cancelled with cancel(...) method.
I think that #Scheduled no support this feature (must be interesting implement that). For advance scheduling feature you need to use quartz or other scheduler solution. My answer is based on Quartz Solution:
#Component
class ReschedulerComponent{
#Autowired
private SchedulerFactoryBean schedulerFactoryBean;
public void reSchedule(){
Trigger oldTriger = schedulerFactoryBean.getScheduler().getTrigger("my_custom_trigger");
Trigger myNewTrigger = TriggerBuilder
.newTrigger()
.forJob(jobDetail) // Name of your job
.withIdentity("my_custom_trigger")
.startAt(myNewDATE)
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withMisfireHandlingInstructionFireNow())
.build();
schedulerFactoryBean.getScheduler().rescheduleJob(oldTriger.getKey(), myNewTrigger);
}
}
Quick introduction: https://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/scheduling.html
This can be done by specifying the cron expression in your property place holder as mentioned below. Add below code in #configuration class.
#Bean
public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
PropertySourcesPlaceholderConfigurer properties = new PropertySourcesPlaceholderConfigurer();
properties.setLocation(new ClassPathResource("test.properties"));
return properties;
}
Now test.properties will be available in your placeholder. Test.properties shown below
variable.name.inside.properties= 00 39 05 * * *
Then inside your scheduler class add
#Scheduled(cron = "${variable.name.inside.properties}")
public void testMethod(){
doSomething();
}
I think you should look at this resource
You can programmatically create scheduled jobs. So if you annotate your method with #PostConstruct it should pick it when the application starts and run at the scheduled time
https://www.programcreek.com/java-api-examples/index.php?api=org.quartz.impl.triggers.SimpleTriggerImpl
http://www.quartz-scheduler.org/api/2.2.1/org/quartz/impl/triggers/SimpleTriggerImpl.html
If you want to configure schedule of the job, so that you don't need to change the code, I suggest you to extract value in property stored in some configuration.properties, then access to it in code with #Value.
UPD: found this topic, maybe you find it useful
Spring Scheduler change cron expression dynamically

Spring schedule cron does not work with hours [duplicate]

How can I configure the time zone for a Spring based #Scheduled cron job?
Background:
I have a job that executes once a day, say 2 PM, using Spring's #Scheduled annotation:
#Scheduled(cron = "0 0 14 * * *")
public void execute() {
// do scheduled job
}
The problem is that 2 PM differs between different servers, because Spring uses on TimeZone.getDefault() internally. Moreover, the JavaDoc of TimeZone.getDefault() states that:
Gets the default TimeZone for this host. The source of the default TimeZone may vary with implementation.
In other words, the time zone is not determined. It may depend on JVM implementation, server time zone configuration, server location, and / or other unknown factors. Consequently, the cron job triggers on different times on different servers, unless there is a way to explicitly set which time zone that should be used?
I am using Spring 3.2.2.
Update
As of Spring 4, Spring Jira issue SPR-10456 has been resolved. Consequently, the #Scheduled annotation has a new zone attribute for exactly this purpose.
It turned out that I could not use the #Scheduled annotation, but I implemented a work-around. In the JavaDoc of the SchedulingConfigurer it is stated that:
[SchedulingConfigurer is] Typically used for setting a specific TaskScheduler bean to be used when executing scheduled tasks or for registering scheduled tasks in a programmatic fashion as opposed to the declarative approach of using the #Scheduled annotation.
Next, I changed the cron job to implement the Runnable interface and then updated my configuration file to implement the SchedulingConfigurer, see below:
#Configuration
#EnableScheduling
#ComponentScan("package.that.contains.the.runnable.job.bean")
public class JobConfiguration implements SchedulingConfigurer {
private static final String cronExpression = "0 0 14 * * *";
private static final String timeZone = "CET";
#Autowired
private Runnable cronJob;
#Bean
CronTrigger cronTrigger() {
return new CronTrigger(cronExpression, TimeZone.getTimeZone(timeZone));
}
#Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addCronTask(new CronTask(job, cronTrigger()));
}
}
Please read the JavaDoc of the #EnableScheduling for more information.
Update
As of Spring 4, Spring Jira issue SPR-10456 has been resolved. Consequently, the #Scheduled annotation has a new zone attribute for exactly this purpose, e.g.
#Scheduled(cron = "0 0 14 * * *", zone = "CET")
public void execute() {
// do scheduled job
}
There is element zone in annotation #Scheduled, starting from version 4.0.
You can insert a timezone as a string that can be accepted by java.util.TimeZone.
Your code should be like this:
#Scheduled(cron = "0 0 14 * * *", zone = "GMT-5")
public void execute() {
// do scheduled job
}
"Zone" is gonna be the desired country's timezone.
Here is a nice tutorial about scheduled tasks with Spring:
https://www.baeldung.com/cron-expressions
You can also use time zone with #Scheduled tag in spring-boot like this :
#Scheduled(cron = "0 0 14 * * *" , zone = "GMT+5:00")
public void execute() {
// do the scheduled job
}
I doubt you want different jobs or parts of application to use different time zones. Assuming you want to have it all consistent and DRY, either configure OS on all servers to have consistent time zone, or set user.timezone Java system property for all of the application servers. Centrally manage configuration (OS, application server), and for that puppet and chef can be very useful.

Categories