There is a startup servlet that initialises Quartz Scheduler in the init() method and shut down the scheduler at destroy() method. I understand that Servlet itself is an object and will be GC collected at a unknown interval. If a shut down of Quartz Scheduler is placed in the destroy() method, I am expecting the scheduler to be restarted each time the servlet is GC collected. If the process of the destroy and start skipped the exact timing where I am expecting quartz to run a thread, I probably will have trouble. Am I right in this assumption?
Note: I noted that there is a context listener in the quartz library to shut down quartz when the application is out of service.
The Servlet specification does allow containers to unload Servlets at any point although they don't have to do this (Tomcat doesn't for example). You are unlikely to hit a problem but if Quartz is used by components other than the Servlet that starts it them it really belongs to the application not the Servlet and should be configured at that level.
Generally, it is better to start and stop Quartz with a ServletContextListener than with a Servlet.
Related
I have Quartz Scheduler running within WebLogic 12.1.3 and backed by a JobStoreCMT, but its behavior doesn't match the configuration (see below). What am I doing wrong?
Background
Quartz has jobs that are loaded from an XML file on startup and run periodically. Some of those jobs spawn one-time jobs. Also, there are one-time jobs that are manually triggered by users. The user-initiated jobs are done from EJBs that have container-managed transactions.
Questions
The transactions in the job classes are not active in the job's execute() method. I have to call begin/commit/rollback. Shouldn't that be taken care of since wrapJobExecutionInUserTransaction is set to true? That's what the documentation says.
The documentation also says that when using XMLSchedulingDataProcessorPlugin with JobStoreCMT, org.quartz.plugin.jobInitializer.wrapInUserTransaction must be set to true. However, when I do that I get a duplicate transaction exception. What's going on?
WebLogic takes forever to shut down whenever Quartz is enabled even though all of the jobs run quickly. From the logs it looks like WebLogic is waiting for the transactions to time out. Is something in the config contributing to this?
Configuration
org.quartz.scheduler.skipUpdateCheck=true
org.quartz.scheduler.instanceName=MyTaskScheduler
org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer=true
org.quartz.scheduler.instanceId=AUTO
org.quartz.scheduler.wrapJobExecutionInUserTransaction=true
org.quartz.scheduler.userTransactionURL=javax.transaction.UserTransaction
org.quartz.scheduler.idleWaitTime=30000
org.quartz.scheduler.dbFailureRetryInterval=15000
org.quartz.scheduler.batchTriggerAcquisitionMaxCount=1
org.quartz.scheduler.batchTriggerAcquisitionFireAheadTimeWindow=0
org.quartz.scheduler.makeSchedulerThreadDaemon=false
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=20
org.quartz.threadPool.threadPriority=5
org.quartz.threadPool.makeThreadsDaemons=false
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreCMT
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.oracle.weblogic.WebLogicOracleDelegate
org.quartz.jobStore.dataSource=MyDataSource
org.quartz.jobStore.nonManagedTXDataSource=MyDataSourceNonXA
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.useProperties=false
org.quartz.jobStore.misfireThreshold=60000
org.quartz.jobStore.isClustered=true
org.quartz.jobStore.clusterCheckinInterval=15000
org.quartz.jobStore.maxMisfiresToHandleAtATime=20
org.quartz.jobStore.txIsolationLevelSerializable=false
org.quartz.jobStore.txIsolationLevelReadCommitted=false
org.quartz.dataSource.MyDataSource.jndiURL=MyDataSource
org.quartz.dataSource.MyDataSource.java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory
org.quartz.dataSource.MyDataSource.java.naming.provider.url=t3://localhost:7003
org.quartz.dataSource.MyDataSourceNonXA.jndiURL=MyDataSourceNonXA
org.quartz.dataSource.MyDataSourceNonXA.java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory
org.quartz.dataSource.MyDataSourceNonXA.java.naming.provider.url=t3://localhost:7003
org.quartz.plugin.jobInitializer.class=org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
org.quartz.plugin.jobInitializer.fileNames=E:/tasks.xml
org.quartz.plugin.jobInitializer.failOnFileNotFound=true
org.quartz.plugin.jobInitializer.scanInterval=0
org.quartz.plugin.jobInitializer.wrapInUserTransaction=false
Any help is appreciated.
I am studying for the Spring Core certification and I have some dount about on this question finded into the provided study material:
What is the preferred way to close an application context?
I know that if I have something like this:
ConfigurableApplicationContext context = …
// Destroy the application
context.close();
by the use of the close() method on the context objet the ApplicationContext is closed and the application is destroyed.
But I think that this is not the best way that I have to do it.
Reading the official documentation I find that I can also do something like this:
context.registerShutdownHook();
that register a Shutdown Hook with the JVM so it is the JVM that will trigger Spring's close phase before JVM exits. So on JVM exit, Spring's close phase will execute.
On the documentation I can read that: usually not possible to call context.close() because many applications (web applications) run indefinitely But what exactly means this last assertion? why web application run indefinitely?
So my questions are:
Can I use this second way to close an application context also with not web application?
Is it prefered respect the context.close()?
Tnx
As you are aware that ContextLoaderListener is the one that takes care of initializing and destroying your ApplicationContext, when you shutdown your server, that ContextLoaderListener's contextDestroyed method is invoked.
public void contextDestroyed(ServletContextEvent event){
closeWebApplicationContext(event.getServletContext());
ContextCleanupListener.cleanupAttributes(event.getServletContext());
}
In that closeWebApplicationContext, they actually call the close method on ApplicationContext like this
if ((this.context instanceof ConfigurableWebApplicationContext)) {
((ConfigurableWebApplicationContext)this.context).close();
}
This is straight from spring-web-4.1.5.jar. As it is evident from here, they use close to destroy ApplicationContext in web applications.
But registerShutdownHook is used to explicitly shut down IoC container in non-web applications something like a standalone desktop application, specially when you're creating the ApplicationContext manually from ClassPathXmlApplicationContext (or) FileSystemXmlApplicationContext (or) some other types.
This is done to release all resources used by your spring application and to call destroy method on your spring beans if any.
On the documentation I can read that: usually not possible to call context.close() because many applications (web applications) run indefinitely But what exactly means this last assertion? why web application run indefinitely?
A web application will run as long as the application server that deploys it runs. It is up to the application server (and not to you) to correctly start and stop your application. This means that when the application server is stopped, the servlet context is destroyed. In a Spring application, the ContextLoaderListener class registered in web.xml listens to this event (context destroyed) to properly close the Spring context.
When using Spring outside of an application server (like a standalone application), it is up to you to correctly stop the Spring context. As you said, this can be done by explicitly calling context.close() or registering a shutdown hook (context.registerShutdownHook()) that makes this call for you.
From https://stackoverflow.com/a/42018369:
The ApplicationContext class doesn't define either of these methods as a part of its interface, but the ConfigurableApplicationContext does define both of these.
From the JavaDoc:
close() -- Close this application context, destroying all beans in its bean factory.
registerShutdownHook() -- Register a shutdown hook with the JVM runtime, closing this context on JVM shutdown unless it has already been closed at that time.
Basically, AbstractApplicationContext#close() will close, or shutdown, the ApplicationContext at the time it is invoked, while AbstractApplicationContext#registerShutdownHook() will close, or shutdown, the ApplicationContext at a later time when the JVM is shutting down for whatever reason. This will be achieved by utilizing the JVM shutdown hook functionality.
In either case, the actual closing is done by the doClose() method.
If you are curious about why your outputs look so similar, it is because they are effectively doing the same thing, whether you call close() or registerShutdownHook() at line 3 of you example. close() will shutdown right away, and registerShutdownHook() will shutdown just before the JVM will exit, which is pretty much as soon as the method is done being invoked, because it is the last line of code!
We have a web application which uses CRON4J scheduling. The Jobs are running twice for same scheduling time. can anybody know why?
we deployed this app on tomcat.
You are definitely registering the Task twice. May be there is another copy of your war deployed, so you actually have 2 instances of your application running ?
If you scheduler is defined in the context listener, check how many times have you defined the context. It will be executed for each context .
You can have multiple context if you use virtual host, or if you define one context in the war (META-INF/context.xml) and other in server.xml (you should not define context here).
I have spring web application and found that
org.springframework.orm.hibernate3.LocalSessionFactoryBean
creates 2 timer threads that don't stop after tomcat shutdown.
Does it possible to configure to stop these threads after tomcat received shutdown command or need use some kind of aspect?
Thanks.
We recently changed our system to keep the latest data in the memory instead of writing to the database. (it will be written to the database when the I/O is relatively free)
However, now we are stuck if in the event of Shutdown is required, there might be some data that have not written to the Database yet.
Is there anyway in Tomcat to trigger a call either a servlet method or some sort to perform action when a "shutdown" is issue to tomcat? We are using the following setup:
OS: Windows Server 2008
Tomcat: 5.5.30
Any idea how to perform the above?
Note: at the moment, we shutdown the tomcat from the windows services.
Like everyone else has pointed out, looks like Servlet.destroy() may be what you want.
public void destroy()
Called by the servlet container to indicate to a servlet that the servlet
is being taken out of service. This
method is only called once all threads
within the servlet's service method
have exited or after a timeout period
has passed. After the servlet
container calls this method, it will
not call the service method again on
this servlet.
This method gives the servlet an opportunity to clean up any resources
that are being held (for example,
memory, file handles, threads) and
make sure that any persistent state is
synchronized with the servlet's
current state in memory.
Does this meet your requirements? You can also implement a context listener:
Handling Servlet Life-Cycle Events
You can monitor and react to events in
a servlet's life cycle by defining
listener objects whose methods get
invoked when life cycle events occur.
To use these listener objects, you
must define the listener class and
specify the listener class.
There's examples there too.
ServletContextListener is what should do the trick
http://download.oracle.com/javaee/1.3/api/javax/servlet/ServletContextListener.html
sample code from PetStore Demo
http://java.sun.com/j2ee/tutorial/1_3-fcs/examples/src/web/bookstore1/listeners/ContextListener.java