How to make an application with scheduler (Quartz) manually testable? - java

We're building a financial application with quite a lot of scheduled processing. We want to make manual testing of the application easy, but because most of the processes take months to finish, we need to give testers an option to move the current date forward.
It's not a problem to fake current date for all of our business services, because all of them access date indirectly through a "TimeService". The problem we run into is with the scheduler (Quartz). It's not possible to move scheduler's current date into the future (nor past, but that just doesn't make much sense). I understand it's probably not the best idea to mess with Scheduler's current time when it's running, but if you could start the scheduler with an offset time interval relative to current date, there should be no logical problem with that - Quartz should just find all missed executions and handle them according to configured misfire instructions.
So to be a little more specific in this general design question:
Is it possible to fake current date for Quartz?
If not, what's the way you design this "magic time button for testers" that takes the application to the future? Especially regarding scheduled tasks...
Just to be clear - we're not having problems with our automatic tests (no need for scheduler there) and we're not trying to test the scheduler itself.

I'll just highlight the solution we ended up implementing for other people that might be interested. In the end, we did not use Quartz in the development environment at all. Scheduler is only running in the production configuration (where it's obviously not possible to shift time). Then we have a special piece of code that launches daily processing for every day when shifting time (which is only present in development / test environment).
The bottom line for us: don't try to combine scheduler & moving time into the future - create separate configuration with one XOR another with special logic to replace scheduler in the scheduler-less configuration.

Your only real option is to advance the system's time before starting the scheduler.

Related

How to make sure one time running quartz job will be executed even if server is not up at that time?

I have a situation that specific quartz job must execute only once at specific time of day.
I want to know if there is a workaround to make sure this job will be executed even if server for any reason does not up and running at that point of time.
If i switch from ramjobstore to database does this guaranty the mentioned problem?
EDIT:
To make things clear i use the #Vala. D comment:
if the server was down at this time to run it immediately after server-start
This behavior will cover my requirements

Run a Web Service at a Particular time of the day EveryDay (Get time From Tomcat parameters )

I have a requirement to send SOAP message to lot of devices everyday at a certain time. I will get the time from a tomcat parameter in web.xml. Something like;
<context-param>
<param-name>DailyTime</param-name>
<param-value>04:00</param-value>
</context-param>
I must create a separate thread that sends the messages. Time will be in 24-hrs format.
The problem is, as a starter i have no idea where to start or how to do it. Can you guys please point me in the right direction or give me some tips, which will help me greatly.
Thank You Everyone :)
You have several options. The two I've used most in the past are:
1) Schedule a cron job to run at the time(s) you want, and have it call an executable java class / jar file.
2) Use a scheduler library like Quartz
Regarding #1 - this assumes you're using a *nix system. If you're using Windows, you can schedule tasks through the Task Scheduler.
Regarding #2 - this gives you more flexibility on the conditions of running a task/job. For example, you could schedule a job to run every 1 minute, but not to start a new job until any existing job is complete.
Anecdotal remark from a version of Quartz circa 2006 - on WebSphere, it seems that my quartz jobs were getting executed by some background thread that made jobs take hours which should have only taken a few seconds. But that was almost a decade ago, and certainly quartz (and hopefully websphere) have vastly improved.

Task scheduling for multiple tasks in java?

i have build a java clock with using timer,which works fine for a single task to alarm on next given/setted time, but i am having problem in scheduling multiple tasks(alarms for diff. times) with this timer, as two times can clash each other(same times for two different works) how to synchronize between such conditions, please help....
Thanks and Regards
Alok Sharma
I'm not sure what you're trying to do, but if you use quartz scheduler, you can resolve just about any scheduling/synchronisation task:
http://www.quartz-scheduler.org/
I agree with Lukas that you can use quartz. It is the best, scalable and robust solution.
But if you need something relatively small you can continue using timer based solution. As javadoc of Timer class indicates your tasks should take very few time. In this case you can forget about time clash. If your tasks take more then 0.1 seconds run them in separate thread. I mean use Timer as a trigger that just makes task to start in separate thread.
The thread may be done as following:
Create thread yourself. If you are in J2EE container it is bad practice. If you are in Tomcat it is ... not so bad.
Use thread pool. Comments about container are relevant here too.
Use JMS: Timer just pushes message to JMS. MDB or its equivalent receives message and performs task.
Using Timer itsef in J2EE container is a bad practice too. If you are there and wish to be "clean" use JCA to to run Timer.

How to schedule an action in java?

I'm developing an application which requires Contents of the database to be written to an ms-excel file at the end of each day. I've written the code for copying the contents into ms-excel file but Now how to proceed further? Whether threads are to be used to check for the completion of 24 hours or there's some other mechanism? Please provide me some guidance.
If you need to facility to run things at set times during the day, you should consider the Quartz Scheduler. It might be overkill, but it's very capable.
For example, you can use its CronTrigger to configure a job to run on a schedule defined by a cron expression, e.g. 0 23 55 * * ? (or something like that) would run your job at 5 to midnight every night (see examples).
Quartz recently got a boost to its future and fortunes by being acquired by the Terracotta folks. Hopefully it'll get some real active development now.
I agree with the others that using something like crontab would be better. However, if you can't do that, I would use the java.util.concurrent package added in Java 1.5. The class you would need is ScheduledThreadPoolExecutor. Specifically, the scheduleAtFixedRate() method.
I think that from the design perspective it is better to use crontab on linux platform or task scheduler on windows platform. It will keep your java program small, and simple. While the solution with thread waiting for the specific time seems simple it will add one serious concern - you will have to monitor its health.
In addition - I would suggest to carefully plan logs your job is writing each time it is run. It is important to have logs for both successful and unsuccessful runs.
It makes sense to make separate file for such logs.
One more case to be considered - what to do if database was not available exactly in the time when job run? Is it acceptable to wait another 24 hours?

Running a regular background event in Java web app

In podcast #15, Jeff mentioned he twittered about how to run a regular event in the background as if it was a normal function - unfortunately I can't seem to find that through twitter. Now I need to do a similar thing and are going to throw the question to the masses.
My current plan is when the first user (probably me) enters the site it starts a background thread that waits until the alloted time (hourly on the hour) and then kicks off the event blocking the others (I am a Windows programmer by trade so I think in terms of events and WaitOnMultipleObjects) until it completes.
How did Jeff do it in Asp.Net and is his method applicable to the Java web-app world?
I think developing a custom solution for running background tasks doesn't always worth, so I recommend to use the Quartz Scheduler in Java.
In your situation (need to run background tasks in a web application) you could use the ServletContextListener included in the distribution to initialize the engine at the startup of your web container.
After that you have a number of possibilities to start (trigger) your background tasks (jobs), e.g. you can use Calendars or cron-like expressions. In your situation most probably you should settle with SimpleTrigger that lets you run jobs in fixed, regular intervals.
The jobs themselves can be described easily too in Quartz, however you haven't provided any details about what you need to run, so I can't provide a suggestion in that area.
As mentioned, Quartz is one standard solution. If you don't care about clustering or persistence of background tasks across restarts, you can use the built in ThreadPool support (in Java 5,6). If you use a ScheduledExecutorService you can put Runnables into the background thread pool that wait a specific amount of time before executing.
If you do care about clustering and/or persistence, you can use JMS queues for asynchronous execution, though you will still need some way of delaying background tasks (you can use Quartz or the ScheduledExecutorService to do this).
Jeff's mechanism was to create some sort of cached object which ASP.Net would automatically recreate at some sort of interval - It seemed to be an ASP.Net specific solution, so probably won't help you (or me) much in Java world.
See https://stackoverflow.fogbugz.com/default.asp?W13117
Atwood: Well, I originally asked on Twitter, because I just wanted something light weight. I really didn't want to like write a windows service. I felt like that was out of band code. Plus the code that actually does the work is a web page in fact, because to me that is a logical unit of work on a website is a web page. So, it really is like we are calling back into the web site, it's just like another request in the website, so I viewed it as something that should stay inline, and the little approach that we came up that was recommended to me on Twitter was to essentially to add something to the application cache with a fixed expiration, then you have a call back so when that expires it calls a certain function which does the work then you add it back in to the cache with the same expiration. So, it's a little bit, maybe "ghetto" is the right word.
My approach has always been to have to OS (i.e. Cron or the Windows task scheduler) load a specific URL at some interval, and then setup a page at that URL to check it's queue, and perform whatever tasks were required, but I'd be interested to hear if there's a better way.
From the transcript, it looks like FogBugz uses the windows service loading a URL approach also.
Spolsky: So we have this special page called heartbeat.asp. And that page, whenever you hit it, and anybody can hit it at anytime: doesn't hurt. But when that page runs it checks a queue of waiting tasks to see if there's anything that needs to be done. And if there's anything that needs to be done, it does one thing and then looks in that queue again and if there's anything else to be done it returns a plus, and the entire web page that it returns is just a single character with a plus in it. And if there's nothing else to be done, the queue is now empty, it returns a minus. So, anybody can call this and hit it as many times, you can load up heartbeat.asp in your web browser you hit Ctrl-R Ctrl-R Ctrl-R Ctrl-R until you start getting minuses instead of pluses. And when you've done that FogBugz will have completed all of its maintenance work that it needs to do. So that's the first part, and the second part is a very, very simple Windows service which runs, and its whole job is to call heartbeat.asp and if it gets a plus, call it again soon, and if it gets a minus call it again, but not for a while. So basically there's this Windows service that's always running, that has a very, very, very simple task of just hitting a URL, and looking to see if it gets a plus or a minus and, and then scheduling when it runs again based on whether it got a plus or a minus. And obviously you can do any kind of variation you want on this theme, like for example, uh you could actually, instead of returning just a plus or minus you could say "Okay call me back in 60 seconds" or "Call me back right away I have more work to be done." And that's how it works... so that maintenance service it just runs, you know, it's like, you know, a half page of code that runs that maintenance service, and it never has to change, and it doesn't have any of the logic in there, it just contains the tickling that causes these web pages to get called with a certain guaranteed frequency. And inside that web page at heartbeat.asp there's code that maintains a queue of tasks that need to be done and looks at how much time has elapsed and does, you know, late-night maintenance and every seven days delete all the older messages that have been marked as spam and all kinds of just maintenance background tasks. And uh, that's how that does that.
We use jtcron for our scheduled background tasks.
It works well, and if you understand cron it should make sense to you.
Here is how they do it on StackOverflow.com:
https://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/

Categories