I am working on an enterprise application that uses Quartz 2.2.1.
Trigger beans are configured in their XML, which included the relative cron expression.
Now, I have the need of programmatically creating triggers with custom fire times; these triggers also have to handle misfiring (I have to be sure that they get executed, even if the server is down at fire time). Is there a way to make quartz do the 'dirty' work without handling trigger persistency manually?
Thank you.
Easier than I thought, solution lies within the SimpleTrigger class.
// Update trigger infos
SimpleTrigger trigger = (SimpleTrigger)builder
.startAt( whenever you want it to start )
.withSchedule(simpleSchedule()
.withIntervalInMinutes( or any interval ).repeatForever() )
.endAt( whenever you want it to end)
.build()
This creates a quartz trigger living between start and end, and executing following the specified interval.
Misfire strategy can be specified as well.
Related
I have run into a case where I have to use a persistent Scheduler, since I have a web application that can crash or close due to some problems and might lose it job details if this happens . I have tried the following:
Use Quartz scheduler:
I used RAMJobStore first, but since it isn't persistent, it wasn't of much help. Can't setup JDBCJobStore because, this will require huge code changes to my existing code base.
In light of such a scenario,
I have the following queries:
If I use Spring's built in #Schedule annotation will my jobs be persistent..? I don't mind if the jobs get scheduled after the application starts. All I want is the jobs to not lose their details and triggers.?
If not, are there any other alternatives that can be followed , keeping in mind that I need to schedule multiple jobs with my scheduler.?
If yes, how can I achieve this.? My triggers are different each job. For e.g I might have a job that is scheduled at 9AM and another at 8.30AM and so on.
If not a scheduler, then can I have a mechanism to handle this.?
One thing, I found is that the documentation for Quartz isn't very descriptive. I mean it's fine for a top level config, but configuring it on your an application is a pain. This is just a side note. Nothing to do with the question.
Appreciate the help. :)
No, Spring's #Schedule-annotation will typically only instruct Spring at what times a certain task should be scheduled to run within the current VM. As far as I know there is not a context for the execution either. The schedule is static.
I had a similar requirement and created db-scheduler (https://github.com/kagkarlsson/db-scheduler), a simple, persistent and cluster-friendly scheduler. It stores the next execution-time in the database, and triggers execution once it is reached.
A very simple example for a RecurringTask without context could look like this:
final RecurringTask myDailyTask = ComposableTask.recurringTask("my-daily-task", Schedules.daily(LocalTime.of(8, 0)),
() -> System.out.println("Executed!"));
final Scheduler scheduler = Scheduler
.create(dataSource)
.startTasks(myDailyTask)
.threads(5)
.build();
scheduler.start();
It will execute the task named my-daily-task at 08:00 every day. It will be scheduled in the database when the scheduler is first started, unless it already exists in the database.
If you want to schedule an ad-hoc task some time in the future with context, you can use the OneTimeTask:
final OneTimeTask oneTimeTask = ComposableTask.onetimeTask("my-onetime-task",
(taskInstance, context) -> System.out.println("One-time task with identifier "+taskInstance.getId()+" executed!"));
scheduler.scheduleForExecution(LocalDateTime.now().plusDays(1), oneTimeTask.instance("1001"));
See the example above. Any number of tasks can be scheduled, as long as task-name and instanceIdentifier is unique.
#Schedule has nothing to do with the actual executor. The default java executors aren't persistent (maybe there are some app-server specific ones that are), if you want persistence you have to use Quartz for job execution.
I'm making use of Quartz Scheduling and there are 2 jobs. First Job is performing the tasks for around 2 minutes and the Second one is to be setup for Cleaning Operations of Temporary Files. So, I need to setup the Schedule to work in a way that after the first job is executed/finished performing tasks I need to do the cleaning operations with the help of Second Job.
Considering the Example 9 - Job Listeners under Quartz 2.1.x which states that we can define a method named jobWasExecuted( _, _ ); in the Job Listener and it executes when the 1st job is executed/or comes in running state.
Are we able to setup the schedule which can listen for the first job finishing then executes second? or,
Are we able to define the join() method like in Java Multithreading which can execute on the completion of first job?
There currently is no "direct" or "free" way to chain triggers with
Quartz. However there are several ways you can accomplish it without
much effort. Below is an outline of a couple approaches:
One way is to use a listener (i.e. a TriggerListener, JobListener or
SchedulerListener) that can notice the completion of a job/trigger and
then immediately schedule a new trigger to fire. This approach can get
a bit involved, since you'll have to inform the listener which job
follows which - and you may need to worry about persistence of this
information.
Another way is to build a Job that contains within its JobDataMap the name of the next job to fire, and as the job completes (the last step in its Execute() method) have the job schedule the next job. Several people are doing this and have had good luck. Most have made a base (abstract) class that is a Job that knows how to get the job name and group out of the JobDataMap using special keys (constants) and contains code to schedule the identified job. Then
they simply make extensions of this class that included the additional
work the job should do.
Ref: http://www.quartz-scheduler.net/documentation/faq.html#how-do-i-chain-job-execution?-or,-how-do-i-create-a-workflow?
I know this is an old question, but nevertheless there are 2 more options available to chain the execution of your jobs which people can find useful:
1) Use the JobChainingJobListener that is included in the standard Quartz distribution since very early releases. This listener allows you to programmatically define simple job chains using its addJobChainLink method.
2) Use a commercial solution such as QuartzDesk that I am the principal developer of. QuartzDesk contains a robust job chaining engine that allows you to externalize the definition of your job chains from the application code and enables you to update your job chains at runtime through a GUI without modifying, redeploying and restarting your application. A job chain can be associated with a particular job, trigger or it can be a global job chain that is executed whenever any of your jobs execute (useful for global job execution failure handlers etc.).
From http://www.quartz-scheduler.net/documentation/faq.html#how-do-i-chain-job-execution?-or,-how-do-i-create-a-workflow
How do I keep a Job from firing concurrently?
Quartz.NET 2.x
Implement IJob and also decorate your job class with
[DisallowConcurrentExecution] attribute. Read the API documentation
for DisallowConcurrentExecutionAttribute for more information.
The annotation is available in the Java implementation.
Quartz API provide a way in which i can create a Job and add it to scheduler for future use by doing something like
SchdularFactory.getSchedulerInstance().addJob(jobDetail, false);
This provides me the flexibility to create jobs store them with the scheduler and use them in later stage.
i am wondering is there any way i can create triggers and add them to scheduler to be used in future.
Not sure if this is valid requirement but if its not possible than all i have to do is to associate the Trigger with any given/existing Job
In Quartz there is a one-to-many relationship between jobs and triggers, which is understandable: one job can be run by several different triggers but one trigger can only run a single job. If you need to run several jobs, create one composite job that runs these jobs manually.
Back to your question. Creating a job without associated triggers is a valid use-case: you have a piece of logic and later you will attach one or more triggers to execute it at different points in time.
The opposite situation is weird - you want to create a trigger that will run something at a given time, but you don't know yet what. I can't imagine use-case for that.
Note that you can create a trigger for future use (with next fire time far in the future), but it must have a job attached.
Finally, check out How-To: Storing a Job for Later Use in the official documentation.
I am using EJB 3.0 Timers in my application.
One thing about EJB Timers is that they are by default persistent which means that when ever there is server restart the Timers will automatically be invoked with out calling them again.
I have a requirement that these timers should be manually be started when ever server is restarted. For this I know we need to change some attribute in config XML which I don't know exact.
Where do I need to change the attribute to set persistent=false.
I am using Weblogic Server.
In EJB 3.0 timers are persistent and there is no attribute to set to make them non-persistent. Possibility to affect this came with EJB 3.1 TimerConfig. Also WebLogic specific configuration does not provide any help.
Create a programmatic Timer (#Timeout Method needed)
TimerConfig timerConfig = new TimerConfig("some info ...", false);
timerService.createIntervalTimer(3000, 1000, timerConfig);
or create automatic timer: just annotate a method with #Schedule:
#Schedule(hour = "*", minute = "*", second = "*", persistent = false)
private void myScheduledMethod(Timer timer) {
// ...
}
For this to work, you need to use EJB 3.1 or higher, that means you need a Java EE 6 (or higher) Server, or container supporting this ejb version.
For Weblogic use need at least the version 12cR1.
If this did not help, i would suggest to cancel all Timers at shutdown, i.e. in the #PreDestroy method of the corresponding bean.
I hope, i could help.
This thread is old, but I think the concerns still apply nowadays.
There is an attribute since EJB 3.1 to specify EJB persistency, as #mikko-maunu indicated, yet I've perceived it was modeled with two responsibilities:
to have the schedule configuration persist after system reinitialization;
to refire all eventually misfired triggers at system initialization.
I think the concepts above should have been modeled independently, so we could have a EJB timer stored on a database, and also have finer control over what to do with misfired triggers at system reinitialization, i.e. should them be retriggered or ignored.
Otherwise, it would seem awkward having a EJB Timer based job module where some of them are stored in a DB and others are not, just because we don't want to refire previous missed triggers for a job scheduled too frequently, running at an hourly basis, for example.
I've noticed, in JBoss 7.1 / Java EE 7, that keeping the schedule information in a database can potentially support a central control for a clustered configuration, instead of having repeated and independent instances of non-persistent time schedules. But the colateral effect is having, for a job triggered many times a day, all eventially misfired triggers fired at once at system reinitialization.
To have finer control over a persistent EJB Timer at restart time, we could, at the #PostConstruct method, check if the timer's getNextTimeout() is a past time. If the timer should ignore misfired triggers, we could cancel the old timer and immediately create a new one, using the same scheduleExpression, so only future triggers will be considered. This seems very useful for timers scheduled to run many times a day.
Another possible, maybe simpler approach is, in the #Timeout method, check if the timer's next execution time, getNextTimeout(), is before the current date and time, and then decide if previous, misfired triggers should be treated or discarded.
I'm scheduling quartz job dynamically and one of the issue that I came across is, I couldnt find an option to programmatically set the job to "PersistJobDataAfterExecution" and "DisallowConcurrentExecution" as both are annotation. Can any of you please suggest whats the equivalent while scheduling a job programmatically ( not declarative )
Since you are scheduling dynamically you should be passing a JobDetail to the Scheduler. You should be able to create your own JobDetail implementation or extends the base implementation then return whatever you want for the corresponding methods.