Accessibility
 
Icon or Spacer
   
Using the Scheduler Servlet in JRun

By Matt Horn
JRun Documentation
Allaire Corp.

JRun includes a Scheduler servlet that executes actions at specified times. Actions can be servlets, CGI requests, ColdFusion pages, ASP pages, or any other Web document. This article concentrates on using the Scheduler servlet to request other servlets.

The Scheduler servlet is conceptually similar to the cron daemon on Unix systems or the Scheduler service (and at command) on Windows NT. A comparison to cron is given below.

This document describes the Scheduler servlet in the following sections:

Overview

Scheduled tasks are typically used by system administrators to run batch jobs such as backups, disk cleaning, and user activity logging. They are sometimes used to search for and record anomalous activity, but almost any command can be run at a set time.

While administrative activities are possible with the Scheduler servlet, they are often easier to do with your existing administrative tools. However, executing servlets or requesting other Web requests at certain intervals can be useful for specialized logging or housecleaning chores, batch processing, or content syndication.

To use the Scheduler servlet, you create an initialization file. Each line of this file defines the time(s) and request string. The request string includes a servlet and any initialization parameters. JRun checks the initialization file when it is started to determine when to execute the request strings. If you make changes to the initialization file, you must restart the JRun server.

Scheduler Servlet and Cron

If you are familiar with the Unix cron daemon, then you will be familiar with the Scheduler servlet. Rather than a crontab file, the Scheduler servlet reads an initialization file that you specify in the web application's web.xml file (more on this later). For the purposes of this document, the "crontab" file for the Scheduler servlet will be referred to as schedule.ini, but you can name the file anything you want. The schedule.ini file contains the execution times and the actions to execute.

Initialization File Syntax

The format of the Scheduler initialization file is similar to a crontab file, with the addition of a seconds parameter and the use of a request string rather than a command. Any time you make a change to the initialization file, you must restart the JRun server.

The syntaxt for the Scheduler servlet's initialization file is:

sec, min, hour, day, month, dayofweek, request

Valid values are as follows:


Parameter Order Full Name Valid Values Description
sec 1st second 0-59 The only argument which cannot contain *.
min 2nd minute 0-59 Military time.
hour 3rd hour 0-23 Military time.
day 4th day of month 1-31  
month 5th month jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec  
dayofweek 6th day of week sun,mon,tue,wed,thu,fri,sat  
request 7th full request string any request string For example, http://hostname.com/request?name=value.

Only the request argument may contain whitespace. The other arguments contain either an asterisk (*) as a wildcard or a comma-separated lists of one or more expressions. An expression is a legal value or a range of legal values specified by the starting and ending values seperated by a hyphen (-). The definition of a legal value depends on the argument. For example: "0,30 * * * * * foo" runs the "foo" command every 30 seconds; "0 0 1 * * mon-fri" occurs at 1 a.m. Monday through Friday.

Each argument is separated by a space.

Edge conditions (for example, the 31st day of months with only 30 days) still occur (for example, on the 1st of the next month) without generating an error. The dayofweek and day (of month) values are or'ed together. For example, "0 0 0 8,11 * mon" occurs midnight every Monday and on the 8th and 11th of every month. However, if one is a "*", then it is ignored. For example, "0 0 0 * * mon" does not occur every day, only every Monday.

Comments can be added using #.

Some sample entries in the intialization file are as follows:

# This is the ini file
#
# Request the SnoopServlet servlet at quarter of every hour of every day:
0 45 * * * * http://localhost/demo/servlet/SnoopServlet
#
# Request the Date servlet every 5 minutes:
0 0,5,10,15,20,25,30,35,40,45,50,55 * * * * http://localhost/servlet/Date
#
# Request the Backup servlet every Friday at 1:02:30 a.m.
30 2 13 * * fri http://localhost/servlet/Backup?erase=true&user=frank
#
# Request the BatchAfterBackup servlet at 12 a.m. the 5th and 20th of every other month
0 0 12 5,20 jan,mar,may,jul,sep,nov * http://localhost/servlet/BatchAfterBackup
#
# Request the BuildAll servlet at half past the hour during business hours
# (8 a.m. - 5p.m.) and again at 8 p.m., Monday through Friday
0 30 8-17,20 * * mon-fri http://localhost/servlet/BuildAll

Using the Scheduler Servlet

To use the Scheduler servlet, perform the following steps:

  1. Create a schedule.ini file. A sample entry in a schedule.ini file is below:
    # Request the WriteTime servlet every 30 seconds:
    15,45 * * * * * http://localhost/demo/servlet/WriteTime
    
  2. Add a new <servlet> block in the web.xml file. This is done in the web.xml file of the Web application that you want to have call the Scheduler servlet.

    The <servlet> block must specify <servlet-name> and <servlet-class> elements. can be any name you choose. Do not use the same name as an existing servlet that is running in your servlet engine. <servlet-class> must be allaire.jrun.scheduler.CronService.

    The <servlet> block also specifies two initialization parameters: schedfile and logfile. Both parameters are required. The schedfile parameter is the initialization file that specifies the actions and their execution times, as described above. The logfile parameter specifies the location of a file that logs Scheduler servlet activity and can be useful for debugging.

    For example, add the following <servlet> block in JRun_root_dir \servers\default\default-app\WEB-INF\web.xml (note that you cannot use the JMC to define the Scheduler servlet):

    
    SchedTest
    allaire.jrun.scheduler.CronService
    SchedTest
    
    
    schedfile
    c:\temp\schedule.ini
    
    
    logfile
    c:\temp\sched.log
    
    
    
    

    This <servlet> block also specifies that SchedTest be loaded on startup, but this is optional.

    It is important to note that even though you added a description of SchedTest to the web.xml file in a <servlet> block, you do not need to create a SchedTest servlet. The CronService takes care of the details. The name here is arbitrary, but you will be able to request this servlet to see a list of secheduled actions.
  3. Restart your JRun server:
    jrun -restart default
    

Additional Notes

Viewing a list of scheduled actions

You can view a list of currently scheduled actions by pointing your browser to the CronService's servlet. For example, in the example above, you could request http://localhost/servlet/SchedTest. JRun responds with a list of currently scheduled actions (defined in the initialization file), as shown in the following example:

CronServlet 3.0

Action Next Scheduled Time
http://localhost/demo/servlet/WriteTime Wed Sep 27 11:17:45 EDT 2000
http://localhost/demo/servlet/SimpleServlet Wed Sep 27 11:17:30 EDT 2000

Understanding Scheduler Servlet Output

You will not see the output of the scheduled action(s) in the traditional sense. Normally, a client, such as a Web browser, makes a request to a servlet which responds with a Web page. The Web page is then viewed in the browser by the client. In the case of scheduled servlets, the Scheduler servlet is the client and the response is not displayed.

Keep in mind that the Scheduler servlet is for batch-type jobs and does not follow the client/server, request/response kind of paradigm. Rather, the scheduled servlet processes its input, if any, and discards the HTTPServletResponse output. Other output, such as writing to files or sending output to other processes, is processed as normal.

Minimizing processing overload

If you are using the Scheduler service to execute processing-intensive servlets that may tie up a significant amount of system resources, you should try setting the execution time to be an odd number, like 4:12:30 a.m. rather than 4 a.m. This minimizes the likelihood that different people will schedule jobs at the same time and therefore cause the servlets to vie for system resources.

Scheduler servlet classes

The classes used by the Scheduler servlet are part of jrun.jar. Specifically, they are:

  • CronService
  • CronTab
  • CronTabEntry
  • CronTabException
  • PeriodicRunnable
  • SchedulerService

Scheduler Servlet Example

The following servlet is an example of using the Scheduler servlet. The task at hand is to generate an HTML page every 10 minutes that provides a directory listing of the default JRun server's /classes directory. This example shows the directory to be located at c:\Program Files\Allaire\JRun\servers\default\default-app\WEB-INF\classes. The page then lists the class files and creates HTTP links for each of them. Using this page, a group of people can get a quick view of a rapidly changing set of classes.

Example Components

This example consists of 3 parts (shown below):

  • schedule.ini file
  • WriteServlets servlet
  • block in the default the web application's web.xml file

These components are described in the sections that follow.

schedule.ini file

This example stores this file in c:\temp\initialization.ini

# Execute WriteServlets servlet every ten minutes
0 0,10,20,30,40,50 * * * * http://localhost/servlet/WriteServlets

WriteServlets Servlet in the JRun Default Server's Classes Directory

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class WriteServlets extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {

String HTMLfile = request.getRealPath("/") + "\\servlets.html";

PrintWriter out = response.getWriter();
response.setContentType("Text/html");

String title = ("Available Classes");

//Get a directory listing of class files.
String dir = "c:\\Program Files\\Allaire\\JRun\\servers\\default\\default-app\\WEB-INF\\classes";
File listdir = new File(dir);
String[] filesindir = listdir.list();

//
//This is the output when the servlet is called directly;
//When called indirectly (by scheduler servlet), this output goes nowhere.
//
out.println("<html><head><title>File Writing Example");
out.println("</head>");
out.println("<BODY>

" + title + "

"); out.println("

This servlet, when called, searches a directory and writes out links to all files in that directory."); out.println("

To see the output: http://localhost/servlets.html"); out.println("</BODY></HTML>"); // //This is the output that is meant to be generated at specified intervals. // try { //Delete existing HTML file, if any. File oldfile = new File(HTMLfile); if (oldfile.exists()) { oldfile.delete(); } //Set up the new HTML file. PrintWriter fileout = new PrintWriter (new FileOutputStream(HTMLfile, true), true); fileout.println("<HTML><HEAD><TITLE>Available Servlets</TITLE></HEAD>"); fileout.println("<BODY>

Available classes on default server


"); //Output list of class files to the HTML file. String server_name = request.getServerName(); String link_part1 = "http://" + server_name + "/servlet/"; Date date = new Date(); fileout.println("List of *.class files in
" + dir + "
"); fileout.println("
As of: " + date + ""); fileout.println("

"); for (int i = 0; i <filesindir.length; i++) { //Output the servlet count and the full file name. fileout.println("TR>"); fileout.println(""); //Build the hyperlinks and drop ".class" from file names. StringTokenizer st = new StringTokenizer(filesindir[i],"."); String link_part2 = (String) st.nextElement(); String link = link_part1 + link_part2; fileout.println(""); } fileout.println("
File
Number
File NameServlet Link" + (i+1) + "" + filesindir[i] + "" + link + "
"); fileout.println("</BODY></HTML>"); } catch (Exception e) { String err = e.toString(); System.out.println(err); } } }

<servlet> Block in web.xml

Add the following <servlet> block to the the web application's web.xml file file in c:\Program Files\Allaire\JRun\servers\default\default-app\WEB-INF\web.xml.


SchedTest
allaire.jrun.scheduler.CronService
SchedTest


schedfile
c:\temp\schedule.ini


logfile
c:\temp\sched.log



Output

Once the SchedTest servlet is added and the default JRun server is restarted, WriteServlets should create a new servlets.html file in the Web server's root directory every 10 minutes or every time the WriteServlets servlet is requested directly. In this example, the new HTML file is created in c:\inetpub\wwwrooot, Microsoft IIS' document root directory.

The servlets.html file should look something like this:

Available Classes on Default Server

Here is a list of *.class files in
c:\Program Files\Allaire\JRun\servers\default\default-app\WEB-INF\classes

As of: Fri Sep 29 12:10:03 EDT 2000

File
Number
File Name Servlet Link
1 Acronym.class http://localhost/servlet/Acronym
2 AddAcronym.class http://localhost/servlet/AddAcronym
3 AuthUser.class http://localhost/servlet/AuthUser
4 Book.class http://localhost/servlet/Book
5 Comments.class http://localhost/servlet/Comments
6 Error.class http://localhost/servlet/Error
7 ProtectedPage.class http://localhost/servlet/ProtectedPage
8 remote.class http://localhost/servlet/remote
9 SessionTest.class http://localhost/servlet/SessionTest
10 stock.class http://localhost/servlet/stock
11 StockGrabber.class http://localhost/servlet/StockGrabber
12 StockGrabberException.class http://localhost/servlet/StockGrabberException
13 WriteDate.class http://localhost/servlet/WriteDate
14 WriteServlets.class http://localhost/servlet/WriteServlets
15 WriteTime.class http://localhost/servlet/WriteTime