Link to home
Start Free TrialLog in
Avatar of snajalm
snajalm

asked on

Forcing Quartz Scheduler to maintain jobs in “job store” even in the case of failed jobs and having them re-run at the specified interval

I'm using the following Quartz Scheduler Task object to run my jobs as follows. For some reason which I think lies in the catch clause, after a series of unsuccessful attempts, my jobs stop rescheduling and they would eventually get wiped out of the job store and at some point freeze the application. Does anyone know how to make this Quarts scheduler run the jobs only once per assigned intervals so that it does not either drop the job or attempts to refire? I used refire immediately since there was no other better handling available upon job failure. How can I assure my jobs remain in the jobs store even when they fail at times and not have to loose them. Could anyone with Quartz experience if I'm going wrong somewhere in this code?

Many Thanks

package IMP;

import IMP.resources.NewPortalConnection;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;
import org.apache.http.NameValuePair;

import java.util.List;
import org.quartz.DisallowConcurrentExecution;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.PersistJobDataAfterExecution;

/**
 * 
 */
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class Task implements Job {

    // parameter names specific to this job
    public static final String DATA_SOURCE_NAME = "data source name";
    public static final String DSN_USERNAME = "dsn username";
    public static final String DSN_PASSWORD = "dsn password";
    public static final String DMZ_USERNAME = "dmz username";
    public static final String DMZ_PASSWORD = "dmz password";
    public static final String DMZ_HOST = "dmz host";
    public static final String DMZ_PORT = "dmz port";
    public static final String QUERIES = "queries";
    public static final String IMPVIEW = "IMPview";

    String FTP_URI;
    String FTP_INITIAL_DIRECTORY;
    List<NameValuePair> ftpParams;
    private static Logger _log = LoggerFactory.getLogger(Task.class);

    /**
     * Empty constructor for job initialization
     */
    public Task() {
    }

    /**
     * <p>
     * Called by the <code>{@link org.quartz.Scheduler}</code> when a
     * <code>{@link org.quartz.Trigger}</code> fires that is associated with
     * the <code>Job</code>.
     * </p>
     * 
     * @throws JobExecutionException
     *             if there is an exception while executing the job.
     */
    public void execute(JobExecutionContext context)
            throws JobExecutionException {

        JobKey jobKey = context.getJobDetail().getKey();
        JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();

        String dataSourceName = jobDataMap.getString(DATA_SOURCE_NAME);
        String dsnUserName = jobDataMap.getString(DSN_USERNAME);
        String dsnPassword = jobDataMap.getString(DSN_PASSWORD);
        String dmzUserName = jobDataMap.getString(DMZ_USERNAME);
        String dmzPassword = jobDataMap.getString(DMZ_PASSWORD);
        String dmzHost = jobDataMap.getString(DMZ_HOST);
        String dmzPort = jobDataMap.getString(DMZ_PORT);
        IMPView view = (IMPView) jobDataMap.get(IMPVIEW);

        view.statusMessageLabel.setText("Running Portal: " + dmzUserName);
        view.statusMessageLabel.repaint();


        try {

            EstablishDMZConnection dmz = new EstablishDMZConnection();

            dmz.userName = dmzUserName;
            dmz.password = dmzPassword.toCharArray();
            dmz.host = dmzHost;
            if (dmzPort != null) {
                dmz.port = dmzPort;
            }

            Connection conn = null;
            conn = NewPortalConnection.getConnection(dataSourceName, dsnUserName, dsnPassword);

            ArrayList<Query> queries = (ArrayList) jobDataMap.get(QUERIES);

            for (int i = 0; i < queries.size(); i++) {

                PreparedStatement pStmt = conn.prepareStatement(queries.get(i).query);
                ResultSet rs = pStmt.executeQuery();

                NewPortalConnection.generateXMLFile(rs, queries.get(i).query_save_name);
                ftpParams = dmz.fetchFTPSettings();

                for (int j = 0; j < ftpParams.size(); j++) {
                    if (ftpParams.get(j).getName().equals("FTPURI")) {
                        FTP_URI = ftpParams.get(j).getValue();
                    }
                    if (ftpParams.get(j).getName().equals("FTPInitialDirectory")) {
                        FTP_INITIAL_DIRECTORY = ftpParams.get(j).getValue() + "/" + dmzUserName;
                    }
                }
                UploadXML.ftp(FTP_URI, dmzUserName, dmzPassword, FTP_INITIAL_DIRECTORY, queries.get(i).query_save_name);
            }

            conn.close();

        } catch (Exception e) {
            _log.info("--- Error in job!");
            JobExecutionException e2 = new JobExecutionException(e);
            e2.refireImmediately();

        }
        _log.info("SimpleJob says: " + jobKey + " executing at " + new Date());
    }
}

Open in new window

Avatar of for_yan
for_yan
Flag of United States of America image

Sorry, I used to use Quartz some time ago, but I used to use Sheduler, SchedulerFarctory, triggers etc.
I see nothing of the kind in your code.
Is it some other  option in Quartz that you are using ?
I'm sure you raed this
http://stackoverflow.com/questions/4408858/quartz-retry-when-failure

and there is a comment down there that this can really freze some of the Quartz thread - see undeder the accepted solution

If you say that you don't care about retrying until next time why would you use this refireImmediately() method which is prone to issues
Avatar of snajalm
snajalm

ASKER

Thanks for_yan,

There is no other form of handling under the JobExecutionException object that would leave the job in the job store for its following turn initially set for that job.  The is option ofr immediate execution or dropping the job.  I'm wondering if I leave the exception clause empty, would it leave the job for its next scheduled execution?  What do you think?
well, I frankly didn't encounter that i  my epsisodic interactions with Quartz,, but if I were writing Quartz, I would have lefty it for next scehdeuled execution - suppose you connect to some host, at some pont it does not respond, but next time it would, why to drop it without special command
I'd have tried  just writing error message into the log in the catch brace and doing nothing elese.
Avatar of snajalm

ASKER

I'll give that a shot and let you know how it went.
ASKER CERTIFIED SOLUTION
Avatar of for_yan
for_yan
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of snajalm

ASKER

Thanks for_yan :-)