The job referenced

2020-06-17 09:31发布

问题:

I'm having some trouble successfully scheduling a job without getting the error mentioned in the title, specifically: The job (CRAWLS.my_repos) referenced by the trigger does not exist. [See nested exception: org.quartz.JobPersistenceException: The job (CRAWLS.my_repos) referenced by the trigger does not exist.]

Here's a look at the code...of which, everything seems like it should be okay.

The runJob method...the main thing to notice is that it's failing in this line: m_scheduler.scheduleJob(trigger); The rest of the method is there in case the rest of it would be useful.

public void runJob(JobInfo jobInfo, 
        com.lawson.search.spi.common.Properties jobProperties)
{
    try {
        JobDataMap jobDataMap = QuartzUtils.createJobDataMapFromLesProperties(jobProperties);
        if (jobExists(jobInfo)) {
            m_scheduler.triggerJob(jobKey(jobInfo.getName(), jobInfo.getGroup()), jobDataMap);
        } else {
            JobDetail job = QuartzUtils.createJobDetailFromJobInfo(jobInfo);
            Trigger trigger = newTrigger()
                .forJob(job)
                .withIdentity(getImmediateTriggerName(jobInfo))
                .build();
            m_scheduler.scheduleJob(trigger);
        }
    } catch (SchedulerException e) {
        String msg = "runJob: " + jobInfo;
        if (s_log.isDebugEnabled()) {
            s_log.debug(msg, e);
        }
        throw new JobSchedulerException(msg, e);
    }
}

The createJobDetailFromJobInfo() method is simple, but important:

static JobDetail createJobDetailFromJobInfo(JobInfo theJobInfo)
{
  JobDetail detail = newJob(QuartzJobAdapter.class)
    .withIdentity(theJobInfo.getName(), theJobInfo.getGroup())
    .storeDurably()
    .build();
  return detail;
}

The only other important method that I can think of would be the getImmediateTriggerName() method which I think may be causing an issue...but I don't know why.

private String getImmediateTriggerName(JobInfo jobInfo)
{
    return jobInfo.getName() + "#" + jobInfo.getGroup() + ":" + System.currentTimeMillis();
}

Any help would be appreciated.

回答1:

Try scheduling a job with

// Schedule the job with the trigger 
m_scheduler.scheduleJob(job, trigger);

instead of

m_scheduler.scheduleJob(trigger);

From quartz-scheduler.org :

How-To: Scheduling a Job in 2.1.x and How-To: Scheduling a Job in 2.2.x

The code is the same for two versions

// Define job instance
JobDetail job1 = newJob(ColorJob.class)
    .withIdentity("job1", "group1")
    .build();

// Define a Trigger that will fire "now", and not repeat
Trigger trigger = newTrigger()
    .withIdentity("trigger1", "group1")
    .startNow()
    .build();

// Schedule the job with the trigger 
sched.scheduleJob(job, trigger);

Anyway, the exception is thrown only if quartz can not retrieve a JobDetail for the trigger's jobkey during the trigger store at storeTrigger method

if (retrieveJob(newTrigger.getJobKey()) == null) {
    throw new JobPersistenceException("The job ("
            + newTrigger.getJobKey()
            + ") referenced by the trigger does not exist.");
}

// add to triggers array
triggers.add(tw);

....

public JobDetail retrieveJob(JobKey jobKey) {
    synchronized(lock) {
        JobWrapper jw = jobsByKey.get(jobKey);
        return (jw != null) ? (JobDetail)jw.jobDetail.clone() : null;
    }
}

so your error is very strange because the jobkey is assigned previously at forJob method in the TriggerBuilder class

public TriggerBuilder<T> forJob(JobDetail jobDetail) {
    JobKey k = jobDetail.getKey();
    if(k.getName() == null)
        throw new IllegalArgumentException("The given job has not yet had a name assigned to it.");
    this.jobKey = k;
    return this;
}

try scheduling the job with

m_scheduler.scheduleJob(job, trigger);

first as suggested before, if does not work you should debug your code and check the job keys, if your keys are right maybe the problem is not in your code and is a quartz configuration mismatch.



回答2:

When I got this error it was because I registered the job with myJobClass.getClass() but I had guice wrap an interceptor around the class so the class name missmatched (i.e the runtime class was ...$$EnhancerByGuice$$13db15). Something similar may happen with Spring.