触发器引用的作业不存在

问题描述 投票:0回答:2

我在成功安排作业时遇到了一些麻烦,但没有出现标题中提到的错误,具体来说:

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.]

看一下代码...其中,一切似乎都应该没问题。

runJob 方法...需要注意的主要事情是它在这一行中失败了:

m_scheduler.scheduleJob(trigger);
该方法的其余部分在那里,以防它的其余部分有用。

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);
    }
}

createJobDetailFromJobInfo()
方法很简单,但很重要:

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

我能想到的唯一其他重要方法是

getImmediateTriggerName()
方法,我认为它可能会导致问题......但我不知道为什么。

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

如有任何帮助,我们将不胜感激。

java quartz-scheduler
2个回答
15
投票

尝试使用

安排作业
// Schedule the job with the trigger 
m_scheduler.scheduleJob(job, trigger);

而不是

m_scheduler.scheduleJob(trigger);

来自 quartz-scheduler.org :

操作方法:在 2.1.x 中安排作业操作方法:在 2.2.x 中安排作业

两个版本的代码相同

// 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);

无论如何,只有在

JobDetail
方法
的触发器存储期间,quartz 无法检索触发器作业密钥的 
storeTrigger

时,才会引发异常
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;
    }
}

所以你的错误非常奇怪,因为作业密钥之前是在

forJob
类中的
TriggerBuilder
方法中分配的

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;
}

尝试用

安排作业
m_scheduler.scheduleJob(job, trigger);

首先按照之前的建议,如果不起作用,您应该调试代码并检查作业密钥,如果您的密钥正确,则问题可能不在您的代码中,而是石英配置不匹配。


2
投票

当我收到此错误时,这是因为我使用 myJobClass.getClass() 注册了作业,但我在类周围包装了一个拦截器,因此类名不匹配(即运行时类是...$$EnhancerByGuice$$13db15) 。 Spring 可能会发生类似的情况。

© www.soinside.com 2019 - 2024. All rights reserved.