Below is the code,
Trigger trigger = TriggerBuilder
.newTrigger().withIdentity(job.getTriggerName(), job.getGroupName())
.withSchedule(CronScheduleBuilder.cronSchedule(new CronExpression(cronExpression)).inTimeZone(TimeZone.getTimeZone(remoteTimezone)).withMisfireHandlingInstructionFireAndProceed())
.startAt(startDate)
.endAt(endDate)
.build();
Below are the logs,
[11-28 15:30:00,906] [pool-1-thread-1] [INFO:QuartzJob:99] job.getStartTimes() - 10:00,11:00,12:00
[11-28 15:30:00,908] [pool-1-thread-1] [INFO:QuartzJob:105] dateValue - Sat Nov 28 15:30:00 IST 2020
[11-28 15:30:00,909] [pool-1-thread-1] [INFO:QuartzJob:105] dateValue - Sat Nov 28 16:30:00 IST 2020
[11-28 15:30:00,910] [pool-1-thread-1] [INFO:QuartzJob:105] dateValue - Sat Nov 28 17:30:00 IST 2020
[11-28 15:30:00,913] [pool-1-thread-1] [INFO:QuartzJob:130] mins --- 30
[11-28 15:30:00,913] [pool-1-thread-1] [INFO:QuartzJob:131] hours --- 15,16,17
[11-28 15:30:00,913] [pool-1-thread-1] [INFO:QuartzJob:132] Timezone startDate --- Sat Nov 28 15:30:00 IST 2020
[11-28 15:30:00,913] [pool-1-thread-1] [INFO:QuartzJob:133] Timezone endDate --- Sat Nov 28 17:30:00 IST 2020
[11-28 15:30:00,913] [pool-1-thread-1] [INFO:QuartzJob:137] Generated cronExpression for the Job is - 0 30 15,16,17 * * ?
Job start times values are in GMT which are converted to IST and Cron Expression is made.
But Getting the below error,
[11-28 15:30:00,936] [pool-1-thread-1] [ERROR:JobExecutor:71] org.quartz.SchedulerException: Based on configured schedule, the given trigger '2020-11-28-DUMMY_JOB_TEST-Jobs.2020-11-28-DUMMY_JOB_TEST-Trigger' will never fire.
Dont understand why this is happening ?
with .startNow() also getting the same Error.
Any help would be highly appreciated.
It seems your start and dates are the same:
Timezone startDate --- Sat Nov 28 15:30:00 IST 2020 Timezone endDate --- Sat Nov 28 17:30:00 IST 2020
they differ only in a few hours, but the quartz scheduler works in a way that the end date must be at least one day after the start date.
You may try testing by removing .endAt(endDate), it should work.
Related
Here is the documentation for the Spring Crontab syntax.
I want to run a task every weekday at 14:40, 14:45, 14:50, 14:55, and 15:00, but I can't figure out how to express this with a Crontab pattern. The closest I've come up with so far is:
0 40/5 14 * * MON-FRI
But this doesn't run at 15:00.
Is this possible to express with a Crontab pattern at all?
You need to split it into two expressions :
0 40-55/5 14 * * MON-FRI
0 0 15 * * MON-FRI
If you only want to have one expression and you are okay with the last trigger time in a day run one minute before, you can use :
0 40-55/5,59 14 * * MON-FRI
Spring internally use CronSequenceGenerator to generate the next trigger time for a cron expression. You can use it to verify a cron expression.
For example , to verify the next several trigger times of 0 40-55/5,59 14 * * MON-FRI:
CronSequenceGenerator generator = new CronSequenceGenerator("0 40-55/5,59 14 * * MON-FRI");
Date d = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());
for (int i = 0; i < 10; i++) {
d = generator.next(d);
System.out.println(d);
}
which will print out :
Tue Jun 02 14:40:00 HKT 2020
Tue Jun 02 14:45:00 HKT 2020
Tue Jun 02 14:50:00 HKT 2020
Tue Jun 02 14:55:00 HKT 2020
Tue Jun 02 14:59:00 HKT 2020
Wed Jun 03 14:40:00 HKT 2020
Wed Jun 03 14:45:00 HKT 2020
Wed Jun 03 14:50:00 HKT 2020
Wed Jun 03 14:55:00 HKT 2020
Wed Jun 03 14:59:00 HKT 2020
Initially I had quite simple test:
#Test
public void testMe() {
System.out.println("Records in H2 db:");
List<DateRangeBean> all = dateRangeServiceImpl.findAll();
all.forEach(x -> System.out.println(x.getDateTo()));
Clock.system(ZoneId.of("UTC"));
ZonedDateTime currentDate = ZonedDateTime.of(2016, 8, 9, 0, 0, 0, 0, clock.getZone());
Date currentDate_date = Date.from(currentDate.toInstant());
System.out.println("Current Date is: " + currentDate_date);
List<DateRangeBean> result = new ArrayList<>();
dateRangeServiceImpl.findGreaterDateTo(currentDate_date).iterator().forEachRemaining(result::add);
result.forEach(x -> System.out.println(x.getDateTo()));
assertEquals(result.size(), 2);
}
that always was executed on PC with default TimeZone UTC and with the following output:
Records in H2 db:
Mon Aug 08 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
Current Date is: Tue Aug 09 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
where:
dateRangeServiceImpl.findAll() implemented as:
public List<DateRangeBean> findAll (){
List<DateRangeBean> result = new ArrayList<>();
dateRangeRepository.findAll().iterator().forEachRemaining(result::add);
return result;
}
dateRangeServiceImpl.findGreatedDateTo(Date date):
public List<DateRangeBean> test (Date currentDate){
List<DateRangeBean> result = new ArrayList<>();
dateRangeRepository.findGreatedDateTo(currentDate).iterator().forEachRemaining(result::add);
return result;
}
and dateRangeRepository - is pure interface as part of Spring Data
public interface DateRangeRepository extends PagingAndSortingRepository<DateRangeBean, Long> {
#Query("from DateRangeBean drb where (drb.dateTo >= :currentDate)")
List<DateRangeBean> findGreatedDateTo(#Param("currentDate") Date currentDate);
}
and DateRangeBean:
#Entity
public class DateRangeBean implements java.io.Serializable {
#Temporal(TemporalType.DATE)
#Column(name = "date_To", length = 10)
private Date dateTo;
.....................
public Date getDateTo() {
return new Date(this.dateTo.getTime());
}
public void setDateTo(Date dateTo) {
this.dateTo = new Date(dateTo.getTime());
}
}
Today I have tried to run this test on PC with Time Zone: UTC -07:00 and test failed with the following output:
Records in H2 db:
Mon Aug 08 00:00:00 MST 2016
Thu Oct 20 00:00:00 MST 2016
Thu Oct 20 00:00:00 MST 2016
Current Date is: Mon Aug 08 17:00:00 MST 2016
Mon Aug 08 00:00:00 MST 2016
Thu Oct 20 00:00:00 MST 2016
Thu Oct 20 00:00:00 MST 2016
java.lang.AssertionError: expected [2] but found [3]
Expected :2
Actual :3
Okey, maybe, it is reasonable: we defined currentDate variable Aug 9 UTC TZ, but on the next step we re-converted currentDate to currentDate_date in MST TZ and as result it is Aug 8.
BUT:
Q1:
based on our #Query: drb.DateTo >= :currentDate
in current case: Mon Aug 08 00:00:00 MST 2016 >= Mon Aug 08 17:00:00 MST 2016 - this statement is incorrect!
Assume, that Spring Data compares only Day, Month, Year and trims Time segment.
Is it correct??
Q2:
I tried to fix the test putting the timezone directly in the test:
public void testMe() {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
..............
}
But I still getting failed result:
Records in H2 db:
Mon Aug 08 07:00:00 UTC 2016
Thu Oct 20 07:00:00 UTC 2016
Thu Oct 20 07:00:00 UTC 2016
Current Date is: Tue Aug 09 00:00:00 UTC 2016
Mon Aug 08 07:00:00 UTC 2016
Thu Oct 20 07:00:00 UTC 2016
Thu Oct 20 07:00:00 UTC 2016
java.lang.AssertionError: expected [2] but found [3]
And at the moment I can't understand how is it possible:
Mon Aug 08 07:00:00 UTC 2016 >= Tue Aug 09 00:00:00 UTC 2016 ?
Q3:
I tried to specify TZ as part of Spring Context:
<bean id="defaultZoneInfo" class="sun.util.calendar.ZoneInfo" factory-method="getTimeZone">
<constructor-arg type="java.lang.String" value="UTC"/>
</bean>
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod" value="java.util.TimeZone.setDefault"/>
<property name="arguments">
<list>
<ref bean="defaultZoneInfo"/>
</list>
</property>
</bean>
but the result was the same as with Q2.
Q4:
Specify TZ in static block:
static {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
}
and test - passed!
Records in H2 db:
Mon Aug 08 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
Current Date is: Tue Aug 09 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
So, can someone explain why specifying default TZ in Spring Context xml file and directly in test method didn't fix problem?
And only specifying TZ via static block solved the problem?
I think it may be your database problem not your application
for example Oracle database not accept connection from client after changing Client location in control panel.
I am working on project using GWT java GAE. In my project i have used cron job.
when i schedule its time like every 5 minutes, every 2 minutes in cron.xml then its working fine i will getting my ouput. but when i schedule it time like every 24 hours or every day 21:00 then cron job executed but its throw error :-
E 2015-11-03 20:18:10.825
com.slicktechnologies.server.cronjobimpl.ContractRenewalCronJobImpl ContractRenewallist: Date Before Adding Day03-Nov-2015
E 2015-11-03 20:18:10.832
com.slicktechnologies.server.cronjobimpl.ContractRenewalCronJobImpl ContractRenewallist: Today Date -30 Days DateSat Oct 03 23:59:59 UTC 2015
E 2015-11-03 20:18:10.832
com.slicktechnologies.server.cronjobimpl.ContractRenewalCronJobImpl ContractRenewallist: Today DateMon Nov 02 18:30:00 UTC 2015
E 2015-11-03 20:18:10.832
com.slicktechnologies.server.cronjobimpl.ContractRenewalCronJobImpl ContractRenewallist: Date After Setting the Time Mon Nov 02 23:59:59 UTC 2015
E 2015-11-03 20:18:10.833
com.slicktechnologies.server.cronjobimpl.ContractRenewalCronJobImpl ContractRenewallist: Date Before Adding Day03-Nov-2015
E 2015-11-03 20:18:10.833
com.slicktechnologies.server.cronjobimpl.ContractRenewalCronJobImpl ContractRenewallist: Today Date +30 Days DateWed Dec 02 18:30:00 UTC 2015
E 2015-11-03 20:18:10.833
com.slicktechnologies.server.cronjobimpl.ContractRenewalCronJobImpl ContractRenewallist: Date Before Adding One DayMon Nov 02 18:30:00 UTC 2015
E 2015-11-03 20:18:10.833
com.slicktechnologies.server.cronjobimpl.ContractRenewalCronJobImpl ContractRenewallist: Today Date +30 Days DateThu Dec 03 18:29:29 UTC 2015
E 2015-11-03 20:18:10.833
com.slicktechnologies.server.cronjobimpl.ContractRenewalCronJobImpl ContractRenewallist: In Contract List
E 2015-11-03 20:18:10.833
com.slicktechnologies.server.cronjobimpl.ContractRenewalCronJobImpl ContractRenewallist: Date After Adding One DateMon Nov 02 23:59:59 UTC 2015
I 2015-11-03 20:18:11.146
This request caused a new process to be started for your application, and thus caused your application code to be loaded for the first time. This request may thus take longer and use more CPU than a typical request for your application.
Any help
Thanks in advance
The message about starting a new instance is not an error, it's just an informational message, expected when app instances are dynamically created (note the i marking):
GAE automatically stops dynamic instances after a period of inactivity (of at least 15 minutes) and start new instances on demand. Your app instance is not idle long enough when the job is scheduled every 2 or 5 minutes because of the cron job itself, but it may be when running the job daily.
More details in here.
You can see the message even when running the job every 2 or 5 minutes if, for example, you stop your instance manually.
After a lot of debugging I narrowed my problem to the following snippet:
public static void calendarBug() {
for (int i=0 ; i<6 ; i++) {
Calendar c = Calendar.getInstance();
c.clear();
c.set(2015, 2, 27, i, 0);
System.out.println(c.getTime());
}
}
Running this gives the following output:
Fri Mar 27 00:00:00 IST 2015
Fri Mar 27 01:00:00 IST 2015
Fri Mar 27 03:00:00 IDT 2015
Fri Mar 27 03:00:00 IDT 2015
Fri Mar 27 04:00:00 IDT 2015
Fri Mar 27 05:00:00 IDT 2015
Does anyone know why does c.set(2015,2,27,2,0) returns 3AM instead of 2AM?
Think about that your are at time just at DST time, It moves forward one hour or moves back one hour without living this time portion.
So It is not bug, it is feature.
When you change the timezone which does not use DST (lets say Canada/East-Saskatchewan), you will see what you have expected.
Here is an example.
public static void calendarBug() {
for (int i=0 ; i<6 ; i++) {
Calendar c = Calendar.getInstance();
c.setTimeZone(TimeZone.getTimeZone("Canada/East-Saskatchewan"));
c.clear();
c.set(2015, 2, 27, i, 0);
System.out.println(c.getTime());
}
}
Fri Mar 27 08:00:00 EET 2015
Fri Mar 27 09:00:00 EET 2015
Fri Mar 27 10:00:00 EET 2015
Fri Mar 27 11:00:00 EET 2015
Fri Mar 27 12:00:00 EET 2015
Fri Mar 27 13:00:00 EET 2015
That is most likely a DST switchover for your timezone.
Mar 27 is the last Friday of March in 2015. This is the day when the DST switchover takes place in the Israel, Jordan, Syria, the West Bank etc.
See
Daylight Savings Time
Daylight Savings Time by Country
Daylight Saving Time Dates - 2014/2015
The problem is that the subtraction of the two dates leaves me double identical value.
From : Thu Nov 29 00:00:00 CET 2012
Value 121: To: Sat Mar 30 00:00:00 CET 2013
Value 122: To: Sun Mar 31 00:00:00 CET 2013
Value 122: To: Mon Apr 01 00:00:00 CEST 2013
Value 123: To: Tue Apr 02 00:00:00 CEST 2013
Long today = (To.getTime() - From.getTime()) / (1000 * 60 * 60 * 24);
Is it possible to somehow avoid that logically? (sorry for English)