I am implementing Quartz scheduler with JDBC JobStore in Spring. I have a use case, where if my application crashes and it has jobs to be executed within time frame between the crash and restart of the scheduler. My approach is to compare nextExecutionTime for all jobs with the current time at startup of the scheduler and if the nextExecutionTime is less than the current time, execute the job.
But I have a strong notion that there is a nicer way to get this job done. Either supported by Quartz or already implemented by someone. Can you suggest a better approach for this?
Does the misfire instruction feature do what you want? See the tutorial at Quartz Tutorial Lesson 4 and more specifically Example - Job Misfires You probably need to call withMisfireHandlingInstructionFireNow() when you build your trigger.
Related
Can anybody help me with scheduling cron jobs with a help of Hazelcast? I know that Hazelcast has IScheduledExecutorService, but I can't find a way to schedule cron task (only delayed or interval jobs).
Hazelcast doesn't have that kind of functionality. You need to use a 3rd party system like quartz scheduler.
I'm using Quartz together with Spring. The JobStore that I'm using is the RAMJobStore.
I create a couple of jobs with the same identification (they have the same instance definition (JobDetail)). Because I want to make sure that these jobs aren't executed in parallel, I annotated their job class with #DisallowConcurrentExecution.
My problem is that the RAMJobStore doesn't allow more than one job with the same identification in the same time in the store, so when I try to add the job I get the exception:
org.quartz.ObjectAlreadyExistsException: Unable to store Job :
'jobX', because one already exists with this identification.
Do you have any idea about how I can overcome this problem?
Thanks a lot!
If you have two different jobs that are running on two different triggers, then I'm not aware of any Quartz annotations that would prevent the two jobs from running in parallel. You could reference the Scheduler instance in each of the jobs to determine if the other job is executing. Then you could pause or reschedule jobs to prevent them from running in parallel.
It is clear from the RAMJobStore source code that there can't be two jobs with the same key in the same time in the RAMJobStore.
Have a look here at the source code.
In my application I need to have periodically run background tasks (which I can easily do with Quartz - i.e. schedule a given job to be run at a specific time periodically).
But I would like to have a little bit more control. In particular I need to:
have the system rerun a task that wasn't run at its scheduled time (i.e. the server was down and because of this the task was not run. In such a situation I want the 'late' task to be run ASAP)
it would be nice to easily control tasks - i.e. run a task on demand or see when a given task was last run or reschedule a given task to be run at a different time
It seems to me that the above points can be achieved with Spring Batch Admin, but I don't have much experience in this area yet. Also, I've seen numerous posts on how Spring Batch is not a scheduling tool so I'm becoming to have doubts what the right tool for the job is here.
So my question is: can the above be achieved with Spring Batch Admin? Or perhaps Quartz is enough but needs configuring to do the above? Or maybe I need both? Or something else?
Thanks a lot :)
Peter
have the system rerun a task that wasn't run at its scheduled time
This feature in Quartz is called Misfire Instructions and does exactly what you need - but is a lot more flexible. All you need is to define JDBCJobStore.
it would be nice to easily control tasks - i.e. run a task on demand or see when a given task was last run or reschedule a given task to be run at a different time
You can use Quartz JMX to access various information (like previous and next run time) or query the Quartz database tables directly. There are also free and commercial management tools basex on the above input. I believe you can also manually run jobs there.
Spring Batch can be integrated with Quartz, but not replace it.
For a system monitoring Java application which currently runs on the command line and uses ScheduledExecutorService, I would like to write a simple web application version, to be run in a Servlet container like Apache Tomcat or Eclipse Jetty.
I have read about Quartz as one of the popular job schedulers for web applications. Would it be better (maybe because of better servlet container integration) to port this application from ScheduledExecutorService to Quartz?
Adding another library dependency to the application is not a problem, I am interested in technical reasons against usage of ScheduledExecutorService.
It depends on what you are using it for.
Quartz is useful for programmed times e.g. every hour on the hour.
ScheduledExecutorService is useful for repeating tasks which don't have to occur at a specific time. Its simpler and possibly more efficient. If you have this working it indicates to me that you don't need Quartz.
ScheduledExecutorService operates at a lower level and you'd have to implement all scheduling monitoring/maintenance facilities yourself.
Quartz has tons of facilities such as Job Persistence, Transactions, Clustering etc.
Java's Executor solution allows you to either:
immediately run a task
start a task after an initial delay (and optionally rerun the task after subsequent delay cycles).
But Quartz empowers you with incredible flexibility on when and how often to run a task/job. For example, one schedule during the Mon-Fri work week and something else (or not at all) during the weekends. Or on the last day of the month and you don't have to figure out if a given month's last day is on the 28th, 29th, 30th, or 31st. Here's some more examples of the flexibility the cron style scheduling accommodates - http://www.quartz-scheduler.org/documentation/quartz-2.x/tutorials/crontrigger.html#examples
Using Java's library is easier but for anyone that wants a jump start into a bare-bones codebase example of Quartz working, I've put this template together for free download usage - https://github.com/javateer/quartz-example
I am using quartz scheduler in my spring project. I have to run a job after another job which is scheduled to run in every 15 mins? I cant run this job concurrently as both of this jobs have to access same mail account using different protocols(one to send:smtp and other to receive: imap) and it may cause problems. Please reply quickly, as its an urgent requirement.
Just write a wrapper job class that launches second job after the first. You could then reuse separate jobs in the future if there will be any necessity.
You could do something with writing a job listener to recognize when the first job ends, and have it start the second. But the solution first suggested by mindas is easier - wrap both your jobs in another Job implementation, which is the one you actually schedule.