aspose file tools*
The moose likes Java in General and the fly likes Rescheduling a Timer Task Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Rescheduling a Timer Task" Watch "Rescheduling a Timer Task" New topic
Author

Rescheduling a Timer Task

Vivek Mathur
Greenhorn

Joined: Jun 29, 2007
Posts: 25
Hi All,

I have made a custom timertask class by extending the java.util.TimerTask, and a singlton timer class by extending the java.util.Timer (as i need only one timer object).Now what i am doing is scheduling repititivly my custom timertask with the timer object using the method-- timer.schedule(repSchedularObj, delay); Now i want to give user the authority to change the delay so that he/she can reschedule it(by giving a user interface to enter a delay).

Can any one suggest how to do it ?

How to check if previously(before changing the delay) the task is running or not and if running how to get the object of the previously runnig task in order to cancel it ?
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 42931
    
  68
Do you really need to cancel a running job? It would seem to make more sense to just schedule the next iteration after the new delay. So you could just call cancel() on the TimerTask (a reference to which you should have stored somewhere), and then schedule it anew.
Vivek Mathur
Greenhorn

Joined: Jun 29, 2007
Posts: 25
Hi Ulf Dittmer!
Thank you for your reply.

-- Do you really need to cancel a running job?

Does that mean that i can reschedule the previously running timertask without canceling it. How ? (can you please eleborate it little)

Its a good idea to store the reference of the timertask so that cancel() can be called.this is what i was thinking off and tried too. however the problem is how do i check if the task is scheduled or not.

One more thing Sir, I am using JBoss server 4.0.5 and many times what i realised is this the instance of timer keeps on runnig while the application server is shut down.
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 42931
    
  68
Does that mean that i can reschedule the previously running timertask without canceling it.
No. You have to cancel and then reschedule it. I was asking about canceling a running job, i.e. interrupting its execution, which would be more involved.

however the problem is how do i check if the task is scheduled or not.
I'm not sure what you're asking. Once a TimerTask has been scheduled for repeated execution, it remains scheduled. For rescheduling you should cancel it first.

the instance of timer keeps on runnig while the application server is shut down.

Make sure to create the Timer so that it uses daemon threads. See the javadocs for the various Timer constructors.
[ January 19, 2008: Message edited by: Ulf Dittmer ]
Vivek Mathur
Greenhorn

Joined: Jun 29, 2007
Posts: 25
1.) Thanks Now i got it about the cancelling and rescheduling.

2.) Yes i have seen the time(isDeamon) constructor.......
thanks for your suggestion i'll try it.

3.) Actually the scenario is, Suppose i shut down the application so i'll lost the schedular services. What i want is to restart the services(schedular task) as soon as the application start/user logs in.i am saving the delay time in database. Now login component will be hit many time by the users so i want to check if the timertask is not running/schedule(when application first starts), taking the delay from database it should restart (once offcourse). And if timertask is scheduled it should not call the code to schedule it.
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 42931
    
  68
Why are you doing the scheduling during a user login, if it's actually related to the application, not the user?

I'd configure a ServletContextListener and perform all setup in there. That way you can be sure that it happens only once, and right away when the application starts.
Vivek Mathur
Greenhorn

Joined: Jun 29, 2007
Posts: 25
Hi
Well that a very good idea.
but i haven't used ServletContextListener. can you please let me know how to do it all.

I am not sure how to call it and how to call.

If you have any sample code can you please post it or mail me.
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 42931
    
  68
This article has a section on "Lifecycle Events", of which a ServletContextListener is one.
Vivek Mathur
Greenhorn

Joined: Jun 29, 2007
Posts: 25
Hi Ulf Dittmer,
I have gone through the article sent by you.And made my own ServerListner class by extending ServletContextListner and did my settings there for timer and timer task.

then using servletContext object i set the timertask object so that it can be accessed further for resheduling.

It is working fine now.

Thanks to you

I just need one more help. I am actually scheduling a BAPI using JCO, now what happens is when the application is redeployed it gives some exception like--->

17:24:26,780 ERROR [STDERR] Exception in thread "Timer-6"
17:24:26,796 ERROR [STDERR] java.lang.ExceptionInInitializerError: JCO.classInit
ialize(): Could not load middleware layer 'com.sap.mw.jco.rfc.MiddlewareRFC'
Native Library C:\WINDOWS\system32\sapjcorfc.dll already loaded in another class
loader
17:24:26,796 ERROR [STDERR] at com.sap.mw.jco.JCO.<clinit>(Unknown Source)

--------
May be the previously loaded classes are not getting undeployed.
I tried to reliase client using JCO.releaseClient(SID); when context is destroyed.............

however i didn't get any result......

Can you please suggest something that may help.
[ January 22, 2008: Message edited by: Vivek Mathur ]
Vivek Mathur
Greenhorn

Joined: Jun 29, 2007
Posts: 25
Hi,
Today I have been doing some R&D on this exception issue and got something from the net.It goes like that.........

------------------
1.)There is known problem with Java VM which denies to load the same DLL in two different classloaders.

2.)http://developer.java.sun.com/developer/bugParade/bugs/4299094.html:
"In the current VM implementation, a native library can only be associated with one classloader. Thus, when multiple applets attempt to use the same library, the VM tries to associate the library with more than one classloader, and that's why it fails. Thus, this is a limitation of the current VM implementation, and it is not a bug."

"Will not fix. This is intentional. Each applet is loaded with its own classloader, and a native library cannot be loaded by more than one classloader. This is in part a security concern, as we don't want one classloader's app to muck up another classloader's app by tampering with native library state."

3.)Solution
Don't include sapjco.jar into your application, for example into WEB-INF/lib.
Use central (shared) instance of jco.jar. In sap j2ee 620 the library jco is predefined, see server/managers/library.txt. The only thing you have to do is to define a reference from your application to this library in reference.txt like

--------------------


Now what i understand is ClassLoader class is loading the sapjco.dll and saprfc.dll files only once at the time of first deployment of application.
so if the application is redeployed without stoping the JBoss server it gives an INIT exception.

Some post on sap's site says that using application-j2ee-engine.xml file you can use the reference of .dll files however this solution was for the SAP Netweaver Web Application Server .

-> So is there any thing that can be done with JBoss server 4.0.5 ??
-> Or is there any way to unload the library (.dll) files using any java code at the time of ContextDestroyed ??

ANY SUGGESTIONS ARE WELCOMED
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 42931
    
  68
So is there any thing that can be done with JBoss server 4.0.5?

I don't understand all the issues mentioned above, but it sounds as if the workaround is to put those libraries in a common shared location, so that they get loaded only once, instead of by each web app individually. That should work regardless of the server being used.

Or is there any way to unload the library (.dll) files using any java code at the time of ContextDestroyed ?

As I understand the above explanation, no, because native libraries are not unloaded (or loaded again) as long as the parent process is running.
Vivek Mathur
Greenhorn

Joined: Jun 29, 2007
Posts: 25
Hi,

One more thing sir, appart from the JCO Exception is ->
The rescheduling task has been changed a little.
I have to make sure that before rescheduling a timertask the previously running task(if in execution state) should complete.

Or if the application is redeployed before undeploying if a timertask is running it should complete first.

Is there any way to find out that the timertask is currently in execution? and if its executing wait till it gets completed and then cancel?
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 42931
    
  68
The task could set some boolean field somewhere that can be checked from other parts of the application through a getter method.
Vivek Mathur
Greenhorn

Joined: Jun 29, 2007
Posts: 25
Hi,
Thanks for the suggestion, i got it i will make a boolean field in my custom timertask class and set it to true as soon as the run method is called(before calling the method that is to be scheduled). and make it false just before exiting the run function(on successful execution of the task).

And before canceling and rescheduling the task i'll check if that field is true/false. IS IT CORRECT SIR.


NOW ABOUT THE JCO EXCEPTION AS YOU SAID YOU DOESN'T UNDERSTAND ALL THE ISSUES

As we all put our all .jar files in WEB-INF/lib. All the library files are packed with the .ear file.

When server starts first time ClassLoader loads the native libraries in server memory once only,Now if i redeploy the application again server tries to load the Native Libraries(as .jar for SAP are packed with .ear) once again(with another ClassLoader) --->and here comes the exception as Native libraries can only be loded once.

As you said there is no way to unload the native libraries.

What i read is in NETWEAVER WEB APPLICATION SERVER -(MAY BE AS IS BASED ON SAP SERVER ITSELF) WE CAN PUT OUR *.JAR FILES RELATED WITH SAP IN THE SERVER'S LIB FOLDER AND HAVE AN EXTERNAL REFERENCE USING APPLICATION-J2EE-ENGINE.XMLSo as to load native libraries once only.

Actually we don't provide any info to JBoss server throught any .xml file about the native library or any other .jar file(library).

What i want to know is if we can also have any such machanism with which we can provide the info to the application server about the location of library files.
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 42931
    
  68
What i want to know is if we can also have any such machanism with which we can provide the info to the application server about the location of library files.

It needs to be in a place where all processes will look for native libraries, e.g. in a directory that's part of the PATH environment variable.
Vivek Mathur
Greenhorn

Joined: Jun 29, 2007
Posts: 25
Hi Ulf Dittmer,

I have put down the sapjco.jar file under the lib folder of JBoss server.
And removed it from my application. However for build path i have to export it from some another location.

but now my application .ear file doesn't have any sapjco.jar and i checked by scheduling some dummy method and by redeploying the application few times.

It is not giving the previous exception now.
I hope it also works in the real environment.

I need to workout around timer and timertask a little more so as to make their working fine(in real environment with live tasks).

BOTH OF MY PROBLEMS HAVE BEEN SOLVED FOR NOW............
HOPE SO ...........

THANK YOU VERY MUCH FOR YOUR HELP AND IMMEDIATE REPLIES

HATS OFF TO YOU
Vivek Mathur
Greenhorn

Joined: Jun 29, 2007
Posts: 25
Hi Ulf,

I have encountered one more problem regarding scheduling.
I have scheduled this timertask for repetetive scheduling with timer object as i explained above using the below function.

timer.scheduleAtFixedRate(bapiSchedularObj, date.getTime(), delay);

bapiSchedularObj--> TimerTask Object
date -->Calendar Object
delay -->Long delay

I want to schedule this task on monthly basis.So in this function i can only change the delay in milliseconds.....30*24*60*60*100(days*hr*min*sec*millisec)..

Now the problem is the task should schedule only on a specific day of each month (suppose on the 5th of every month), the number of days differ on each month (can be 30/31/28/29).

So can you give some idea as how to reset the delay dynamically?

As after calling the function timer will itself take care of next period to schedule, depending on the days of month how can we set (automatically/dynamically)the delay for the next schedule if next month is of februry(28/29 days)?

Thanks in Advance.
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 42931
    
  68
You could schedule the task to run once a day, and only execute the critical code if it's the 5th day of a month.
Vivek Mathur
Greenhorn

Joined: Jun 29, 2007
Posts: 25
Hi Ulf,

I didn't get you?

Can you please elaborate this a little.

this scheduling task should run as the service and if it is scheduled on monthly basis on a specific day or on yearly basis(once a year) on a specific day it should repeat itself on that day.

-----------------------------
if i schedule a task on 30 Jan than there would be a problem on the next month of Feb (as it don't contain 30).

What should be the strategy to follow in these scenarios ?
-----------------------------
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 42931
    
  68
I'm talking about something like the following. You would schedule it to run every day, but thanks to the check for the day of the month, it would only execute its work on that particular day.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Rescheduling a Timer Task