About

Fathom-Quartz provides Quartz Scheduler integration for your application. Quartz allows you to easily setup scheduled tasks within your application.

This is a fork of the Apache Onami Scheduler.

Installation

Add the Fathom-Quartz artifact.

<dependency>
    <groupId>com.gitblit.fathom</groupId>
    <artifactId>fathom-quartz</artifactId>
    <version>${fathom.version}</version>
</dependency>

Layout

YourApp
└── src
    └── main
        └── java
            └── conf
                ├── Jobs.java
                └── quartz.properties

Note

This module depends on the value of the application.package setting. If you have specified an application package then your Jobs class must be ${package}/conf/Jobs.java.

Configuration

By default, this module will try to configure Quartz from a conf/quartz.properties resource file.

Quartz has many features and settings. Two common ones that you are likely to change are how worker threads are named and how many threads are in the Quartz threadpool.

# Prefix of Quartz worker thread
org.quartz.threadPool.threadNamePrefix = Jobs Worker

# Number of threads in the Quartz pool
org.quartz.threadPool.threadCount = 5

Usage

Create a conf/Jobs.java class. Jobs can be manually scheduled in the conf/Jobs.java class or they can be annotated on each Job class.

package conf;

public class Jobs extends JobsModule {

  @Override
  protected void schedule() {

    scheduleJob(MyJob.class);
    scheduleJob(OtherJob.class).withCronExpression("0/60 * * * * ?");

  }

}

Then create some Job classes. Job classes support injection.

@Scheduled(jobName = "My Job", cronExpression = "0/60 * * * * ?")
@DisallowConcurrentExecution
public class MyJob implements Job {

  final Logger log = LoggerFactory.getLogger(MyJob`.class);

  @Inject
  EmployeeDao employeeDao;

  @Override
  public void execute(JobExecutionContext context) throws JobExecutionException {
    int count = employeeDao.getAll().size();
    log.debug("My job triggered, {} employees in system", count);
  }

}

Requiring Settings

Your job may need one or more settings to function and you may specify them as annotated requirements.

Each required setting must be present in the runtime profile configuration and must have a non-empty value otherwise the job will not be registered.

@RequireSetting("myjob.url")
@Scheduled(jobName = "My Job", cronExpression = "0/60 * * * * ?")
public class MyJob implements Job {

  final Logger log = LoggerFactory.getLogger(MyJob.class);

  @Inject
  Settings settings;

  @Override
  public void execute(JobExecutionContext context) throws JobExecutionException {
    String url = settings.getString("myjob.url");
    log.debug("My job triggered {}", url);
  }

}

Requiring Modes

You might only want to load your job in a particular runtime mode. This is easily accomplished by using one or more of the mode-specific annotations: @DEV, @TEST, and @PROD.

@Scheduled(jobName = "DEV Job", cronExpression = "0/30 * * * * ?")
@DEV
public class DevJob implements Job {

  final Logger log = LoggerFactory.getLogger(DevJob.class);

  @Override
  public void execute(JobExecutionContext context) throws JobExecutionException {
    log.debug("My DEV job triggered");
  }

}

Monitoring

Fathom-Quartz installs a global job listener which automatically tracks job execution statistics, buffers recent job stacktraces, and allows pause & resume control over jobs.

@Inject
JobsMonitor jobsMonitor;

public void logJobsThatThrewAnException() {
  for (JobInfo job : jobsMonitor.getJobs()) {
    if (job.getExceptionCount() > 0) {}
      log.error("{} was executed {} times and failed {} times ({}% failure rate)",
        job.getName(), job.getExecutionCount(), job.getExceptionCount(), job.getExceptionPercentage());
    }
  }
}