quartz-scheduler / quartz Goto Github PK
View Code? Open in Web Editor NEWCode for Quartz Scheduler
Home Page: http://www.quartz-scheduler.org
License: Apache License 2.0
Code for Quartz Scheduler
Home Page: http://www.quartz-scheduler.org
License: Apache License 2.0
CREATE TABLE QRTZ_FIRED_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR(95) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
FIRED_TIME BIGINT(13) NOT NULL,
SCHED_TIME BIGINT(13) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16) NOT NULL,
JOB_NAME VARCHAR(200) NULL,
JOB_GROUP VARCHAR(200) NULL,
IS_NONCONCURRENT VARCHAR(1) NULL,
REQUESTS_RECOVERY VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID))
TYENGINEPE=InnoDB;
change to
CREATE TABLE QRTZ_FIRED_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR(95) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
FIRED_TIME BIGINT(13) NOT NULL,
SCHED_TIME BIGINT(13) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16) NOT NULL,
JOB_NAME VARCHAR(200) NULL,
JOB_GROUP VARCHAR(200) NULL,
IS_NONCONCURRENT VARCHAR(1) NULL,
REQUESTS_RECOVERY VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID))
ENGINE=InnoDB;
InnoDB has a maximum size of 767 bytes on a single column index. When using a VARCHAR(200)
as one of the columns in a multicolumn primary key, this limit still is in force.
When the character encoding is set to UTF8mb4
, the VARCHAR(200)
data type required 800 bytes, which is greater than the allowed 767 by InnoDB.
This should be easy to fix by reducing the VARCHAR(200)
columns to VARCHAR(190)
columns, which will fit inside the 767 byte limit with any encoding that uses 4 bytes or less.
For limitations on InnoDB, see http://dev.mysql.com/doc/refman/5.6/en/innodb-restrictions.html
Hi,
Sorry I am not an OSGI export, hoping someone could check this out and validate this issue.
I'm unable to use quartz inside an OSGI bundle with Felix (even with the following decalared optional). The import "commonj.work" appears to be incorrect. I am not sure what this java package is, but I also suspect that other OSGI containers might still work with the optional declaration, just not in my case.
So should this import actually be in the MANIFEST.MF ?.
https://github.com/quartz-scheduler/quartz/blob/master/quartz/pom.xml#L232
Cheers.
In Quartz 2.2.3, if I call
scheduler.pauseTriggers(GroupMatcher.triggerGroupEquals("abc"));
on a scheduler without triggers, then follow it with a
scheduler.resumeTriggers(GroupMatcher.triggerGroupEquals("abc"));
the paused group "abc" is not removed from the list of paused groups in the scheduler, so that any subsequent Trigger that is added will be in paused state.
I don't know if this is the expected behavior, but it goes against logic.
You can see the problem in RAMJobStore.resumeTriggers():
Set<String> groups = new HashSet<String>();
synchronized (lock) {
Set<TriggerKey> keys = getTriggerKeys(matcher);
for (TriggerKey triggerKey: keys) {
groups.add(triggerKey.getGroup());
if(triggersByKey.get(triggerKey) != null) {
String jobGroup = triggersByKey.get(triggerKey).jobKey.getGroup();
if(pausedJobGroups.contains(jobGroup)) {
continue;
}
}
resumeTrigger(triggerKey);
}
for (String group : groups) {
pausedTriggerGroups.remove(group);
}
}
As you can see, pausedTriggerGroups.remove(group) is called only if getTriggerKeys(matcher) returns some elements, which doesn't happen when there are no triggers.
On a machine without SVN installed project build fails with the following error:
[ERROR] Failed to execute goal org.terracotta:maven-forge-plugin:1.1.9:manifest (create-manifest) on project quartz: Execution create-manifest of goal org.terracotta:maven-forge-plugin:1.1.9:manifest failed: Execute failed: java.io.IOException: Cannot run program "svn": error=2, No such file or directory -> [Help 1]
IMO the build should not depend on SVN since the project has moved to Github.
Spend over 5s to delete job in the cases of high concurrent.
on http://www.quartz-scheduler.org/documentation/quartz-2.2.x/examples/Example6.html
BadJob1 Example called
e2.refireImmediately();
it should be
e2.setRefireImmediately(true);
http://www.quartz-scheduler.org/documentation/quartz-2.x/cookbook/UpdateTrigger.html
typo issue found for :
Trigger newTrigger = tb.withSchedule(simpleSchedule()
.withIntervalInSeconds(10)
.withRepeatCount(10)
.build();
missing right parenthesis after withRepeatCount
should be
Trigger newTrigger = tb.withSchedule(simpleSchedule()
.withIntervalInSeconds(10)
.withRepeatCount(10))
.build();
Hi, i define two triggers, they fire on the same time, i set every seconds.
of course, set org.quartz.threadPool.threadCount = 1
so one job cannot fire, because one thread at one time cannot execute two job, and i read quartz document, I find:
http://www.quartz-scheduler.org/documentation/quartz-2.2.x/examples/Example5.html
withMisfireHandlingInstructionNowWithExistingCount()) // set misfire instruction
but it not work, still only one job execute, other one job cannot execute.
import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
public class SimpleTriggerExample {
public static void main(String[] args) throws Exception {
try {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();
System.out.println("----------1");
// define the job and tie it to our HelloJob class
JobDetail job = newJob(SimpleJob.class).withIdentity("job1",
"group1").build();
System.out.println("----------2");
Trigger trigger = newTrigger()
.withIdentity("trigger1", "group1")
.startNow()
.withSchedule(
simpleSchedule().withIntervalInSeconds(2)
.repeatForever()).build();
System.out.println("----------3");
scheduler.scheduleJob(job, trigger);
System.out.println("----------4");
} catch (SchedulerException se) {
se.printStackTrace();
}
}
class SimpleJob implements Job {
@Override
public void execute(JobExecutionContext context)
throws JobExecutionException {
String jobName = context.getJobDetail().getKey().getName();
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy 年 MM 月 dd 日 HH 时 mm 分 ss 秒");
String jobRunTime = dateFormat.format(new Date());
System.out.println( jobName + " " + jobRunTime);
}
}
}
[org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin.processFile(XMLSchedulingDataProcessorPlugin.java:322)] Error scheduling jobs: Job class must implement the Job interface.
java.lang.IllegalArgumentException: Job class must implement the Job interface.
at org.quartz.JobDetail.setJobClass(JobDetail.java:291)
at org.quartz.JobDetail.(JobDetail.java:156)
at org.quartz.xml.XMLSchedulingDataProcessor.process(XMLSchedulingDataProcessor.java:655)
at org.quartz.xml.XMLSchedulingDataProcessor.processFile(XMLSchedulingDataProcessor.java:501)
at org.quartz.xml.XMLSchedulingDataProcessor.processFileAndScheduleJobs(XMLSchedulingDataProcessor.java:841)
at org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin.processFile(XMLSchedulingDataProcessorPlugin.java:317)
at org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin.start(XMLSchedulingDataProcessorPlugin.java:245)
at org.quartz.plugins.SchedulerPluginWithUserTransactionSupport.start(SchedulerPluginWithUserTransactionSupport.java:144)
at org.quartz.core.QuartzScheduler.startPlugins(QuartzScheduler.java:2341)
at org.quartz.core.QuartzScheduler.start(QuartzScheduler.java:514)
at org.quartz.impl.StdScheduler.start(StdScheduler.java:143)
at org.quartz.ee.servlet.QuartzInitializerServlet.init(QuartzInitializerServlet.java:184)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1282)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1195)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1085)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5318)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5610)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:899)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:875)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1259)
at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1998)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
here is my properties:
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 4
org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
org.quartz.plugin.jobInitializer.fileNames = quartz_jobs.xml
quartztest
quartzGroup
this is HelloWorld......
test.Quartztest
quartztrigger
quartztest
quartzGroup
0/10 * * * * ?
src/test/Quartztest.java
my pro environment :
jdk 1.7
quartz 1.8.6
quartz all 1.8.6
and some anthor jar file
when this in the new web project it working normally , but when i put it in my project ,it take the problem,
Any help will be greatly appreciate
org.quartz.JobPersistenceException: Couldn't remove job: Deadlock found when trying to get lock; try restarting transaction
[See nested exception: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction]
I deploy a cluster with 2 nodes, would it because i did'n set the acquireTriggersWithinLock property?
Hello everyone, I based on quartz encapsulates a distributed task scheduling platform, called "XXL-JOB"。
The purpose is to contribute to open source, welcome you all to use。
大家好,我基于quartz封装了一个分布式任务调度平台,叫做 “XXL-JOB” 。
目的是为开源做贡献,欢迎大家使用啊。
https://github.com/xuxueli/xxl-job
can quartz support getScheduledFireTime of the original time.
I am using jdbc job store and have problem with getScheduledFireTime.
Currently I am using workaround with setting misfireThreshold to be very large so that misfire is not handled (or handle like ram job store).
The scenario is described as below
Hello, quartz support or not support the sqlite database?
Moving from https://jira.terracotta.org/jira/browse/CDV-1673
Error -
2016-08-01 10:29:58 DEBUG JobStoreTX:3949 - MisfireHandler: scanning for misfires...
2016-08-01 10:29:58 DEBUG JobStoreTX:3198 - Found 0 triggers that missed their scheduled fire-time.
<Aug 1, 2016 10:30:00 AM IST> <oracle.dfw.incident> <incident 178 created with problem key "DFW-99998 [java.lang.ClassNotFoundException][weblogic.utils.classloaders.ChangeAwareClassLoader.loadClass][EmpEngApp]">
<Aug 1, 2016 10:30:00 AM IST> <oracle.odl.management.logquery> <unexpected exception: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Double
Please note this doesn't occur always but only sometimes. So can't understand where I am going wrong.Any help will be appreciated.
RelevantFiles.zip
I used CronScheduleBuilder Class setting Scheduling time
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroupName) .withSchedule(CronScheduleBuilder.cronSchedule("* 0/1 * * * ?")) .startNow().build();
I just want to according to the current time run once a minute, again and again I delete the schedule according to the current time waiting for a minute, but I didn't find similar functionality in the document
Thanks!
https://jira.terracotta.org/jira/plugins/servlet/project-config/QTZ/summary - contains the original issue information. Copied here
An incorrect start time is set on a Cron Trigger when the provided start time is on the date when DST ends (for the time zone where Quartz is running) and the hour is equal to 1 hour before the DST end hour, and the time zone set on the trigger is different than the time zone where Quartz is running.
If such a scenario is encountered, the trigger start time is ultimately set to 1 hour later than the desired start time.
An example will make this much clearer:
Let's say I want to create a cron trigger with a start date of 10pm on November 1, 2014, with a time zone of "America/Los_Angeles". And Quartz is running on a server in time zone "America/New_York". 10pm in Los Angeles is equivalent to November 2 at 1am EDT (the first Sunday in November when DST will end at 2am for New York). This will ultimately create a cron trigger that has a start time of 11pm on November 1, 2014 in time zone "America/Los_Angeles" (instead of the desired 10pm that was originally specified).
This issue occurs because a time zone is NOT specified while creating a Calendar instance when setting the start time on the cron trigger. Specifically: within class CronTriggerImpl.java, method setStartTime, line 393.
Because the time zone is not used, it is assumed that the time is in New York time zone (which would then be 1am EDT). After executing the line of code to clear the milliseconds, the Calendar instance no longer returns 1am EDT, but instead returns 1am EST. And now, when the date is translated back into Los Angeles time, the value is incorrect.
We were testing an upgrade of quartz in another product and we started off with a DB dump of the live data, then we ran the migrations to upgrade it to the schema required by quartz 2.2.2 and then when attempting to startup the application (and quartz) we would hit a NullPointerException:
2016-07-13 13:19:33,978 [QuartzScheduler_QuartzSchedulerThread] ERROR org.quartz.core.ErrorLogger - An error occurred while scanning for the next triggers to fire.
org.quartz.JobPersistenceException: Couldn't acquire next trigger: null [See nested exception: java.lang.NullPointerException]
at org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTrigger(JobStoreSupport.java:2860)
at org.quartz.impl.jdbcjobstore.JobStoreSupport$40.execute(JobStoreSupport.java:2759)
at org.quartz.impl.jdbcjobstore.JobStoreSupport$40.execute(JobStoreSupport.java:2757)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3799)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTriggers(JobStoreSupport.java:2756)
at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:272)
Caused by: java.lang.NullPointerException
at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.insertFiredTrigger(StdJDBCDelegate.java:2651)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTrigger(JobStoreSupport.java:2844)
... 5 more
This looks to be because we had a RECOVERING_JOBS trigger in the database from the dump and these don't have a next fire time which acquireNextTrigger
method was expecting. By dropping this row from the DB quartz started up correctly, however it would be good if quartz was a little more robust.
Site: http://www.quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/tutorial-lesson-06.html
The site says :"Months can be specified as values between 0 and 11, or by using the strings JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC."
My test is : the value of month is between 1 and 12.
It looks like the PR#50 work of adding -Xdoclint:none only works for JDK8, but not JDK7 nor JDK6! We need to create a separate profile that detect JDK version for these flags.
I have a cron expression like 0 04 14 ? * FRI * and I have a Date. I want to check if that date matches this cron expression. In other words, I would like to know if a given cron expression will run a cronjob instantiated with this cron expression the given date/time (or was executed if the date/time is in the past).
I guess you already have that cron expression engine. Would be nice to make it public available.
quartz-terracotta-system-tests
Description Resource Path Location Type
Project build error: Non-resolvable parent POM for org.quartz-scheduler.internal:quartz-terracotta-system-tests:2.2.4-SNAPSHOT: Failure to find org.terracotta:system-tests-parent:pom:4.3.2-SNAPSHOT in http://www.terracotta.org/download/reflector/snapshots was cached in the local repository, resolution will not be reattempted until the update interval of terracotta-snapshots has elapsed or updates are forced and 'parent.relativePath' points at no local POM pom.xml /quartz-terracotta-system-tests line 11 Maven pom Loading Problem
Hi,
I guess you moved to github for the hosting.
The quartz-scheduler.org DNS record does not point to the site anymore and www.quartz-scheduler.org shows an invalid HTTPS certificate (github.com).
If I google I find the non www link as the first, which gives me a time out.
You may want to fix this (DNS and certificate :) ).
Greetings,
Vincent
give a reason,and can I not use uppercase?
I have a simple Trigger defined as a cron expression like "* 15 * ? * * *" that is meant to fire the job every hour at 15 minutes past the hour. This Job is created when my Spring Boot app starts up, using the JDBC Store for job storage.
Everything is created fine, and when the Trigger fires, the job fires every second for several minutes, and then eventually stops. There are no exceptions or errors, and the login within the job is simple and does what I expect.
I cannot figure out why the job is fired so many times. The Job is created with the following code:
`
try {
log.debug("Cron Expression: " + cron);
Scheduler scheduler = this.schedulerFactory.getScheduler();
JobKey key = JobKey.jobKey(PASSWORD_EXPIRE_JOBKEY);
final JobDetail job;
// Create or Update the job details.
if ( ! scheduler.checkExists(key) )
{
job = newJob(PasswordExpiredCheckJob.class)
.storeDurably()
.withIdentity(key)
.requestRecovery(false)
.build();
scheduler.addJob(job, true);
}
else {
job = scheduler.getJobDetail(key);
}
Trigger trigger = newTrigger()
.withIdentity(PASSWORD_EXPIRE_JOBKEY)
.withSchedule(cronScheduleNonvalidatedExpression(cron)
.withMisfireHandlingInstructionFireAndProceed())
.withDescription(cron)
.forJob(job)
.build();
// See if the job already exists.
if ( scheduler.checkExists(trigger.getKey()) )
{
if ( this.passwordExpireEmailEnabled )
{
// See if there is anything to update
Trigger current = scheduler.getTrigger(trigger.getKey());
log.debug("Existing Cron: " + current.getDescription());
if ( ! current.getDescription().equals(cron) )
{
// Update it with the current schedule info.
scheduler.rescheduleJob(trigger.getKey(), trigger);
}
}
else scheduler.deleteJob(key);
}
else {
if ( this.passwordExpireEmailEnabled )
scheduler.scheduleJob(trigger);
}
}
catch (SchedulerException | ParseException se)
{
log.error("Error creating Password Expiration Check", se);
throw new RuntimeException("Aborting Process", se);
}
`
We recently discovered a scenario where we had 20 perpetually misfired triggers in our Quartz scheduler. The jobs associated with these triggers were never being run, and it took a while to figure out why. It turns out there was an "invalid" misfired trigger that was "breaking" the misfire process. Specifically, a RECOVERING_JOBS trigger had a record in QRTZ_TRIGGERS with a TRIGGER_TYPE of 'SIMPLE', but there was not a record in QRTZ_SIMPLE_TRIGGERS for it. As a result, each time the MisfireHandler ran, it would error out with an exception on the first trigger and skip the remaining 19 triggers.
08/10/16 12:41:06 [QuartzScheduler_ClusterScheduler-1470857567998_MisfireHandler] INFO - Handling 20 trigger(s) that missed their scheduled fire-time.
08/10/16 12:41:06 [QuartzScheduler_ClusterScheduler-1470857567998_MisfireHandler] ERROR - MisfireHandler: Error handling misfires: Couldn't retrieve trigger: No record found for selection of Trigger with key: 'RECOVERING_JOBS.recover_X.X.X.X1415014951113_1415015028210' and statement: SELECT * FROM QRTZ_SIMPLE_TRIGGERS WHERE SCHED_NAME = 'ClusterScheduler' AND TRIGGER_NAME = ? AND TRIGGER_GROUP = ?
org.quartz.JobPersistenceException: Couldn't retrieve trigger: No record found for selection of Trigger with key: 'RECOVERING_JOBS.recover_X.X.X.X1415014951113_1415015028210' and statement: SELECT * FROM QRTZ_SIMPLE_TRIGGERS WHERE SCHED_NAME = 'ClusterScheduler' AND TRIGGER_NAME = ? AND TRIGGER_GROUP = ?
at org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveTrigger(JobStoreSupport.java:1533)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverMisfiredJobs(JobStoreSupport.java:979)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.doRecoverMisfires(JobStoreSupport.java:3199)
at org.quartz.impl.jdbcjobstore.JobStoreSupport$MisfireHandler.manage(JobStoreSupport.java:3947)
at org.quartz.impl.jdbcjobstore.JobStoreSupport$MisfireHandler.run(JobStoreSupport.java:3968)
Caused by: java.lang.IllegalStateException: No record found for selection of Trigger with key: 'RECOVERING_JOBS.recover_X.X.X.X1415014951113_1415015028210' and statement: SELECT * FROM QRTZ_SIMPLE_TRIGGERS WHERE SCHED_NAME = 'ClusterScheduler' AND TRIGGER_NAME = ? AND TRIGGER_GROUP = ?
at org.quartz.impl.jdbcjobstore.SimpleTriggerPersistenceDelegate.loadExtendedTriggerProperties(SimpleTriggerPersistenceDelegate.java:95)
at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.selectTrigger(StdJDBCDelegate.java:1819)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveTrigger(JobStoreSupport.java:1531)
... 4 common frames omitted
It would be nice if there was some additional error handling to prevent against this scenario so that in the event one trigger has an issue, it doesn't prevent the other misfired triggers from being handled properly.
Note: of course, the secondary issue here is why the RECOVERING_JOBS trigger got into that invalid state in the first place, but I figure making the MisfireHandler more robust is a good place to start that would have prevented this issue for us.
Perhaps utilizing clouldbees, so that it is more publicly visible.
I see we have committed some IDE (eg: .settings
dir files) related files in repo. We should clean this up. Most of IDE now a day should able to open the pom.xml file without further need of customization. If there is, it should be user specific and not need to be in repo.
The following command should display a list of what to remove.
git ls-files --ignored --exclude-from=.gitignore
Like titile.
Quartz 2.2.1
OracleDelegate
We have a number of triggers for a single job with the execution parameters stored in the JobDataMap. Once the trigger is created this data appears to be stored in the job_data column of triggers.
We do not change this data. We occasionally add and remove triggers but the data is static once the trigger is created.
The job is not marked with @PersistJobDataAfterExecution annotation.
Sporadically, for no obvious reason, the data in this column vanishes and the trigger will not fire and attempts to read the trigger information will fail.
Upon investigation it appears that the OracleDelegate is rewriting the data in this column always every time the trigger is accessed for scheduling of misfire handling. It rewrites by updating with an empty blob then updating with the data. It seems the first part of this is working but the resaving of the data is for some reason fails occasionally with the resulting problem of a zero length blob and missing JobDataMap.
First, since the job is not marked to persist after execution, it should not be trying to persist the data after execution. It also should not be persisting the data in any other handling.
Second, this writing of the JobDataMap appears to be controlled by the JobDataMap dirty flag. When the trigger is created the JobDataMap is serialized with the dirty flag set to true. When the trigger is retrieved the JobDataMap is retrieved with the flag true and the flag is never cleared until after the update of the blob occurs.
Setting false the dirty flag after retrieval of the JobDataMap, assuming that would have no other adverse consequences, might address this issue.
Hi Quartz communities,
Because of the maturity and stability of Quartz, our work flow system is using Quartz library. We can't use UTC directly, since many of our jobs have to depend on PDT/PST. I've read through the daylight saving part of Quartz documentation. However, Both CronTrigger and SimpleTrigger can not meet our requirement.
We are using CronTrigger, but 2:00-3:00 job will be missed when daylight saving changes, you know. Do you have any hacks to let jobs delay to run (no skip) at that day, if the job is a daily job.
The CronExpression class doesn't properly check the range of the value after '/' character.
The interval is only checked when the field starts with '/' as in the following case, which raises an Exception:
new org.quartz.CronExpression("0 /120 8-18 ? * 2-6")
However, if the first character of the field is numeric, the check is completely bypassed, as in the following example where the incorrect interval is accepted:
new org.quartz.CronExpression("0 0/120 8-18 ? * 2-6")
A quick look at the source would suggest to add a check in checkNext method of CronExpression.java similar to the check in storeExpressionVals (for the value following the '/' character).
Andrea
QuartzSchedulerMBeanImpl.addJob method invokes JobDetailSupport.newJobDetail to create a JobDetail instance before the job detail is registered with the scheduler. JobDetailSupport.newJobDetail uses Class.forName to load the job implementation class. This works only if the job implementation class can be loaded by the class loader that loaded the JobDetailSupport class and this is not always the case. For example, this is a very common Quartz deployment scenario:
App.ear
|
+--- lib
| |
| +--- quartz-x.y.z.jar
|
+--- App1.war
| |
| +--- WEB-INF/classes or WEB-INF/lib /* possibly contains Quartz job impl classes */
|
+--- EJBJar.jar /* possibly contains Quartz job impl classes */
In this scenario, when you attempt to add a new job through the QuartzSchedulerMBean API, it fails, because the Quartz class loader cannot see classes in WAR and EJB JAR modules.
Various Quartz components consistently use the ClassLoadHelper to load job implementation classes as well as other classes that may not reside on the Quartz scheduler's classpath. JobDetailSupport does not make use of the ClassLoadHelper. This severly limits the use of the Quartz MBean API to only one Quartz deployment scenario where Quartz API and job implementation classes are all loaded through the Quartz API class loader (or any of its parent class loaders).
I have implemented a fix for Quartz 2.2.1 and I am attaching the relevant patches for the modified classes in the picture below.
Please consider including the patch in Quartz 2.2.4. Thank you.
Thank you,
Jan
Seems to me like the comments on CompletedExecutionInstruction. SET_TRIGGER_ERROR and CompletedExecutionInstruction. SET_ALL_JOB_TRIGGERS_ERROR should be switched.
Am I missing anything?
Quartz Job fired twice in cluster mode,see the detail bug : https://jira.terracotta.org/jira/browse/QTZ-453
Setup:
Zemians-Air:quartz-test zemian$ mvn -version
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-10T11:41:47-05:00)
Maven home: /Users/zemian/apps/apache-maven-3.3.9
Java version: 1.8.0_60, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "10.11.6", arch: "x86_64", family: "mac"
Output:
Results :
Failed tests: testFired(org.terracotta.quartz.upgradability.serialization.CalendarIntervalTriggerImplSerializationTest): Unrecognized serialized form saved to /Users/zemian/javadev/zemian/quartz-test/quartz/CalendarIntervalTriggerImpl-2.ser
testConstructed(org.terracotta.quartz.upgradability.serialization.CalendarIntervalTriggerImplSerializationTest): Unrecognized serialized form saved to /Users/zemian/javadev/zemian/quartz-test/quartz/CalendarIntervalTriggerImpl-3.ser
testFired(org.terracotta.quartz.upgradability.serialization.CronTriggerImplSerializationTest): Unrecognized serialized form saved to /Users/zemian/javadev/zemian/quartz-test/quartz/CronTriggerImpl-2.ser
testConstructed(org.terracotta.quartz.upgradability.serialization.CronTriggerImplSerializationTest): Unrecognized serialized form saved to /Users/zemian/javadev/zemian/quartz-test/quartz/CronTriggerImpl-3.ser
testFired(org.terracotta.quartz.upgradability.serialization.DailyTimeIntervalTriggerImplSerializationTest): Unrecognized serialized form saved to /Users/zemian/javadev/zemian/quartz-test/quartz/DailyTimeIntervalTriggerImpl-2.ser
testConstructed(org.terracotta.quartz.upgradability.serialization.DailyTimeIntervalTriggerImplSerializationTest): Unrecognized serialized form saved to /Users/zemian/javadev/zemian/quartz-test/quartz/DailyTimeIntervalTriggerImpl-3.ser
testEmptyAllowTransientsMap(org.terracotta.quartz.upgradability.serialization.JobDataMapSerializationTest): Unrecognized serialized form saved to /Users/zemian/javadev/zemian/quartz-test/quartz/JobDataMap-2.ser
testEmptyMap(org.terracotta.quartz.upgradability.serialization.JobDataMapSerializationTest): Unrecognized serialized form saved to /Users/zemian/javadev/zemian/quartz-test/quartz/JobDataMap-3.ser
testFired(org.terracotta.quartz.upgradability.serialization.SimpleTriggerImplSerializationTest): Unrecognized serialized form saved to /Users/zemian/javadev/zemian/quartz-test/quartz/SimpleTriggerImpl-2.ser
testConstructed(org.terracotta.quartz.upgradability.serialization.SimpleTriggerImplSerializationTest): Unrecognized serialized form saved to /Users/zemian/javadev/zemian/quartz-test/quartz/SimpleTriggerImpl-3.ser
Tests run: 51, Failures: 10, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] quartz-checkstyle .................................. SUCCESS [ 1.336 s]
[INFO] quartz-parent ...................................... SUCCESS [ 0.076 s]
[INFO] quartz-core ........................................ SUCCESS [05:49 min]
[INFO] quartz-commonj ..................................... SUCCESS [ 1.114 s]
[INFO] quartz-jboss ....................................... SUCCESS [ 1.384 s]
[INFO] quartz-stubs ....................................... SUCCESS [ 0.886 s]
[INFO] quartz-oracle ...................................... SUCCESS [ 1.091 s]
[INFO] quartz-weblogic .................................... SUCCESS [ 0.904 s]
[INFO] quartz-jobs ........................................ SUCCESS [ 3.985 s]
[INFO] quartz-plugins ..................................... SUCCESS [ 2.853 s]
[INFO] quartz-terracotta-root ............................. SUCCESS [ 0.002 s]
[INFO] quartz-terracotta-bootstrap ........................ SUCCESS [ 1.731 s]
[INFO] quartz ............................................. FAILURE [ 4.666 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 06:09 min
[INFO] Finished at: 2016-10-11T22:35:21-04:00
[INFO] Final Memory: 21M/212M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test (default-test) on project quartz: There are test failures.
[ERROR]
[ERROR] Please refer to /Users/zemian/javadev/zemian/quartz-test/quartz/target/surefire-reports for the individual test results.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
[ERROR]
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR] mvn <goals> -rf :quartz
/**
* Whether or not the query and update to acquire a Trigger for firing
* should be performed after obtaining an explicit DB lock (to avoid
* possible race conditions on the trigger's db row). This is the
* behavior prior to Quartz 1.6.3, but is considered unnecessary for most
* databases (due to the nature of the SQL update that is performed),
* and therefore a superfluous performance hit.
*/
public boolean isAcquireTriggersWithinLock() {
return acquireTriggersWithinLock;
}
The property must be set for databases where simple SELECTs are never blocked (for ex. Oracle), it would be very helpful if this information was reflected somewhere in documentation.
It would be much more convenient for the users if DB schema scripts were included in org.quartz-scheduler:quartz
artifact rather than having to download the distribution archive and extract them from there.
This way the scripts would easily obtainable using the dependency management system of choice. In addition, this would also allow for a programmatic access to scripts since they would automatically be included in the classpath.
Many other popular frameworks take this approach, for example many Spring projects (Integration, Batch, Security...), Activiti BPMN, etc.
Using Your Own Listeners
...
For your convenience, tather than implementing those interfaces...
..
I'm running quartz on a cluster and I'm using spring to integrate with it.
There is a race condition going on when the cluster starts and it starts replacing the old stale jobs with the new ones.
One node will be initializing the scheduler and it will decide to replace the trigger (breakpoint org.quartz.impl.jdbcjobstore.SimpleTriggerPersistenceDelegate#deleteExtendedTriggerProperties )
Right after it executes this method, the trigger won't be in the database any longer so when another node in the cluster will try to read it (org.quartz.impl.jdbcjobstore.JobStoreSupport#retrieveTrigger) it will fail with the exception below. Because of this exception, the whole application will fail to start (not just the scheduler).
Caused by: org.quartz.JobPersistenceException: Couldn't retrieve trigger: No record found for selection of Trigger with key:
The logs can be found at https://github.com/apixandru/case-study/tree/master/spring-boot-quartz/logs (The exception can be found on the Server-1 node after the 4th restart)
For the whole project that demonstrates this issue go to https://github.com/apixandru/case-study/tree/master/spring-boot-quartz
To get the bug on any machine, start one server in debug mode and put a breakpoint on SimpleTriggerPersistenceDelegate.deleteExtendedTriggerProperties and just after it executes, start the second server and you will get this exception
The part of the spring code that causes this race condition just calls rescheduleJob, it can be found at
https://github.com/spring-projects/spring-framework/blob/v4.3.3.RELEASE/spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerAccessor.java#L302
Quartz scheduler is released under the Apache 2.0 license but has a dependency on c3p0 (0.9.1.1) which uses LGPL. In my understanding this is not allowed http://www.apache.org/legal/resolved.html#category-x
Newer versions of c3p0 declare a dual license LGPL/EPL which should be be fine to statically link against without violating the Apache license model.
When an JobPersistenceException is caught in the main QuartzSchedulerThread loop, the loop continues and immediately retries to read the triggers from the database. This leads to 120 to 1500 database connection attempts per second (!!). This leads to a flood of error log entries on our server.
Quartz should automatically throttle the retry attempts in case of database connection errors.
The first exception (and only one logged by Quartz directly) is
2015 10 10 18:58:06#+00#ERROR#org.quartz.core.ErrorLogger##anonymous#global_QuartzSchedulerThread#na#services#dispatcher#web##An error occurred while scanning for the next triggers to fire.
org.quartz.JobPersistenceException: Failed to obtain DB connection from data source 'DefaultDB': java.sql.SQLException: Could not retrieve datasource via JNDI url 'java:comp/env/jdbc/DefaultDB' <exception details from driver>. [See nested exception: java.sql.SQLException: Could not retrieve datasource via JNDI url 'java:comp/env/jdbc/DefaultDB' <exception details from driver>.]
at org.quartz.impl.jdbcjobstore.JobStoreSupport.getConnection(JobStoreSupport.java:778)
at org.quartz.impl.jdbcjobstore.JobStoreTX.getNonManagedTXConnection(JobStoreTX.java:71)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3784)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTriggers(JobStoreSupport.java:2756)
at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:272)
Caused by: java.sql.SQLException: Could not retrieve datasource via JNDI url 'java:comp/env/jdbc/DefaultDB' <exception details from driver>.
at org.quartz.utils.JNDIConnectionProvider.getConnection(JNDIConnectionProvider.java:163)
at org.quartz.utils.DBConnectionManager.getConnection(DBConnectionManager.java:108)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.getConnection(JobStoreSupport.java:775)
... 4 more|
This issue was originally reported and discussed here: https://jira.terracotta.org/jira/browse/QTZ-491
When I download the code and try to build with "mvn clean install -DskipTests", It always failed with error of javadoc plugin.
Seems this is because of java 8 javadoc xlint check is much more strict than previous. See blog.joda.org/2014/02/turning-off-doclint-in-jdk-8-javadoc.html.
I have a Quartz cluster that is updated via rolling update, and I want to schedule a new job in it. The problem with that is that I can't enforce that the new job is only executed on the already updated nodes, so an old node may pick it up, fail to instantiate the job and change the trigger to ERROR. This is unfortunate, because then the job will never automatically recover from this situation.
So, not set the trigger to ERROR when the job failed to instantiate?
hello,first ,thanks for quartz to help me to complete my time jobs.
But now ,i have some question about the Database table of the Quartz framework.
Because I want to knows the tables's columns meaning ,but is a pity,i can't find the related docs.
Could you can me,beautiful girls or handsome boys!!!! ^ o ^
hi,
quartz 2.2.3
I was debugging a intermittent problem where the JobDataMap was not updated at the point jobWasExecuted was fired.
here's the bug:
on line 224 of JobRunShell. job you notify the listeners the job was complete.
// notify all job listeners
if (!notifyJobListenersComplete(jec, jobExEx)) {
break;
}
then on line 269 you notify the job store that the job was complete.
qs.notifyJobStoreJobComplete(trigger, jobDetail, instCode);
the JobDataMap is only updated after notifyJobStoreJobComplete is called, so notifyJobListenersComplete should be called after notifyJobStoreJobComplete (after line 269)
Steps to to reproduce
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.