Introduction

This posting is how to for developing and scheduling jobs in WebSphere Application Server. IBM Rational Software Architect/Rational Application Developer is used for this example.

Requirement

  1. IBM Rational Software Architect/Rational Application Developer.
  2. A relational database (SQL Server/Oracle/My SQL etc.).
  3. Knowledge in Java, J2ee and basic Websphere administration (to create data source and etc.)

Steps

  • Creating a WAS Scheduler
  • Creating a EJB Project with stateless session bean which will be used as job.
  • Creating a Dynamic Web Project to control the job.

1. Creating a WAS Scheduler.

  • Open Admin console.
  • To create a scheduler first have to create a data source.
  • Verify the connection is working.
  • No have to create a scheduler.
  • Go to Resources Schedulers.

    resoures_scheduler

  • Create a new scheduler.

    new_scheduler

  • Give a name, specify a JNDI name this will be used to control the jobs register to the scheduler, select data source JNDI name and JAAS alias for the data source.
  • Click Apply and save the configuration.

    save_the_configuration

  • Now select the scheduler and click Create Tables.

2. Creating a EJB project.

  • Create a EJB project in IBM RSA/RAD.
  • Now create a stateless session bean in the EJB project with remote home interface as com.ibm.websphere.scheduler.TaskHandlerHome and remote interface as com.ibm.websphere.scheduler.TaskHandler

    create_a_stateless_session_bean

  • Now you have to change the JNDI of the Bean if you want it can remain as default.
  • The IDE will create a stub EJB Bean.
package ejbs;

public class TestBeanBean implements javax.ejb.SessionBean {

    static final long serialVersionUID = 3206093459760846163L;
    private javax.ejb.SessionContext mySessionCtx;
    public javax.ejb.SessionContext getSessionContext() {
        return mySessionCtx;
    }
    public void setSessionContext(javax.ejb.SessionContext ctx) {
        mySessionCtx = ctx;
    }
    public void ejbCreate() throws javax.ejb.CreateException {
    }
    public void ejbActivate() {
    }
    public void ejbPassivate() {
    }
    public void ejbRemove() {
    }
}
  • Now add the interface com.ibm.websphere.scheduler.TaskHandler and overrides the methods of the Interface and you have the stub of the job bean.
package ejbs;

import java.rmi.RemoteException;

import javax.ejb.EJBHome;
import javax.ejb.EJBObject;
import javax.ejb.Handle;
import javax.ejb.RemoveException;

import com.ibm.websphere.scheduler.TaskStatus;

public class TestBeanBean
    implements javax.ejb.SessionBean,com.ibm.websphere.scheduler.TaskHandler {

    static final long serialVersionUID = 3206093459760846163L;
    private javax.ejb.SessionContext mySessionCtx;
    public javax.ejb.SessionContext getSessionContext() {
        return mySessionCtx;
    }
    public void setSessionContext(javax.ejb.SessionContext ctx) {
        mySessionCtx = ctx;
    }
    public void ejbCreate() throws javax.ejb.CreateException {
    }
    public void ejbActivate() {
    }
    public void ejbPassivate() {
    }
    public void ejbRemove() {
    }
    public void process(TaskStatus taskStatus) throws RemoteException {
        // TODO Here implement the business logic of the job.
        System.out.println("Inside a job bean");
    }
    public EJBHome getEJBHome() throws RemoteException {
        return null;
    }
    public Handle getHandle() throws RemoteException {
        return null;
    }
    public Object getPrimaryKey() throws RemoteException {
        return null;
    }
    public boolean isIdentical(EJBObject object) throws RemoteException {
        return false;
    }
    public void remove() throws RemoteException, RemoveException {

    }
}

3. Creating a Dynamic web project.

  • Create a Dynamic web application.
  • Create the folder called jsp under Webcontent and put the following two JSP files.

testJob.jsp

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<HEAD>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="IBM Software Development Platform">
<META http-equiv="Content-Style-Type" content="text/css">
<TITLE>Test Job</TITLE>
<SCRIPT>
    function setAction(action){
        document.getElementById('action').value=action;
    }
    function init(){
        var error = document.forms[0].error.value;
        if(error.lentgh > 0){
            alert(error);
        }
    }
    function getParams(){
        var action = document.forms[0].action.value;
        if(action == 'start'){
            var url = '<%=request.getContextPath()%>/jsp/testJobParams.jsp';
            var secStr = window.showModalDialog(url,”,'dialogHeight:422px;dialogWidth:550px;center:yes;scroll:no;status:no');
            if(secStr['starttime'] == undefined){
                return;
            }
            document.getElementById('starttime').value=secStr['starttime'];
            document.getElementById('interval').value=secStr['interval'];
        }
    }
</SCRIPT>
</HEAD>
<BODY>

    <table width="100%" height="100%">
        <tr>
            <td align="center" valign="middle">
                <form action="<%=request.getContextPath()%>/TestJob" onsubmit="getParams();">
                    <input type=hidden name="action" id="action"/>
                    <input type=hidden name="starttime" id="starttime"/>
                    <input type=hidden name="interval" id="interval"/>
                    <TABLE>
                        <tr>
                            <td>Test Job Status</td>
                        </tr>
                        <tr>
                            <td>Status: ${requestScope.STATUS}</td>
                        </tr>
                        <tr>
                            <td>Next Sheduld Time: ${requestScope.NEXT}</td>
                        </tr>
                        <tr>
                            <td class="fontSpecifications">${requestScope.error}</td>
                        </tr>
                    </TABLE>
                    <table>
                        <tr>
                            <td align="center">
                                <input type=submit onclick="setAction('start')" value="Start"></submit>
                                <input type=submit onclick="setAction('suspend')" value="Suspend"></submit>
                                <input type=submit onclick="setAction('resume')" value="Resume"></submit>
                                <input type=submit onclick="setAction('cancel')" value="Cancel"></submit>
                            </td>
                        </tr>
                    </table>
                </form>
            </td>
        </tr>
    </table>
</BODY>
</html>

testJobParams.jsp

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>

<HEAD>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="IBM Software Development Platform">
<META http-equiv="Content-Style-Type" content="text/css">
<TITLE>Test Job Params</TITLE>
<SCRIPT>
    var r = new Array();
    function ok(){
        var date_val = document.getElementById('date').value;
        var time_val = document.getElementById('time').value;
        var int_val = document.getElementById('int_val').value;
        var int_type = document.getElementById('int_type').value;
        r['starttime'] = date_val+' '+time_val;
        r['interval'] = int_val+”+int_type
        window.close();
    }
    function cancel(){
        r['starttime'] = undefined;
    }
    function windiowUnload(){
        window.returnValue = r;
    }
</SCRIPT>
</HEAD>
<BODY onunload="windiowUnload()">
    <form>
    <table width="100%" height="100%">
        <tr>
            <td align="center" valign="middle">
                <table>
                    <tr>
                        <td colspan="2">
                            Enter Date And time to start the job
                        </td>
                    </tr>
                    <tr>
                        <td class="fontSpecifications">Date (dd/MM/yyyy):</td>
                        <td><input type="text" name='date'  size=10 maxlength="10" id='date'/></td>
                    </tr>
                    <tr>
                        <td class="fontSpecifications">Time (HH24:MI):</td>
                        <td><input type="text" name='time' size="5" maxlength="5" id='time'></td>
                    </tr>
                    <tr>
                        <td class="fontSpecifications">Interval:</td>
                        <td>
                            <input type="text" size="4" name='int_val' alt="Enter Numeric Value" id='int_val'>
                            <select name='int_type' id='int_type'>
                                <OPTION value="seconds">Second(s)</OPTION>
                                <OPTION value="minutes">Minute(s)</OPTION>
                                <OPTION value="hours">Hour(s)</OPTION>
                                <OPTION value="days">Day(s)</OPTION>
                                <OPTION value="months">Month(s)</OPTION>
                                <OPTION value="years">Years(s)</OPTION>
                            </select>
                        </td>
                    </tr>
                    <tr>
                        <td colspan="2" align="right">
                            <input type="button" value="Ok" onclick="ok();"/>
                            <input type="button" value="Cancel" onclick="cancel()"/>
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
    </form>
</BODY>
</HTML>
  • Create a servlet TestJob
package com.servlets;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;

import javax.naming.InitialContext;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ibm.websphere.scheduler.BeanTaskInfo;
import com.ibm.websphere.scheduler.Scheduler;
import com.ibm.websphere.scheduler.TaskHandlerHome;
import com.ibm.websphere.scheduler.TaskStatus;

public class TestJob extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
    private static final long serialVersionUID = 9166651663233476722L;

    public TestJob() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String action = request.getParameter("action");
        System.out.println("Action >>---> " + action);
        String status = null;
        String error = "";
        Scheduler scheduler;
        int intStatus = -99;
        boolean isReg = false;
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm");
        try {
            scheduler = (Scheduler) new InitialContext()
                    .lookup("sche/test");// JNDI Name of the scheduler
            Iterator iter = scheduler.findTasksByName("Test Job");
            System.out.println("Size of iter " + iter.hasNext());
            BeanTaskInfo taskInfo = null;
            if (iter.hasNext()) {
                taskInfo = (BeanTaskInfo) iter.next();
                System.out.println(" Next fire time "
                        + taskInfo.getNextFireTime());
                isReg = true;
                intStatus = taskInfo.getStatus();
            }
            if (action != null && action.equals("start")) {
                String startTime = request.getParameter("starttime");
                String interval = request.getParameter("interval");
                System.out.println("St Int >>---> "+startTime+" "+interval);
                Date startDt = dateFormat.parse(startTime);
                if (!isReg) {
                    taskInfo = (BeanTaskInfo) scheduler
                            .createTaskInfo(BeanTaskInfo.class);
                    Object o = new InitialContext()
                            .lookup("ejb/scheduler/TestBeanHome");
                    TaskHandlerHome home = (TaskHandlerHome) javax.rmi.PortableRemoteObject
                            .narrow(o, TaskHandlerHome.class);
                    taskInfo.setTaskHandler(home);
                    taskInfo.setStartTime(startDt);
                    taskInfo.setNumberOfRepeats(-1);//If the value is positive the job will run specified times.
                    taskInfo.setName("Test Job");
                    taskInfo.setRepeatInterval(interval);
                    TaskStatus ts = scheduler.create(taskInfo);
                    System.out.println("Task created with id: "
                            + ts.getTaskId() + " " + ts.getStatus() + " "
                            + ts.getNextFireTime());
                    //return mapping.getInputForward();
                } else {
                    scheduler.cancel(taskInfo.getTaskId(), true);
                    taskInfo = (BeanTaskInfo) scheduler
                            .createTaskInfo(BeanTaskInfo.class);
                    Object o = new InitialContext()
                            .lookup("ejb/scheduler/TestBeanHome");
                    TaskHandlerHome home = (TaskHandlerHome) javax.rmi.PortableRemoteObject
                            .narrow(o, TaskHandlerHome.class);
                    taskInfo.setTaskHandler(home);
                    taskInfo.setStartTime(startDt);
                    taskInfo.setNumberOfRepeats(-1);
                    taskInfo.setName("Test Job");
                    taskInfo.setRepeatInterval(interval);
                    TaskStatus ts = scheduler.create(taskInfo);
                    System.out.println("Task created with id: "
                            + ts.getTaskId() + " " + ts.getStatus() + " "
                            + ts.getNextFireTime());
                }
                intStatus = taskInfo.getStatus();
            }else if (action != null && action.equals("suspend")) {
                System.out.println("Inside Task Suspend Before if");
                if (taskInfo != null) {
                    System.out.println("Inside Task Suspend");
                    TaskStatus taskStatus = scheduler.suspend(taskInfo.getTaskId());
                    System.out.println("Status "+taskStatus.getStatus());
                    intStatus = taskStatus.getStatus();
                }
            }else if (action != null && action.equals("resume")) {
                System.out.println("Inside Task Suspend Before if");
                if (taskInfo != null) {
                    System.out.println("Inside Task Suspend");
                    TaskStatus taskStatus = scheduler.resume(taskInfo.getTaskId());
                    System.out.println("Status "+taskStatus.getStatus());
                    intStatus = taskStatus.getStatus();
                }
            }else if (action != null && action.equals("cancel")) {
                System.out.println("Inside Task Suspend Before if");
                if (taskInfo != null) {
                    System.out.println("Inside Task Suspend");
                    TaskStatus taskStatus = scheduler.cancel(taskInfo.getTaskId(),true);
                    System.out.println("Status "+taskStatus.getStatus());
                    intStatus = taskStatus.getStatus();
                }
            }
            if (intStatus == -99) {
                status = "NOT SCHEDULED";
            } else {
                switch (intStatus) {
                case TaskStatus.SCHEDULED:
                    status = "SCHEDULED";
                    break;
                case TaskStatus.COMPLETE:
                    status = "COMPLETE";
                    break;
                case TaskStatus.INVALID:
                    status = "NOT SCHEDULED";
                    break;
                case TaskStatus.RUNNING:
                    status = "RUNNING";
                    break;
                case TaskStatus.SUSPENDED:
                    status = "SUSPENDED";
                    break;
                case TaskStatus.CANCELLED:
                    status = "CANCELLED";
                    break;
                }
            }
            request.setAttribute("STATUS", status);
            if(taskInfo != null)
                request.setAttribute("NEXT", taskInfo.getNextFireTime().toString());
            System.out.println("Task Status " + status);

        } catch (Exception e) {
            e.printStackTrace();
            error = "Error: "+ e.getMessage();
        }
        request.setAttribute("error", error);
        RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("jsp/testJob.jsp");
        dispatcher.forward( request, response );

    }
}