Skip Headers

Oracle® Application Server Containers for J2EE Job Scheduler Developer's Guide 10g Release 3 (10.1.3) B15876-01 |
| Home | Solution Area | Contents | Index

Previous | Next |

# 2 Adding and Removing Jobs

This chapter describes how to add and remove jobs use Oracle Application Server Containers for J2EE. The following topics are covered:

- Adding Jobs

- Accessing Job Scheduler Using JNDI Lookup

- Removing Jobs

- Best Practices for Adding and Removing Jobs

- Frequently Asked Questions About Adding and Removing Jobs

## 2.1 Adding Jobs

Before a job can be run, it must first be submitted to Job Scheduler.

To add a job, you must implement the `oracle.ias.scheduler.Executable` interface, then submit the job to Job Scheduler using the `oracle.ias.scheduler.Scheduler.add()` API method.

For more information about `add()`, see Oracle Containers for J2EE Job Scheduler API Reference.

### 2.1.1 Implementing a Job with the Executable Interface

The `oracle.ias.scheduler.Executable` interface is defined as follows:

    public interface Executable {
       public void execute (JobContext context) throws JobExecutionException, JobCancellationException;
    }

This interface specifies the contract by which a Java class is invoked by the Job Scheduler. All Java classes submitted to Job Scheduler must implement this interface.

Note: Any class implementing this interface must provide an empty constructor. Each time a submitted job is run, a new instance of the object is created using this constructor. As such, a job implementation should not rely on instance or static member variables for maintaining state.

The `execute()` method is invoked by Job Scheduler when the associated job's trigger fires. Use the `oracle.ias.scheduler.JobContext` object as the input parameter to enable a job to examine and evaluate all associated metadata related to the job definition and access to the logging subsystem.

The `oracle.ias.scheduler.JobContext` object provides the following methods

- `getLogger()`

  This method returns a JDK 1.4-compliant logger object `java.util.logging.Logger` that references the application's log.

- `getJob()`

  This method returns an `oracle.ias.scheduler.Job` object used to access the job's configuration information.

The `oracle.ias.scheduler.JobContext` object provides access to the job's data and associated subsystems. For more information, refer to Oracle Containers for J2EE Job Scheduler API Reference.

### 2.1.2 Submitting a Job

For a job to run, it must first be submitted to Job Scheduler. This is done using the `oracle.ias.scheduler.Scheduler.add()` method. As part of the submission, input parameters may be specified as name-value pairs using a `java.util.Properties` object. For maintenance and reusability purposes, job parameters should be used whenever possible (see Example 2-1).

With the `oracle.ias.scheduler.Scheduler.add()` method, you can add a job with a schedule, a trigger, or both.

Once the job is submitted, the specified class is executed by Job Scheduler according to the specified schedule or trigger. If the schedule does not repeat, the job becomes inactive after the timer expiration notification is sent to the associated trigger.

When a job is successfully submitted, an `oracle.ias.scheduler.JobHandle` object is returned. This object functions as a handle to the submitted job. This handle may be used to perform certain administration tasks on the job (for example, pausing the job). Additionally, this object may be stored by the application for later use.

The `add()` method provides transaction support. If the transaction is rolled back for any reason, the operation is canceled and the job is not created. In addition, a job will not run until the transaction is committed.

### 2.1.3 Examples of Adding Jobs

This section provides examples of how to implement and submit a job to Job Scheduler.

Example 2-1 Implementing a Job to Perform Backups

Scenario: A legacy application was migrated to the J2EE environment, part of which includes data stored in a file system. As part of the J2EE application, a job is required to back up the data on a regular basis. The job requires two input parameters:

1. Source directory: the directory from which files will be copied

2. Destination directory: the directory to which files will be copied

The source and destination directories could have been included in the job implementation. However, by specifying these as parameters to the job properties, the job can be used again without modification. See Example 2-2 for an example of how properties are specified.

    import java.io.File;
    import java.io.IOException;
    import oracle.ias.scheduler.Job;
    import oracle.ias.scheduler.Executable;
    import oracle.ias.scheduler.JobContext;
    import oracle.ias.scheduler.JobExecutionException;

    public class BackupJob implements Executable {

        public void execute(JobContext context) throws JobExecutionException {

            // retrieve the source/destination directories
            Job job = context.getJob();
            String source = job.getProperties().getProperty("SourceDirectory");
            String destination =              job.getProperties().getProperty("DestinationDirectory");

            // get the list of files to copy
            File directory = new File(source);
            File[] files = directory.listFiles();

            // copy the files
            Runtime runtime = Runtime.getRuntime();
            Process process;
            for (int x = 0; x < files.length; x++) {
                try {
                    process = runtime.exec("/bin/cp " + files[x].toString() +
                                           " " + destination);
                    process.waitFor();
                } catch(IOException e) {
                    throw new RuntimeException("copy failed: "+files[x],e);
                } catch(InterruptedException e) {
                    throw new RuntimeException("copy failed: "+files[x],e);
                }
            }
        }
    }

Notice that the `getProperty()` object is used to retrieve the source and destination directories. Instead of specifying these directories directly in the job implementation, they are specified when the job is submitted to Job Scheduler (see Example 2-2).

Using the `execute()` method fulfills the contract for implementing the `oracle.ias.scheduler.Executable` interface. This method is invoked every time the job is executed.

Example 2-2 Specifying Job Properties and Submitting a Job

Once a job is created, it must be submitted to Job Scheduler. A job is submitted using the `add()` method provided by Job Scheduler. The following code example shows how the job is submitted with properties (in this case, the source and destination directories):

    // set up the properties
    java.util.Properties properties = new Properties();
    properties.put("SourceDirectory","/mnt/data");
    properties.put("DestinationDirectory","/mnt/backup");

    // submit the job
    jobHandle = scheduler.add("file backup job, runs every week",
                               new BackupJob().getClass().getName(),
                               new Schedule(),
                               properties);

Notice that the job properties and schedule are specified when the job is submitted to Job Scheduler. For more information about specifying scheduling options, see Chapter 3.

## 2.2 Accessing Job Scheduler Using JNDI Lookup

The Java Naming and Directory Interface (JNDI) is a native Java API that enables any Java-based application to store and retrieve any Java object. It provides naming and directory services for Java applications, enabling them to store and retrieve named Java objects of any type.

The following code example shows how to perform a JNDI lookup to access Job Scheduler:

    InitialContext ic = new InitialContext();
    Object objRef = ic.lookup("java:comp/env/ejb/scheduler");
    SchedulerHome home = (SchedulerHome)
    PortableRemoteObject.narrow(objRef, SchedulerHome.class);
    Scheduler scheduler = home.create();

For more information about JNDI, go to:

`http://java.sun.com/products/jndi/index.jsp`

## 2.3 Removing Jobs

After a job is submitted, it can be removed with the `oracle.ias.scheduler.Scheduler.remove()` method. This method does not remove any job executions that are running, but it does remove the job definition, thus preventing any job executions from being run in the future.

For more information about the `remove()` method, see Oracle Containers for J2EE Job Scheduler API Reference.

The following code example shows how to remove the `BackupJob` job implemented in Example 2-1 and submitted in Example 2-2:

Example 2-3 Removing a Job

    // remove a job
    scheduler.remove(jobHandle);

If you want to stop a job execution that is currently running, you must cancel the job. For more information about canceling jobs, see Chapter 6.

If you want to stop scheduled jobs from running but do not want to have their definitions removed from the system, thereby preventing them from ever running again, you should pause the job. For more information about pausing jobs, see Chapter 5.

## 2.4 Best Practices for Adding and Removing Jobs

When designing and implementing a job, keep the following in mind:

- All job metadata is available at run time. Use the `oracle.ias.scheduler.JobContext` object to access it.

- Input parameters can improve job reuse. During implementation, identify input parameters and use properties as necessary.

- A job that needs to be canceled must use the oracle.ias.scheduler.Cancellable interface. Trying to cancel a job that does not use this interface causes an exception.

- Implementation of the execute( ) method must eventually return control to the caller. Avoid gating job completion based on an application condition or conditions that require a long time before the condition is met (for example, in excess of one minute). Instead, use a trigger to start the job execution when the application's condition or conditions have ben met. In doing so, you minimize the processing resources required by the application.

## 2.5 Frequently Asked Questions About Adding and Removing Jobs

What are the possible states for a job?

At any point in time, a job can be in one of three states: active, paused, or completed.

In the active state, a job can receive notifications and evaluate the trigger expression. If the trigger evaluates to true in the active state, the job is executed and the trigger is reset to false.

In the paused state, a job can receive notifications and evaluate trigger expressions. However, if a trigger evaluates to true in the paused state, the trigger is not reset to false and the job execution is suppressed.

In the completed state (which is a valid state for schedule-based jobs), scheduling of jobs is completed and no new jobs can be scheduled. If a job is not schedule-based, then it cannot be in the completed state. For more information about schedule-based jobs, see Chapter 3.

Does removing a job also remove the outstanding retry (of a job that failed to run) and replay (of a paused job) executions?

Yes, removing a job means no job executions will occur.

For more information about retry, see Chapter 3. For more information about replay, see Chapter 5.