I want to know the best method to schedule a code. I have a code that generates reports and sends mail to a set of people at interval of 24hrs. Its a console based java application. I want to know the best method to schedule that. Sometimes I may need to change that to 12hrs interval. However the application doesn't perform any other task in between the interval.
Here are few approach, from simplest to most comprehensive:
sleep():
TimeUnit.HOURS.sleep(24)
This approach is very simple, do the work and sleep for 24 hours. Actually it is a bit more complex because the report generation takes some time, so you have to sleep slightly shorter. All solutions below handle this transparently.
java.util.Timer#scheduleAtFixedRate() - simple, built-in Java solution.
#Scheduled annotation in spring or #Schedule in ejb - more complex but also more powerful, e.g. accepts cron expressions:
#Scheduled(fixedRate=DateUtils.MILLIS_PER_DAY)
public void generateReport() {
//...
}
quartz-scheduler - full blown Java scheduler with clustering and fail-over, misfire handling, full cron support, etc. Very comprehensive:
newTrigger().
withSchedule(
simpleSchedule().
withIntervalInHours(24).
repeatForever()
).build();
or
newTrigger().
withSchedule(
cronSchedule().
dailyAtHourAndMinute(17, 30). //17:30
).build();
I am using two ways:
First for non managed code like client code:
Chron4J
Second is implmented in the JavaEE framewoks. You can use it via annotating methods when you use an container like Glassfish/JBoss. Would be something like this:
#Schedule(second="*/1", minute="*",hour="*", persistent=false)
public void doWork(){
System.out.println("timer: " + helloService.sayHello());
}
I would take a look at the quartz scheduler if I were you.
I used in a number of applications and it's really easy to use.
You can find more information here: http://quartz-scheduler.org/
If you use the spring stack I would surely recommend it, since it is super easy to configure in xml and let spring inject all the stuff for you.
Well, if the program can be idle try something like this
try
{
for (;;) {
//code
Thread.sleep(1000 * 60 * 60 * 24);
//code
}
}
catch(Exception e)
{
System.out.println(e);
}
Related
I have a few APIs I'm trying to thoroughly integration test -- I'm hitting the remote service which is running in a test environment (not the same box that is running the tests, the tests make real service calls), I can't just use dependency injection to solve all my problems. We already have a good suite of unit tests on these classes.
The API I'm testing is SaveThingy. It saves a Thingy if it's valid, and returns you the id of it. One of the checks is that you can only save a thingy at certain times, say only on weekdays. If you call SaveThingy on the weekend, it insults you personally instead of saving a Thingy. The implementation looks something like the following
ThingyId saveThingy(Thingy thingy) {
if (isWeekend(LocalDate.now().getDayOfWeek())) {
throw new PersonalInsultException("your mother wears army boots");
}
return thingyDao.save(thingy);
}
I'd ideally like to have both cases tested each time we run integration tests, without any waiting. In some code, I want tests similar to the following to run each time.
#Test
public void saveThingy_validThingyOnWeekday_savesThingy() {
ThingyId id = serviceUnderTest.saveThingy(THINGY);
assertThat(serviceUnderTest.getThingyById(id)).isEqualTo(THINGY);
}
#Test(expected = PersonalInsultException.class)
public void saveThingy_validThingyOnWeekend_receivePersonalInsult() {
serviceUnderTest.saveThing(THINGY);
}
Are there any standard ways that allow complete testing of such APIs? I've considered a few options (below), but wanted to get additional opinions.
say no to integration testing, live with only unit tests for these APIs
change the remote clock, either using a private API or by literally ssh-ing into the host before running each test
write tests that are time dependent; only testing one of the possible behaviors, or testing one behavior then sleeping until other conditions are met
invent dummy data that will always save or always throw an exception
I suppose in your ThingyService class you have a public
or protected isWeekend method. Probably something like this:
public boolean isWeekend(DayOfWeek dayOfWeek) {
return dayOfWeek == DayOfWeek.SATURDAY || dayOfWeek == DayOfWeek.SUNDAY;
}
In your ThingyServiceTest you can then create two specialized ThingyService instances with mocked isWeekend methods.
In your test-cases you can use either of these:
// service with weekday behavior
private ThingyService serviceUnderTest_weekday = new ThingyService() {
#Override
public boolean isWeekend(DayOfWeek dayOfWeek) {
return false;
}
};
// service with weekend behavior
private ThingyService serviceUnderTest_weekend = new ThingyService() {
#Override
public boolean isWeekend(DayOfWeek dayOfWeek) {
return true;
}
};
#Test
public void saveThingy_validThingyOnWeekday_savesThingy() {
ThingyId id = serviceUnderTest_weekday.saveThingy(THINGY);
assertThat(serviceUnderTest_weekday.getThingyById(id)).isEqualTo(THINGY);
}
#Test(expected = PersonalInsultException.class)
public void saveThingy_validThingyOnWeekend_receivePersonalInsult() {
serviceUnderTest_weekend.saveThing(THINGY);
}
You are trying to achieve black box testing with white box testing requirements: it's simply not possible. Stick to white box testing and mock out your DateProvider locally. Maybe not what you want to hear but you will waste so much time otherwise trying to align the stars to produce the output you want in your assertion.
Now on the other hand if you really want to do this run your application inside a docker container and change the system clock then just tear it down between tests.
Alternatively open up a separate endpoint which allows to specify the current time via your service and only deploy this endpoint when you are testing. Or have a configuration interface responsible for determining the source of your current time and when you deploy to your test environment configure the app accordingly.
Instead of using LocalDate.now() or Instant.now() or Whatever.now() or passing long timestamps, consider adding java.time.Clock field to your class, and either add an initialization parameter to constructor or provide a setter.
Clock.instant() is essentially Instant.now(), and you can convert the instant into any other temporal class.
In production, you will use Clock.systemUTC() as the value of that field.
In some tests, you can use Clock.fixed(), and in all tests you can just mock the way you need it for tests.
This approach is mostly suited for unit tests. You can still inject your custom Clock implementation in integration environment, so that the application as a whole will think that the current time is whatever you need.
currently, I have a web application based on Java 7, tomcat 7 and Spring 4 that invokes a thread on tomcat startup.
This thread is always alive and the java code is:
public class Scheduler {
Queue<Long> queue = new ArrayBlockingQueue<Long>();
private static class ThreadExecutor implements Runnable
{
.......
#Override
public void run()
{
while(true)
{
Long ID = queue.get();
if(ID != null)
{
Object o = webFacade.get(ID);
//Exec....
}
else
{
try
{
Thread.sleep(30000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
}
An external event fills the queue with the Object's ID.
With one tomcat this thread works well, but now I nedd to add onother tomcat, so I want to introduce Quartz in clustered mode.
I've configured Quartz in my project and it seems to work, but now how can I "translate" this class using Quartz?I want that only one thread is active because it is very expensive for my Database.
Thanks in advance
In general Quartz while being run in a cluster mode guarantees that the job will be triggered (and handled) on one server only.
So Job will be the task that you execute (in other words, what should be executed).
Now Quartz also introduces the concept of Trigger which basically defines when the job will be triggered.
From your code snippet, you run the job every 30000 ms = 30 seconds. So you'll trigger your stuff every 30 seconds (SimpleTrigger will do the job).
So, the 'while' loop goes away, it will be handled by quartz automatically.
In job you'll only work with a queue. Its unclear who fills this queue, but it looks like a different question.
It's hard to say exactly how you translate the queue, but in general job should
Get from queue
Call webFacade just like now
That's it. Last but not the least, Spring has a beautiful integration with Quartz. See Chapter 33.6.
My application file (EAR) consists of combination of EJB and WAR. FrameWork is JSF and IDE is Netbeans 6.9.1 applition server is glassfich V2.x. I want to calculate the execution time fro each and every invoked method in my application. i have gone through so many blogs. most of them suggested to use AOP. but nobody tell me how to configure and how to use it in my application. could anybody tell me ragarding this. I have some code here and i made use of AOP and JAMon to calculate the method execution time. but i confused about how to configure this because for every method invocation this calss should be invoked for that what to do i dont know. could anybody give some suggestions on it.If you any additional details to answer this i will provide. Code is:
public class PerformanceMonitorIncptr implements MethodInterceptor{
/** Creates a new instance of PerformanceMonitorIncptr */
public PerformanceMonitorIncptr() {
}
public Object invoke(MethodInvocation mi) throws Throwable {
String mName = mi.getMethod().getDeclaringClass().getName() + "." + mi.
getMethod().getName();
Monitor mon = MonitorFactory.start(mName);
// long l = System.currentTimeMillis();
Object returnValue = null;
try {
returnValue = mi.proceed();
} finally {
mon.stop();
System.out.println(mon);
}
System.out.println(mName);
// System.out.println(l - System.currentTimeMillis());
return returnValue;
}
}
AOP is best suited here.
You need to configure #PointCut #Around each method you want to log the time of execution
Have a look at this tutorial .
Update
I hope 20 methods you are talking about /can be are Spring Service methods, and you don't need to alter them at all you just need to configure a #Aspect that will involve all the methods. read more
AOP is the solution.
But why would you write it yourself.
Use Javamelody -> EJB configuration documentation.
We use it with Spring, and it's great. There are also such solutions as AppDynamics, DynaTrace, NewRelic, JXInsight, CorrelSense, Nastel.
As for me Javamelody is free, opensource and very easy to use.
I have a method which opens a web service session. The method structure looks something like this:
public Soap getServicePort()
{
//TODO: Open a connect and return the SOAP object
return soap;
}
I have a requirement to add a monitor straight after the return. The monitor's job is to wait for 2hrs and in-activate the session and rebuild a new one - well reason been the current session will be invalid at that time and therefore we need to rebuild and return a new session.
Can anyone suggest a reasonable way of doing this?
Thanks.
public Soap getServicePort()
{
try {
return soap;
} finally {
// add monitor here.
}
}
But be careful: monitor should not throw exceptions. Put its initiation ito try/catch.
Probably better solution is wraper pattern. For example you can define interface with method getServicePort() and 2 implementations: one your real implementation and other that wraps real and adds monitor. This solution is more flexible. For example probably you will have to create your monitor afeter other methods and even after other methods implemented in other classes.
In this case you can use AOP. There are several ways to use it. One is using Dynamic Proxy of java. Other is using special tools like AspectJ.
So, choose your solution. Your choice should depend on the complexity of your task and number of methods/classes that required to implement this functionality. If it is only one method use try/finally, if it is several methods in the same class, use wrapper pattern. If it is required for several methods in several classes use Proxy or AspectJ.
You can try logic like this.. no need to have monitor on this
private Soap soap = null;
public Soap getServicePort()
{
try {
if(soap!=null && soap.isValide()){
// not sure about the method isValide(), some condition to check session
return soap;
}else{
// create new soap & return
return soap;
}
} catch(Exception e){
}// END Catch
}// END MEthod
Call the method as many times as you want...
I have a bean that has a method executed on a schedule using <task:scheduled> in the context configuration.
Is there a way for me to find the time of the next scheduled run during execution of that method?
The same method is also executed manually, and the mechanism for receiving scheduler information may not break executions from outside the scheduler...
The <task:scheduled> configuration style is a convenient shortcut on to underlying Spring factory beans that generate schedulers and schedules. As a convenience, it's useful, but is much less flexible than using the underlying scheduler factories directly.
Having said that, the schedulers themselves would need to expose the "next fire time" information via their API, and that's implementation-dependent. For example, I don't see a way to get this information from the standard ScheduledExecutorService implementations.
Quartz, however, does expose this, via the getNextFireTime() method on the Trigger class.
If you're willing to abandon <task:scheduled> and use the Quartz-Spring integration directly, then you can get access to the Trigger (or TriggerBean) and get what you want that way.
For those not using quartz but spring, I have achieved to get next execution time by extending CronTrigger and remembering nextExecutionTime:
import org.springframework.scheduling.support.CronTrigger;
public class MyCronTrigger extends CronTrigger {
public MyCronTrigger(String expression) {
super(expression);
}
#Override
public Date nextExecutionTime(TriggerContext triggerContext) {
Date date = super.nextExecutionTime(triggerContext);
nextExecutionTime = new Date(date.getTime()); //remember
return date;
}
}