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.
Related
When scheduling a task in Quartz, you have the ability to set misfires and rescheduling. This could be used in the example scenario whereby there is a job that runs every 30 mins, and potentially there could be a backlog and and the job would execute for longer than 30 mins. To prevent the same job running twice you could use the #DisallowConcurrentExecution. Once complete the job would then execute the second instance that is queued by using simpleSchedule().withMisfireHandlingInstructionNowWithExistingCount().
Now in Spring Scheduler there doesn't appear to be this fine grained ability, with just the fixed-rate and fixed-delay options to schedule it every 30 mins or wait 30 mins after the previous job completed. Without using the hammer route of restricting to a single thread, as I want to increase the thread count for other batch jobs to run concurrently, what would be the best method of recreating the Quartz behaviour?
So it looks like with the basic Spring Scheduler there isn't such a mechanism. To do this either use the Spring Quartz Scheduler, or Quartz directly.
I am looking for a way to specify the duration for a particular task to run - e.g. a particular file cleaner task may not run longer than 2 minutes. If it finishes under 2 minutes - great, but it should terminate after 2 minutes.
Does Quartz or any other library provide some effective way of doing so?
There is no such feature in quartz. You'll have to encapsulate the "timeout manager" in your job implementation.
You should detach the actual job implementation in a separate Task that is managed by the Quartz Job.
Take a look to this example: https://stackoverflow.com/a/2275596/1517816
Assume your QuartzJob is the Test class and move your business logic in the Task class.
Hope it helps
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.
I was wondering if it was possible to schedule a job to start after a job fired by a CronTrigger successfully completes, using Quartz in Java?
From the feature Documentation:
As Jobs are completed, they return a
JobCompletionCode which informs the
scheduler of success or failure. The
JobCompletionCode can also instruct
the scheduler of any actions it should
take based on the success/fail code -
such as immediate re-execution of the
Job.
I think the JobChainingJobListener should be interesting:
Keeps a collection of mappings of which Job to trigger after the completion of a given job.
This is assuming you use the CronJob from quartz of course.
Otherwise you'd need to program (in java) some kind of socket listener, and wrap the cron job in a script which, at the end, triggers Java by writing something on the socket (or pipe, or web service call, whatever you like). Your java code would then trigger the quartz job.