Question : Job Scheduling in Java

Hi,

We've a web-based application running on Apache Tomcat v6.0.10. Of course, reports are also available as part of our application.  Now, we've planned to introduce a new feature in the application called report scheduling.  Using report scheduling, application User's can schedule reports of their choice and get it delivered at their mail box. We want to give User's as much flexibility as they can in scheduling the reports.

I also heard & read about job scheduling in Java at:

Open Source Job Schedulers in Java
http://java-source.net/open-source/job-schedulers

What is Quartz
http://onjava.com/lpt/a/6207

JobServer 1.4 Open Source Java Job Scheduler
http://www.javalobby.org/java/forums/t68751.html

Considering my use case explained above, my questions are:
1) Is it possible to use Sun's own java.util.TimerTask for my complex report scheduling?
2) What are the valid/strong reasons/limitations of java.util.TimerTask compared to other job scheduler frameworks?  So that I myself have a strong belief/reason before choosing  a third-party job scheduler framework.
3) There are a maximum of 100-200 Users in my application.  In case, Users have scheduled reports in such a way at one time there are 100 report requests in the queue.  How does the  job scheduler framework OR java.util.TimerTask handle such scenarios?  Do we have control over this?
4) At any time, Users are allowed to change their report schedules. Does the job scheduler framework support this?
5) Obviously, to run a report there are report inputs, that has to be passed to each report schedule.  Do we have the flexibility/option in passing parameters to the job scheduler framework?
5) Which is the best way? Integrating job scheduler framework with web application or running it as a standalone?

NOTE
Because of memory leak in our application, we've a restart of Tomcat service daily-basis at low-usage time.  Reason I'm explaining this is that report scheduled by Users should be persisted across server/Tomcat restarts.  Take this into consideration.

Experts opinion in right direction are appreciated.

Answer : Job Scheduling in Java

Well I just had a look at one of my applications that uses Quartz (Wrapped by Spring) and on update i unschedule a job and then schedule the changed one.

Here my code for sheduling/unscheduling ... I also have to pass quite some information to the Job, so it's relatively similar to what you need (but keep in mind, that mabe one or the other class is only available when using the Spring Quartz wrapper) ("data" is the real job data, spring-context and job-executer-service are referenced to the Spring context and a service, that I need inside my job)
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
	protected
	void scheduleJob(final SchedulerJob aJob)
	{
        // Create a Job context (Quartz-Object).
        final JobDataMap jobDataMap = new JobDataMap();
        jobDataMap.put("data", aJob);
        jobDataMap.put("spring-context", ctx);
        jobDataMap.put("job-executer-service", jobEcecuterService);

        // Create a Job execution detail (Quartz-Object).
        final JobDetail jobDetail = new JobDetail(aJob.getId(),
                null, DefaultSchedulerExecuter.class);
        jobDetail.setJobDataMap(jobDataMap);

        // Add the jod-definition to the scheduler.
        try {
            schedulerFactory.addJob(jobDetail, true);

            // Create a Quartz trigger to start the job.
            final CronTrigger trigger = new CronTrigger();
            // Set the name to the id.
            trigger.setName(aJob.getId());
            trigger.setJobName(aJob.getId());
            // Start now.
            trigger.setStartTime(Calendar.getInstance().getTime());
            // Schedule as specified in the cron expression.
            trigger.setCronExpression(aJob.getCronExpression());

            if(log.isInfoEnabled()) {
                log.info("[SCHEDULER] - Scheduling Job: " +
                        aJob.getId() + " with executer " +
                        jobDetail.getJobClass().getCanonicalName());
            }

            // Schedule the new Job.
            schedulerFactory.scheduleJob(trigger);
        } catch (final Exception e) {
            if(log.isDebugEnabled()) {
                log.info("Error Scheduling Job " + aJob.getName() + ". Job deactivated.", e);
            }

            // Deactivate the Job, so it is not started automatically again.
            aJob.setEnabled(false);

            // Save the modified job.
            try {
                updateJob(aJob);
            } catch(final Exception ex) {
                throw new RuntimeException(ex);
            }
        }
	}

	protected
	void unscheduleJob(final String aJobId)
	{
    	try {
    		if(schedulerFactory.getJobDetail(
                    aJobId, "DEFAULT") != null) {
				if(log.isInfoEnabled()) {
					log.info("[SCHEDULER] - Unscheduling Job: " +
							aJobId);
				}

				schedulerFactory.deleteJob(aJobId, "DEFAULT");
    		}
		} catch (final SchedulerException e) {
			throw new RuntimeException(
					"Error unscheduling job with id " + aJobId, e);
		}
	}
Random Solutions  
 
programming4us programming4us