【问题标题】:Quartz Jobs Not Kicking Off石英工作没有开始
【发布时间】:2012-06-26 13:26:10
【问题描述】:

编辑:我正在使用quartz-2.1.5.jar。以下是我的课程摘要:

HttpPollingJob 扩展 PollingJob 扩展 ScheduledJob 实现 org.quartz.Job

具体来说:

1) ScheduledJob 实现 Quartz Job(我的所有 Job 类型的抽象基类):

import org.quartz.Job;
import org.quartz.Trigger;

public abstract class ScheduledJob implements Job {
    private Trigger trigger;

    public ScheduledJob() {
        this(null);
    }

    public ScheduledJob(Trigger trig) {
        super();

        if(trig == null)
            trig = getDefaultTrigger();

        setTrigger(trig);
    }

    public Trigger getTrigger() {
        return trigger;
    }

    public void setTrigger(final Trigger trig) {
        trigger = trig;
    }

    protected abstract Trigger getDefaultTrigger();
}

2) PollingJob 扩展 ScheduledJob - 所有“轮询器”以特定频率轮询某些资源/端点:

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;

import com.me.jobs.ScheduledJob;

public abstract class PollingJob extends ScheduledJob {
    private static long DEF_FREQUENCY = 10 * 1000; // 10 secs
    private String name;    
    private long frequency;

    public PollingJob(final String nm) {
        this(nm, DEF_FREQUENCY);
    }

    public PollingJob(final String nm, final long freq) {
        super();

        setName(nm);
        setFrequency(freq);
    }

    public abstract void poll(JobExecutionContext context);

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        poll(context);      
    }

    public String getName() {
        return name;
    }

    public void setName(final String nm) {
        name = nm;
    }

    public long getFrequency() {
        return frequency;
    }

    public void setFrequency(final long freq) {
        frequency = freq;
    }

    protected final Trigger getDefaultTrigger()  {
        TriggerBuilder<?> triggerBuilder = TriggerBuilder.newTrigger()
            .startNow()
            .withSchedule(SimpleScheduleBuilder.simpleSchedule()
            .withIntervalInMilliseconds(DEF_FREQUENCY));

        return triggerBuilder.build();
    }
}

3) HttpPollingJob 扩展 PollingJob - “HTTP pollers”轮询 Web 服务器(使用 HTtpClient):

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.quartz.JobExecutionContext;

import com.me.MonitoredEvent;
import com.me.MonitoredEventRegistrar;

public class HttpPollingJob extends PollingJob {
    private String serverURL;
    private org.slf4j.Logger logger =
        org.slf4j.LoggerFactory.getLogger(HttpPollingJob.class);

    public HttpPollingJob(final String nm, final String server) {
        super(nm);

        setServerURL(server);
    }

    public String getServerURL() {
        return serverURL;
    }

    public void setServerURL(final String server) {
        serverURL = server;
    }

    @Override
    public final void poll(JobExecutionContext context) {
        MonitoredEvent event = null;

        try {
            // This is where we would use HttpClient to connect to a web server and poll it.
            System.out.println("Job fired!");
        }
        catch(Throwable thrown) {
            logger.error(thrown.getMessage());
        }
    }
}

4) JobDriver - 定义了几个 HttpPollingJobs 并使用 Quartz 启动它们:

public class JobDriver {
    private List<HttpPollingJob> jobs;

    public JobDriver() {
        HttpPollingJob job1 = new HttpPollingJob("job-1", "http://www.example.com/1");
        HttpPollingJob job2 = new HttpPollingJob("job-2", "http://www.example.com/2");
        HttpPollingJob job3 = new HttpPollingJob("job-3", "http://www.example.com/3");

        jobs = new ArrayList<HttpPollingJob>();
        jobs.add(job1);
        jobs.add(job2);
        jobs.add(job3);
    }

    public static void main(String[] args) {
    JobDriver driver = new JobDriver();
        driver.startJobs();
    }

    private void startJobs() {
        try {
            // Obtain a basic SchedulerFactory and fire it up.
            SchedulerFactory schedulerFactory = new org.quartz.impl.StdSchedulerFactory();
            Scheduler scheduler = schedulerFactory.getScheduler();
            scheduler.start();

            // Define a job for every declared monitor.
            JobBuilder jobBuilder = null;

            for(ScheduledJob job : jobs) {

            Trigger trigger = job.getTrigger();
            jobBuilder = JobBuilder.newJob(job.getClass());

            // Bind the current job to this trigger.
            scheduler.scheduleJob(jobBuilder.build(), trigger);

            // TODO: Shut the scheduler down politely?!?!
        }
        catch(Throwable exc) {
            logger.error(exc.getMessage());

            // Force application to kick out.
            throw new RuntimeException(exc);
        }
    }
}

当我运行这段代码时,我得到了一个完美的启动,没有错误或运行时异常。如果我撒上System.out.println 语句,我可以看到每一行代码都完美执行。唯一的问题是,一旦程序运行,它不会打印指示轮询作业正在启动的“Jobfired!”消息。

我已经尝试了start()shutdown() 的所有组合我能想到的无济于事。任何 Quartz 专家都可以查看这段代码并告诉我为什么作业没有触发吗?

在日志中(我配置了 log4j),我看到正在为计划作业创建 Quartz 工作线程。我觉得我已经完成了 99% 的工作,但只是缺少一些明显的东西。提前致谢!

【问题讨论】:

  • 这不公平,我先给出了正确答案。你怎么能奖励赏金在赏金关闭后给出的答案。不道德的

标签: java quartz-scheduler


【解决方案1】:

@4herpsand7derpsago 是的,你是对的,你是 99%,我运行了你的代码,其中只有一个问题,HttpPollingJobPollingJob 类中没有默认构造函数,因此调度程序不是能够创建他们的实例,

简单的解决方案在下面的类中添加以下代码
HttpPollingJob

public HttpPollingJob() {
}

PollingJob

public PollingJob() {
}

Bingo,将打印以下消息

Job fired!
Job fired!
Job fired!

如果要重复触发,在PollingJob

中添加如下代码
protected final Trigger getDefaultTrigger() {
    TriggerBuilder<?> triggerBuilder = TriggerBuilder
            .newTrigger()
            .startNow()
            .withSchedule(
                    SimpleScheduleBuilder.simpleSchedule()
                            .withIntervalInMilliseconds(DEF_FREQUENCY).repeatForever());

    return triggerBuilder.build();
}

希望现在我能收到赏金:)

奖金
似乎您想使用 url 进行投票或做某事,使用 king JobDataMap

来传递它的更好方法

更新JobDriver

import java.util.ArrayList;
import java.util.List;

import org.quartz.JobBuilder;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;

public class JobDriver {
private List<HttpPollingJob> jobs;

public JobDriver() {
    HttpPollingJob job1 = new HttpPollingJob("job-1",
            "http://www.example.com/1");
    HttpPollingJob job2 = new HttpPollingJob("job-2",
            "http://www.example.com/2");
    HttpPollingJob job3 = new HttpPollingJob("job-3",
            "http://www.example.com/3");

    jobs = new ArrayList<HttpPollingJob>();
    jobs.add(job1);
    jobs.add(job2);
    jobs.add(job3);
}

public static void main(String[] args) {
    JobDriver driver = new JobDriver();
    driver.startJobs();
}

private void startJobs() {
    try {
        // Obtain a basic SchedulerFactory and fire it up.
        SchedulerFactory schedulerFactory = new org.quartz.impl.StdSchedulerFactory();
        Scheduler scheduler = schedulerFactory.getScheduler();
        scheduler.start();
        // Define a job for every declared monitor.
        JobBuilder jobBuilder = null;

        for (HttpPollingJob job : jobs) {

            Trigger trigger = job.getTrigger();
            jobBuilder = JobBuilder.newJob(job.getClass());
            jobBuilder.usingJobData("name", job.getName());
            jobBuilder.usingJobData("url", job.getServerURL());

            // Bind the current job to this trigger.
            scheduler.scheduleJob(jobBuilder.build(), trigger);

            // TODO: Shut the scheduler down politely?!?!
        }


    } catch (Throwable exc) {
        // Force application to kick out.
        throw new RuntimeException(exc);
    }
}
}

更新了 HttpPollingJob

import java.util.Map;

import org.quartz.JobExecutionContext;

public class HttpPollingJob extends PollingJob {
private String serverURL;
private org.slf4j.Logger logger =
    org.slf4j.LoggerFactory.getLogger(HttpPollingJob.class);

public HttpPollingJob(final String nm, final String server) {
    super(nm);

    setServerURL(server);
}
public HttpPollingJob() {
}

public String getServerURL() {
    return serverURL;
}

public void setServerURL(final String server) {
    serverURL = server;
}

@Override
public final void poll(JobExecutionContext context) {

    try {
        Map dataMap = context.getJobDetail().getJobDataMap();
        String nm = (String)dataMap.get("name");
        String url = (String)dataMap.get("url");
        // This is where we would use HttpClient to connect to a web server and poll it.
        System.out.println("Job fired! name:"+nm+" url:"+url);
    }
    catch(Throwable thrown) {
        logger.error(thrown.getMessage());
    }
}
}

新输出

Job fired! name:job-1 url:http://www.example.com/1
Job fired! name:job-2 url:http://www.example.com/2
Job fired! name:job-3 url:http://www.example.com/3

【讨论】:

  • @4herpsand7derpsago 你检查我的答案了吗?
【解决方案2】:

显然,您还没有启动触发器。见Quartz TutorialJavadocs

// Trigger the job to run now, and then every 40 seconds
  Trigger trigger = newTrigger()
      .withIdentity("myTrigger", "group1")
      .startNow()
      .withSchedule(simpleSchedule()
          .withIntervalInSeconds(40)
          .repeatForever())            
      .build();

【讨论】:

  • 这仍然不起作用...还有其他想法吗?无论如何都要为帮助 +1!
【解决方案3】:

它是你的构造函数——JobBuilder 寻找无参数,因为它们没有被定义,所以它拒绝构建工作。添加空的无参数 ctor,一切就绪。

【讨论】:

  • 哇,你给了自己一个赏金,我们可以报告这个答案吗?
【解决方案4】:

您能否尝试将PollingJob 类中方法getDefaultTrigger 的代码更改为以下代码:

    protected final Trigger getDefaultTrigger()  {

return TriggerBuilder.newTrigger()
         .withSchedule(SimpleScheduleBuilder.simpleSchedule()
        .withIntervalInMilliseconds(DEF_FREQUENCY))
        .startAt(DateBuilder.futureDate(1,  DateBuilder.IntervalUnit.SECOND))
        .build();
}

【讨论】:

    【解决方案5】:

    我觉得您创建触发器的方式有些问题。 请记住,您不能为多个作业重复使用触发器

    尝试创建具有唯一身份和组的触发器,如下所示

    触发 everyHourTrigger = newTrigger().withIdentity("everyWeeklyTrigger", "group1") .startNow().withSchedule(cronSchedule("0 1 * * * ?")).build();

    【讨论】:

      猜你喜欢
      • 2019-09-08
      • 2017-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-06
      • 1970-01-01
      相关资源
      最近更新 更多