Spring #Scheduled stops running when system time set back - spring

I have Spring Boot based cron job running:
#Scheduled(cron = "30 * * * * *}")
// #Scheduled(initialDelay = -1, fixedDelay = 60000)
public void cronCheck()
{
instance.refreshStatus();
if (instance.status.isVerified() && !instance.status.isExpired())
{
instance.updateCheckTime();
}
}
Most of the cases, it's running perfect. But when I changed the system time back , for example one month, it would run one single time and never run again. However, if I change system back forward, it would run as scheduled.
Anyone has any idea why this is happening and maybe a solution?
Highly appreciate it!

Related

SpringBoot Scheduler Cron over running

is there any expert having the issue using springboot scheduler
trying to set it to run between 2pm til 10pm on weekday every 15mins/per hour, but it seem like trigger by minute, is that because my cron is wrong or i shld do smthg to control it ?
running in linux server via springboot-web-started
#Scheduled(cron = "0 15 14-22 * * MON-FRI")
private void fireDownload() {
log.info("fireDownload");
this.jmsXXXX.run(Constants.XXXX);
}
version
spring-boot 2.4.2
java 11
Please try this
#Scheduled(cron = "0 */15 14-22 * * MON-FRI")
You say in a comment that this is not working, so let's test this with a simple proof-of-concept that fires every 5 minute
#Scheduled(cron = "0 */5 8-22 * * MON-FRI")
private void cronPOC() {
log.info("cronPOC triggered by cron");
}
Screen-shot below shows that the POC is indeed working.
While we're at testing, let's put #GerbenJongerius suggestion from comment above to the test as well (with some tiny changes in order to speed things up).
#Scheduled(cron = "0 0/5 8-22 ? * MON-FRI")
private void cronPOC() {
log.info("cronPOC triggered by cron v2");
}
... and this is also working
Some Spring cron examples with explanations here:
https://stackoverflow.com/a/26147143/14072498

scheduled cron expression that never runs

What I tried:
#Scheduled(cron="* * * 08 04 2099")
I want cron expression that never executes.can any one help me with the expression.
Thanks in advance...!
This cron will run every minute and task will be bound with condition.
If you need different cron job then you can generate using this website.
#Scheduled(cron = "0 0/1 * 1/1 * ? *")
protected void performTask() {
if (condition)//if value matches with database value
{
//perform the task
}
}
You can use.
#Scheduled(cron = "${cron.expression}")
cron.expression=-
This works from Spring 5.1.
See the docs.

Spring Boot scheduled task running for entire hour rather than at the hour

Spring Boot here. I have the following scheduled task:
#Component
public class AdminWatchdog {
#Autowired
private EmailService emailService;
// Ctors, getters & setters here
#Scheduled(cron = "'* * */12 * * *")
public void runReports() {
// Doesn't matter what it does, really
}
}
When I run this, it appears to be firing either every minute or every second (can't tell based on the logs) for the entire duration of the 12th hour of every day!
I only want this task to run one time every day at noon (12 pm). Is the Spring cron configured incorrectly or do I have something else going on in my app perhaps??
Your cron is incorrect. For running your job every noon every day use this
"0 0 12 * * ?"
The expression is very self explainatory if you understand what each character represent
0 0 12 * * ?
<second> <minute> <hour> <day-of-month> <month> <day-of-week>
For your reference. You can make use of tools like http://www.cronmaker.com/ to design your cron

Using schedule task(#schedule) in spring

Hello am working on a cron job and would like to schedule the task to run every 2 minute,the problem is instead of 2 minutes its starts around 1min 20sec.this is the cron schedule I have
#scheduled
(cron="${followed_forum_task_
crown_expression} ")
Then in my application.property file I have
followed_forum_task_
crown_expression = 0 0/2 * * * ?
You can use
#Scheduled(fixedDelay = 0, fixedRate = 2*1000*60)
instead of cron expression.

ejb poller always triggers at every 30 seconds

I have created EJB 3 Timer and it is deployed into weblogic cluster. The createTimer parameters are createTimer(1000, 20000, null);
This should create recurring timer for every 20 seconds. But the timer is always created every 30 seconds. I even changed the intervalDuration to 40 and 50 seconds but the timeout method is always triggered every 30 seconds.
Below are the entry from WEBLOGIC_TIMERS table
1##OSBNode2_1355845459844 (BLOB) 1355846770914 1000 TimerearTimerTest.jarTimerTest OSBDomain OSBCluster
Below are the entry from ACTIVE table
timer.1##OSBNode2_1355843156331 -96726833478167425/OSBNode2 OSBDomain OSBCluster 18-DEC-12
service.TimerMaster 8866906753834651127/OSBNode1 OSBDomain OSBCluster 18-DEC-12
service.SINGLETON_MASTER 8866906753834651127/OSBNode1 OSBDomain OSBCluster 18-DEC-12
Can anyone help me to investigate why the timer always triggers every 30 second instead of my intervalDuration value?
Below is the EJB ----->>
package com.timertest;
import java.util.*;
import javax.annotation.Resource;
import javax.ejb.*;
#Stateless(mappedName = "TimerTest")
public class TimerTest implements TimerTestRemote
{
#Resource
private SessionContext ctx;
#Override
public void createMyTimer()
throws EJBException
{
ctx.getTimerService().createTimer(1000, 20000, null);
}
#Timeout
public void timeout(Timer timer)
{
System.out.println("-> Timed Out ..."+ new Date());
}
}
Below is the and weblogic descripor-------->>
<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-ejb-jar
xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-ejb-jar"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd http://xmlns.oracle.com/weblogic/weblogic-ejb-jar http://xmlns.oracle.com/weblogic/weblogic-ejb-jar/1.2/weblogic-ejb-jar.xsd">
<wls:weblogic-enterprise-bean>
<wls:ejb-name>TimerTest</wls:ejb-name>
<wls:stateless-session-descriptor>
<wls:stateless-clustering>
<wls:home-is-clusterable>true</wls:home-is-clusterable>
<wls:home-load-algorithm>round-robin</wls:home-load-algorithm>
<wls:stateless-bean-is-clusterable>true</wls:stateless-bean-is-clusterable>
<wls:stateless-bean-load-algorithm>round-robin
</wls:stateless-bean-load-algorithm>
</wls:stateless-clustering>
<wls:business-interface-jndi-name-map>
<wls:business-remote>TimerTestRemote</wls:business-remote>
<wls:jndi-name>TimerTest</wls:jndi-name>
</wls:business-interface-jndi-name-map>
</wls:stateless-session-descriptor>
<wls:enable-call-by-reference>false</wls:enable-call-by-reference>
<wls:jndi-name>TimerTest</wls:jndi-name>
</wls:weblogic-enterprise-bean>
<wls:timer-implementation>Clustered</wls:timer-implementation>
</wls:weblogic-ejb-jar>
Thanks in advance
This might not be the direct answer, but might help to avoid such condition.
Timers are persistent by default, so you have to cancel the previous timers before starting new ones.
Also, you can provide info while creating timer object instead of passing null, may be string identifier. It will later help to identify which timer had timed out or to cancel it in case of multiple timers in the system.
Creating timers & restarting the application multiple times, there are several such timers having same info, but are having different hashCode. So they don't overlap & are created new each time.
You can get timers by ctx.getTimerService().getTimers() & cancel by iterating over them.
Edit : I have replicated the scenario & have faced similar issue. I have debugged & it happens when there are multiple previous timers active for the same interval, which aren't being cancelled.
You try below code, I have tried & it resolved the issue.
for(Timer t : timerService.getTimers())
t.cancel(); //-- Cancel timers before creatimng new one
ctx.getTimerService().createTimer(1000, 20000, null);
Excerpt from documentation :
intervalDuration - If expiration is delayed (e.g. due to the interleaving of other method calls on the bean), two or more expiration notifications may occur in close succession to "catch up".
You can use a different style (annotations). See below:
#Schedule(hour = "*", minute = "*",second = "*/40")
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
#Lock(LockType.WRITE)
#AccessTimeout(1000 * 60 * 60)//1 Hour...//Concurrent Access is not permitted...

Resources