Scheduling a Job in webserver -Java - java

I want to schedule a job in Jboss and websphere server.
I have a piece of code in java which should execute at a certain frequency independantly.And it should execute in a server continiously.
Is it possible to execute a code when server starts.

I'd recommend to use Quartz Scheduler if you require full portability of the code (WebSphere, JBoss, Tomcat, etc.)
You can initialize Quartz very easily by using build-in QuartzInitializerServlet or even better QuartzInitializerListener.

you could use Timer api.
add #Startup on your bean.
or add this to your web.xml (change properties for your convenience)
<servlet>
<servlet-name>Servlet</servlet-name>
<servlet-class>example.web.Servlet2Stateless</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>

Use Quartz Scheduler as mentioned by #Tomasz Blachowicz. Use Databse approach to configure Jobs and triggers. And just add below three line in your Startup servlet. That's It!
StdSchedulerFactory factory = new StdSchedulerFactory(configFile);
// where configFile => quartz.properties file complete path.
Scheduler scheduler = factory.getScheduler();
scheduler.start();
Hope this will work for you. I am using this and its very easy to configure.

You could use Flux to schedule your java jobs inside a web container.

Related

Quartz + Spring : Configure jobs to run on specific time using JobStore

I'm trying out Quartz scheduler and managed to get it to work with Spring using Maven.
What I need to do is configure Quartz to store the jobs so that for a scheduled time it may execute the job. As far as I know there are two types of triggers in Quartz, Simple and Cron. And I also found out that there is something called JobStore in Quartz. I got it configured to some extent.
Could someone please give me a good reference/references on how to setup Quartz, JobStore? Big help, thank you.
You can have a look at these links
Quartz JobStore with Spring Framework
http://trimplement.com/using-spring-and-quartz-with-jobstore-properties/
If you still cant figure it out then let me know
Just to give you another option, have you try task scheduling of Spring?. Nowadays I change all my old Quartz jobs for this and is easier to configure and you can use the annotations.
http://spring.io/blog/2010/01/05/task-scheduling-simplifications-in-spring-3-0/
You will usually create a Scheduler from a factory class. Quartz can be setup in several ways.
By using the org.quartz.impl.StdSchedulerFactory.getDefaultScheduler(). This will load the quartz.properties file in the Quartz distribution if you have not provided your own.
By specifying your configuration as Key-Value pairs in a quartz.properties file and loading it in org.quartz.impl.StdSchedulerFactory(java.lang.String fileName).getScheduler().
By specifying your configuration in a java.util.Properties as Key-Value pairs and loading it in org.quartz.impl.StdSchedulerFactory(java.util.Properties props).getScheduler().
By using the spring-context-support jar from the Spring Framework and using a higher level abstraction such as org.springframework.scheduling.quartz.SchedulerFactoryBean.
etc.
Quartz will start triggering jobs only when the org.quartz.Scheduler#start() has been invoked. Until this method is called the Scheduler will be in Standby mode.
The Scheduler can be destroyed to release threads by calling org.quartz.Scheduler#shutdown().
Example of Bootstrapping Quartz with Spring
#org.springframework.context.annotation.Configuration
public class QuartzExample {
...
#org.springframework.context.annotation.Bean
public org.springframework.scheduling.quartz.SchedulerFactoryBean schedulerFactory() {
org.springframework.scheduling.quartz.SchedulerFactoryBean factoryBean = new org.springframework.scheduling.quartz.SchedulerFactoryBean();
return factoryBean;
}
}
The bean definition above is enough to perform the following configuration:-
JobFactory - The default is Spring’s org.springframework.scheduling.quartz.AdaptableJobFactory, which supports java.lang.Runnable objects as well as standard Quartz org.quartz.Job instances.
ThreadPool - Default is a Quartz org.quartz.simpl.SimpleThreadPool with a pool size of 10. This is configured through the corresponding Quartz properties.
SchedulerFactory - The default used here is the org.quartz.impl.StdSchedulerFactory, reading in the standard quartz.properties from quartz.jar.
JobStore - The default used is org.quartz.simpl.RAMJobStore which does not support persistence and is not clustered.
Life-Cycle - The org.springframework.scheduling.quartz.SchedulerFactoryBean implements org.springframework.context.SmartLifecycle and org.springframework.beans.factory.DisposableBean which means the life-cycle of the scheduler is managed by the Spring container. The org.quartz.Scheduler#start() is called in the start() implementation of SmartLifecycle after initialization and the org.quartz.Scheduler#shutdown() is called in the destroy() implementation of DisposableBean at application teardown.
You can override the startup behaviour by setting org.springframework.scheduling.quartz.SchedulerFactoryBean().setAutoStartup(false). With this setting you have to manually start the scheduler.
All these default settings can be overridden by the calling the various setter methods on org.springframework.scheduling.quartz.SchedulerFactoryBean.
I have provided a full working example on Github. If you are interested in an example that saves the jobs in a database checkout the HSQLDB branch of the same repository.

how to start Quartz Scheduler automatically in Java

I'm using Quartz Scheduler 2.2.1 in a webapp which is built on Tomcat webserver. I use a servlet to start Quartz . However, if the system reboots, I also have to restart Quartz manually by sending request to that servlet. Therefore, the problem is how to start Quartz automatically !
One more thing that is I want to use Quartz to perform a task at 00:00:00 everyday, so what is the best design for the trigger in this case ?
Define a ServletContextListener and implement a contextInitialized() method that starts quartz. This listener gets triggered if the tomcat is restarted or your servlet is redeployed
You should use a custom ServletContextListener and configure it in your web.xml for automatically starting your cron job.
http://docs.oracle.com/cd/B14099_19/web.1012/b14017/filters.htm#i1000654
If not satisfied by the Oracle link, do a little Google and you will get plenty of examples
To start a cron job every day at 12:00 am the below cron pattern should work:
0 0 0 * * ?

How to get Quartz jobs running in a multi-ApplicationContext environment?

I have a Spring Web application with an applicationContext.xml loaded through a ContextLoaderListener in an XmlWebApplicationContext. The application context has a Quartz scheduler (defined with a SchedulerFactoryBean like here) but has no trigger nor job details.
During loading of this main application context, I load some "plug-in" JARs containing their own pluginApplicationContext.xml file.
Each pluginApplicationContext.xml is loaded in a GenericXmlApplicationContext as a child of the main XmlWebApplicationContext.
Those plug-ins may contain Quartz jobs (QuartzJobBean) which are scheduled within the scheduler discussed above. Scheduling have to be done programmatically through the Quartz API but this is fine for me. When the job is triggered, it is well instanciated by Quartz and, because it extends the QuartzJobBean, I'm able to get the current ApplicationContext through setApplicationContext.
The problem here is that I get the XmlWebApplicationContext instead of the GenericXmlApplicationContext from which the job have been scheduled. Thus, I cannot call getBean to retrieve the beans defined within the plugin.
I well understand why all of this happen. But I cannot find a clean and reusable solution to handle it. I've already had a look at OSGi but we're implementing this plug-in system on an existing application, not creating a new one from scratch and migrating the whole application to OSGi would be too much work to do. Do you know how OSGi and other plug-in frameworks deal with this kind of situation?
Thanks a lot for your help
I am not sure I get all those spring problems but I've done these things with OSGi.
What people often do not realize is that you can embed OSGi in your existing application without making any changes to the existing code. Richard Hall describes it here http://felix.apache.org/site/apache-felix-framework-launching-and-embedding.html (the API is 100% standardized).
Having a framework, you can then run your plugins in the framework. You will have to make sure the framework exports all the application packages (see the org.osgi.framework.system.packages.extra launch property). Plugins and application can then communicate through services.
I've never used Quartz but I've some experience with scheduling. I register a Runnable service with cron like properties:
#Component(properties="cron=1 * * * *")
public void SomeImpl implements Runnable {
public void run() {
...
}
}
You will then need to make a bundle that calls that service according to its cron specification).
I agree osgi is a good approach, but maybe you can simply crate one huge application context (to rule them all)? Instead of manually starting new child application context based on pluginApplicationContext.xml file simply add:
<import resource="classpath:/pluginApplicationContext.xml"/>
And this will find all plugins and merge their beans into a single application context. From architecture point of view this is a worse approach, but it will work if you discover all plugins at startup time.

Quartz on a webapp - scheduler does not stop

I have a webapp running on weblogic that runs a Scheduler on a ServletContextListener.
The problem is the scheduler runs indefinitely, so even if i stop the webapp or redeploy the scheduler keeps running.
I should be able to stop the scheduler on contextDestroyed, but I don't have the instance. I've seen a couple of websites recommending this aproach to the problem, but they all have shedulers running a defined number of times.
Quartz comes with a servlet specifically for starting & stopping the scheduler on application startup and shutdown simply add the following to your web.xml:
<servlet>
<servlet-name>QuartzInitializer</servlet-name>
<servlet-class>org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
If you want to shutdown without waiting for the executing jobs to finish use:
scheduler.shutdown(false);
Check this page for more info.
Upon application shutdown you must call
scheduler.shutdown();
Sometimes you have to do a Thread.sleep(1000); to let it shut down properly aswell.
Do this in a ContextLoad listener or other shutdown hook that you have.
To get the instance depends on how you have set up quartz, but the default scheduler can be obtained like this:
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
See http://www.quartz-scheduler.org/docs/1.x/quick_start_guide.html for more information

shutdown hook for java web application

I need to save some data preferrably when the java web application is stopped, or when tomcat is stopped. how can this be done?
Edit:
any drawback if I use the jvm shutdown hook?
Use a class that implements ServletContextListener in your web.xml:
<web-app>
<!-- Usual stuff here -->
<listener>
<listener-class>com.mycompany.MyClass</listener-class>
</listener>
</web-app>
Why do you want to do it specifically during shutdown? And do you really need to save it (as in "is it absolutely critical?") or would you like to (as in "would be nice but I'll live without it")?
The distinction is important - no matter what method you try (servlet / context listener as suggested by other answers or JVM shutdown hook) there are no guarantees that it will actually be invoked.
Servlet / context listener destroy events would only be triggered during normal (graceful) container shutdown OR during application reload. JVM shutdown hook would be triggered during process interruption as well; however killing a process (or cutting out the power) would obviously trigger neither.
As an addition to leonm's answer:
If you use Spring, you can use Spring's "lifecycle management" to achieve a similar effect. For example, you can annotate a method in a bean with #PreDestroy to have it invoked automatically on container shutdown. That way, you don't need to put anything into the web.xml.
See Spring beans factory lifecycle.
I suggest using ehcache to cache this information. If you use ehcache's persistent store, then when you start Tomcat again, the cached data will still be available.
In effect, this delegates the issue to ehcache, which is optimised for these types of problems.

Categories