eXo Platform 3.0

- Prev
- Next

## Chapter 54. Job Scheduler Service

## What is Job Scheduler

Job scheduler defines a job to execute a given number of times during a given period. It is a a software application that is in charge of unattended background executions, commonly known for historical reasons as batch processing.

Today's job schedulers typically provide a graphical user interface and a single point of control for definition and monitoring of background executions in a distributed network of computers. Increasingly job schedulers are required to orchestrate the integration of real-time business activities with traditional background IT processing, across different operating system platforms and business application environments.

Some features that may be found in a job scheduler include:

- Continuously automatic monitoring of jobs and completion notification

- Event-driven job scheduling

- Performance monitoring

- Report scheduling

## How does Job Scheduler work?

Jobs are scheduled to run when a given Trigger occurs. Triggers can be created with nearly any combination of the following directives:

- at a certain time of day (to the millisecond)

- on certain days of the week

- on certain days of the month

- on certain days of the year

- not on certain days listed within a registered Calendar (such as business holidays)

- repeated a specific number of times

- repeated until a specific time/date

- repeated indefinitely

- repeated with a delay interval

Jobs are given names by their creator and can also be organized into named groups. Triggers may also be given names and placed into groups, in order to easily organize them within the scheduler. Jobs can be added to the scheduler once, but registered with multiple Triggers. Within a J2EE environment, Jobs can perform their work as part of a distributed (XA) transaction.

### How can Job Scheduler Service be used in Kernel?

Kernel leverages Quartz for its scheduler service and wraps `org.quartz.Scheduler` in `org.exoplatform.services.scheduler.impl.QuartzSheduler` for easier service wiring and configuration like any other services. To work with Quartz in Kernel, you'll mostly work with `org.exoplatform.services.scheduler.JobSchedulerService` (implemented by `org.exoplatform.services.scheduler.impl.JobSchedulerServiceImpl`.

To use `JobSchedulerService`, you can configure it as a component in the configuration.xml. Because `JobSchedulerService` requires `QuartzSheduler` and `QueueTasks`, you also have to configure these two components.

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
      xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">

      <component>
        <type>org.exoplatform.services.scheduler.impl.QuartzSheduler</type>
      </component>

      <component>
        <type>org.exoplatform.services.scheduler.QueueTasks</type>
      </component>

      <component>
        <key>org.exoplatform.services.scheduler.JobSchedulerService</key>
        <type>org.exoplatform.services.scheduler.impl.JobSchedulerServiceImpl</type>
      </component>

    </configuration>

### Samples

We will work with `JobSchedulerService` by creating a sample project and use GateIn-3.1.0-GA for testing.

Firstly, create a project:

    mvn archetype:generate
    //....
    Choose version:
    1: 1.0
    2: 1.0-alpha-1
    3: 1.0-alpha-2
    4: 1.0-alpha-3
    5: 1.0-alpha-4
    Choose a number: : 1
    Define value for property 'groupId': : org.exoplatform.samples
    Define value for property 'artifactId': : exo.samples.scheduler
    Define value for property 'version': 1.0-SNAPSHOT: 1.0-SNAPSHOT
    Define value for property 'package': org.exoplatform.samples: jar
    Confirm properties configuration:
    groupId: org.exoplatform.samples
    artifactId: exo.samples.scheduler
    version: 1.0-SNAPSHOT
    package: jar
    Y: Y

Choose version as 1.0-SNAPSHOT, groupId as org.exoplatform.samples, artifactId as exo.samples.scheduler and package as jar. Edit the pom.xml as following:

    <project
      xmlns="http://maven.apache.org/POM/4.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

      <modelVersion>4.0.0</modelVersion>

      <parent>
        <artifactId>exo.portal.parent</artifactId>
        <groupId>org.exoplatform.portal</groupId>
        <version>3.1.0-GA</version>
      </parent>

      <groupId>org.exoplatform.samples</groupId>
      <artifactId>exo.samples.scheduler</artifactId>
      <version>1.0-SNAPSHOT</version>
      <name>eXo Samples For Scheduler</name>
      <description>eXo Samples Code For Scheduler</description>
      <dependencies>

        <dependency>
          <groupId>quartz</groupId>
          <artifactId>quartz</artifactId>
          <version>1.5.2</version>
          <scope>provided</scope>
        </dependency>

        <dependency>
          <groupId>picocontainer</groupId>
          <artifactId>picocontainer</artifactId>
          <version>1.1</version>
          <scope>provided</scope>
        </dependency>

        <dependency>
          <groupId>org.exoplatform.kernel</groupId>
          <artifactId>exo.kernel.commons</artifactId>
          <scope>provided</scope>
        </dependency>

        <dependency>
          <groupId>org.exoplatform.kernel</groupId>
          <artifactId>exo.kernel.component.common</artifactId>
          <scope>provided</scope>
        </dependency>

      </dependencies>
    </project>

After that, create a eclipse project and then import into eclipse:

    mvn eclipse:eclipse

We'll work with this project all the time through samples.

#### StartableScheduler for DumbJob example

- See how it works on Quartz at: http://www.quartz-scheduler.org/docs/tutorial/TutorialLesson03.html

- Create a package in created project: conf/portal and add a configuration configuration.xml as follows:

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
      xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">

      <component>
        <type>org.exoplatform.services.scheduler.impl.QuartzSheduler</type>
      </component>

      <component>
        <type>org.exoplatform.services.scheduler.QueueTasks</type>
      </component>

      <component>
        <key>org.exoplatform.services.scheduler.JobSchedulerService</key>
        <type>org.exoplatform.services.scheduler.impl.JobSchedulerServiceImpl</type>
      </component>

      <component>
        <type>org.exoplatform.samples.scheduler.StartableScheduler</type>
      </component>

    </configuration>

- Note: You can see a component: StartableSheduler to be defined. It's a component startable when portal containers are initialized.

    package org.exoplatform.samples.scheduler;

    import java.util.Date;

    import org.exoplatform.samples.scheduler.jobs.DumbJob;
    import org.exoplatform.services.log.ExoLogger;
    import org.exoplatform.services.log.Log;
    import org.exoplatform.services.scheduler.impl.QuartzSheduler;
    import org.picocontainer.Startable;
    import org.quartz.JobDetail;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.quartz.Trigger;
    import org.quartz.TriggerUtils;

    /**
     * Created by The eXo Platform SAS
     * Author : eXoPlatform
     *          exo@exoplatform.com
     * Jul 1, 2010
     */
    public class StartableScheduler implements Startable {
      private static final Log LOG = ExoLogger.getLogger(StartableScheduler.class);

      public StartableScheduler(QuartzSheduler quartzScheduler) throws SchedulerException {
        LOG.info("Init StartableScheduler");
        JobDetail jobDetail = new JobDetail("myJob",
                                            Scheduler.DEFAULT_GROUP,
                                            DumbJob.class);
        Trigger trigger = TriggerUtils.makeImmediateTrigger(3, 5000);
        trigger.setStartTime(new Date());
        trigger.setName("myTrigger");

        Scheduler scheduler = quartzScheduler.getQuartzSheduler();

        scheduler.scheduleJob(jobDetail, trigger);
      }

      @Override
      public void start() {
        // TODO Auto-generated method stub

      }
      @Override
      public void stop() {
        // TODO Auto-generated method stub

      }
    }

- DumbJob is defined as a job:

    package org.exoplatform.samples.scheduler.jobs;

    import org.exoplatform.services.log.ExoLogger;
    import org.exoplatform.services.log.Log;
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;

    /**
     * DumbJob.java
     *
     * @author     <a href="http://hoatle.net">hoatle (hoatlevan at gmail dot com)</a>
     * @since      Jul 1, 2010
     * @copyright  eXo SAS
     */
    public class DumbJob implements Job {
      private static final Log LOG = ExoLogger.getLogger(DumbJob.class);
      @Override
      public void execute(JobExecutionContext context) throws JobExecutionException {
        LOG.info("DumbJob is executing!");
      }

    }

mvn clean install the project. Copy jar file to lib in tomcat bundled with GateIn-3.1.0-GA. Run bin/gatein.sh to see the DumbJob executed on the terminal when portal containers are initialized.

### Where is Job Scheduler Service used in eXo Products?

Job Service Scheduler (JSS) is used in many eXo products such as Social, DMS, WCM, KS and CS.

For example: It is used in Schedule lifecycle in DMS.

Also, it is used for News Letter Email Job in ECM, Reminder Job for calendar and History Job for chat in CS, Auto-count Active Users in KS.

By using Job Scheduler Service in eXo kernel, many kinds of job can be configured to run. You can addPeriodJob, addCronJob, addGlobalJobListener, addJobListener and many more. Just write a job (a class implements Job interface of quartz library and config plugin for JobSchedulerService and you're done.

## Advantages of Job Scheduler

It's very useful to use Job Scheduler to create schedules for a lot of work, especially if they are spread across multiple machines. It's a tool to make that task a lot easier. Job Schedule is also widely used in almost eXo products such as: WCM, DMS, KS, CS, Social thanks to its benefits and advantages.

- The Job Scheduler provides automatically log files for running programs

- The execution status of programs is automatically checked and an administrator will receive protocols by eMail

- The sequence of job starts can be organized depending on their execution status

- Job Schedulers are controlled by a graphical user interface

- Job Schedulers can be used to create complex job chains and job dependencies

Also, a wide variety of enterprise applications can take advantage of job schedulers. Job schedulers can enhance the functionality of enterprise applications as well as simplify their design. Furthermore, job scheduling components allow software development teams to focus on their applications and not on the intricate details of scheduling. By using server-side components, software teams can reduce development costs and bring their applications to market sooner.

## Reference

To further understand about Job Scheduler, you can refer the following links:

- http://www.quartz-scheduler.org/

- http://en.wikipedia.org/wiki/Job_scheduler

- http://www.theserverside.com/news/1364726/Job-Scheduling-in-J2EE-Applications

- http://technet.microsoft.com/en-us/library/cc720070%28WS.10%29.aspx

- Prev
- Up
- Home
- Next